use bitvec::vec::BitVec;
pub struct AtomicBitmap {
pub data: Vec<std::sync::atomic::AtomicU64>,
pub len: usize, }
impl AtomicBitmap {
pub fn new(len: usize) -> Self {
let n_words = len.div_ceil(64);
let data = (0..n_words).map(|_| std::sync::atomic::AtomicU64::new(0)).collect();
Self {data, len}
}
pub fn set(&self, index: usize, value: bool) {
assert!(index < self.len);
let word_idx = index / 64;
let bit_idx = index % 64;
let mask = 1_u64 << bit_idx;
if value {
self.data[word_idx].fetch_or(mask, std::sync::atomic::Ordering::Release);
} else {
self.data[word_idx].fetch_and(!mask, std::sync::atomic::Ordering::Release);
}
}
pub fn get(&self, index: usize) -> bool {
assert!(index < self.len);
let word_idx = index / 64;
let bit_idx = index % 64;
let mask = 1_u64 << bit_idx;
(self.data[word_idx].load(std::sync::atomic::Ordering::Acquire) & mask) != 0
}
#[allow(dead_code)]
pub fn len(&self) -> usize {
self.len
}
pub fn into_bitvec(self) -> BitVec<usize, bitvec::order::Lsb0> {
let non_atomic: Vec<usize> = self.data.into_iter().map(
|x| x.load(std::sync::atomic::Ordering::Acquire) as usize
).collect();
let mut bv = BitVec::from_vec(non_atomic);
bv.truncate(self.len); bv
}
}