pub struct VisitedTable {
visit_status: Box<[u8]>,
iteration: u8,
}
impl VisitedTable {
pub fn new(n: usize) -> Self {
Self {
visit_status: vec![0; n].into_boxed_slice(),
iteration: 1,
}
}
#[inline]
pub fn get_visit_status(&self) -> &[u8] {
&self.visit_status
}
#[inline]
pub fn set(&mut self, id: usize) {
self.visit_status[id] = self.iteration;
}
#[inline]
pub fn get(&self, id: usize) -> bool {
self.visit_status[id] == self.iteration
}
pub fn advance(&mut self) {
self.iteration += 1;
if self.iteration == u8::MAX - 1 {
self.visit_status.fill(0);
self.iteration = 1;
}
}
}
#[cfg(test)]
mod tests_visited_table {
use super::*;
#[test]
fn test_new_visited_table() {
let table = VisitedTable::new(10);
assert_eq!(table.get_visit_status(), &[0; 10]);
assert_eq!(table.iteration, 1);
}
#[test]
fn test_set_and_get() {
let mut table = VisitedTable::new(5);
assert_eq!(table.get(2), false); table.set(2);
assert_eq!(table.get(2), true); assert_eq!(table.get(3), false); }
#[test]
fn test_advance_iteration() {
let mut table = VisitedTable::new(3);
table.set(1);
assert_eq!(table.get(1), true);
table.advance(); assert_eq!(table.get(1), false); }
#[test]
fn test_set_multiple_times() {
let mut table = VisitedTable::new(5);
table.set(3);
assert_eq!(table.get(3), true);
table.advance();
assert_eq!(table.get(3), false);
table.set(3);
assert_eq!(table.get(3), true); }
#[test]
#[should_panic]
fn test_set_out_of_bounds() {
let mut table = VisitedTable::new(2);
table.set(5); }
#[test]
#[should_panic]
fn test_get_out_of_bounds() {
let table = VisitedTable::new(2);
let _ = table.get(5); }
#[test]
fn test_advance_overflow() {
let mut table = VisitedTable::new(2);
table.iteration = u8::MAX - 2;
table.advance();
assert_eq!(table.iteration, 1);
assert_eq!(table.get_visit_status(), vec![0; 2].as_slice());
}
}