#[derive(Debug)]
pub struct DenseLiveSet {
mark: Vec<u64>,
epoch: u64,
touched: Vec<u32>,
}
impl DenseLiveSet {
pub fn new(n: usize) -> Self {
Self {
mark: vec![0; n],
epoch: 0,
touched: Vec::new(),
}
}
pub fn next_epoch(&mut self) {
self.epoch += 1;
self.touched.clear();
}
pub fn set_live(&mut self, i: u32) -> bool {
let m = &mut self.mark[i as usize];
let newly_touched = *m / 2 != self.epoch;
if newly_touched {
self.touched.push(i);
}
let was_live = !newly_touched && *m % 2 == 0;
*m = self.epoch * 2;
!was_live
}
pub fn set_dead(&mut self, i: u32) -> bool {
let m = &mut self.mark[i as usize];
if *m / 2 != self.epoch {
self.touched.push(i);
*m = self.epoch * 2 + 1;
return false;
}
let was_live = *m % 2 == 0;
*m = self.epoch * 2 + 1;
was_live
}
pub fn is_live(&self, i: u32) -> bool {
let m = self.mark[i as usize];
m / 2 == self.epoch && m % 2 == 0
}
pub fn touched(&self) -> &[u32] {
&self.touched
}
}