use metrale_model_engine::traits::SequenceState;
use super::model::{GARBAGE, RecordingModel};
impl RecordingModel {
fn recurrent_key(seq: &SequenceState) -> u64 {
if seq.session_hash != 0 {
seq.session_hash
} else {
u64::from(seq.tokens.first().copied().unwrap_or(0))
}
}
pub(super) fn recurrent_consume(&self, seq: &SequenceState, start: usize, len: usize) -> bool {
if self.cfg.recurrent_fed_rows.is_none() {
return true;
}
let key = Self::recurrent_key(seq);
let (clean, reused) = {
let mut map = self.recurrent.lock().unwrap();
let entry = map.entry(key).or_insert((0, false));
if start == 0 {
*entry = (0, false);
}
let reused = (entry.0 != start && !entry.1).then_some(entry.0);
entry.1 |= reused.is_some();
entry.0 = start + len;
(!entry.1, reused)
};
if let Some(expected) = reused {
self.rec(format!(
"recurrent state of s{key} consumed again at {start} (expected {expected})"
));
}
clean
}
pub(super) fn recurrent_out(&self, clean: bool, out: u32) -> u32 {
if clean { out } else { GARBAGE }
}
}