#[derive(Clone, Debug)]
pub(crate) struct Entry {
pub(crate) left: String,
pub(crate) right: String,
pub(crate) trail_entry_id: usize,
}
impl PartialEq for Entry {
fn eq(&self, other: &Self) -> bool {
self.left == other.left && self.right == other.right
}
}
impl Eq for Entry {}
#[derive(Clone, Default)]
pub(crate) struct InfiniteLoopTracker {
history: Vec<Entry>,
}
impl InfiniteLoopTracker {
pub(crate) fn new() -> Self {
InfiniteLoopTracker {
history: Vec::new(),
}
}
pub(crate) fn append(&mut self, entry: Entry) {
self.history.push(entry);
}
pub(crate) fn get_repeating_entries(&self) -> Option<Vec<Entry>> {
let length = self.history.len();
let mut candidate_size = 1;
while candidate_size <= length / 2 {
let candidate_start = length - candidate_size * 2;
let mut matched = true;
for i in 0..candidate_size {
if self.history[candidate_start + i]
!= self.history[candidate_start + candidate_size + i]
{
matched = false;
break;
}
}
if matched {
return Some(
self.history[candidate_start..candidate_start + candidate_size].to_vec(),
);
}
candidate_size += 1;
}
None
}
}