#[derive(Default)]
pub struct MarkBits(Vec<u8>);
impl MarkBits {
pub fn reset(&mut self, capacity: usize) {
self.0.clear();
self.0.resize(capacity, 0);
}
pub fn get(&self, index: u32) -> bool {
let index = usize::try_from(index).unwrap();
let byte_index = index / 8;
let bit_index = index % 8;
let mask = 1 << bit_index;
self.0[byte_index] & mask != 0
}
pub fn set(&mut self, index: u32) -> bool {
let index = usize::try_from(index).unwrap();
let byte_index = index / 8;
let bit_index = index % 8;
let mask = 1 << bit_index;
let old_byte = self.0[byte_index];
self.0[byte_index] = old_byte | mask;
old_byte & mask != 0
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn mark_bits() {
let mut mark_bits = MarkBits::default();
for i in 0..32 {
mark_bits.reset(32);
for j in 0..32 {
assert_eq!(mark_bits.get(j), false);
}
let was_already_set = mark_bits.set(i);
assert!(!was_already_set);
let was_already_set = mark_bits.set(i);
assert!(was_already_set);
if i > 0 {
let was_already_set = mark_bits.set(i - 1);
assert!(!was_already_set);
let was_already_set = mark_bits.set(i - 1);
assert!(was_already_set);
assert!(mark_bits.get(i));
}
if i < 31 {
let was_already_set = mark_bits.set(i + 1);
assert!(!was_already_set);
let was_already_set = mark_bits.set(i + 1);
assert!(was_already_set);
assert!(mark_bits.get(i));
}
}
}
}