use std::hash::{BuildHasher, Hash, Hasher};
pub use config::{HashBits, HASH_SHIFT, HASH_SIZE};
pub const HASH_MASK: HashBits = (HASH_SIZE - 1) as HashBits;
#[inline]
pub fn mask(hash: HashBits, shift: usize) -> HashBits {
hash >> shift & HASH_MASK
}
pub fn hash_key<K: Hash + ?Sized, S: BuildHasher>(bh: &S, key: &K) -> HashBits {
let mut hasher = bh.build_hasher();
key.hash(&mut hasher);
hasher.finish() as HashBits
}
#[derive(PartialEq, Eq, Clone, Copy, Default)]
pub struct Bitmap {
data: HashBits,
}
impl Bitmap {
#[inline]
pub fn new() -> Self {
Self::default()
}
#[inline]
pub fn get(self, index: usize) -> bool {
self.data & (1 << index) != 0
}
#[inline]
pub fn set(&mut self, index: usize, value: bool) -> bool {
let mask = 1 << index;
let prev = self.data & mask;
if value {
self.data |= mask;
} else {
self.data &= !mask;
}
prev != 0
}
#[inline]
pub fn len(self) -> usize {
self.data.count_ones() as usize
}
}
impl IntoIterator for Bitmap {
type Item = usize;
type IntoIter = Iter;
fn into_iter(self) -> Self::IntoIter {
Iter {
index: 0,
data: self.data,
}
}
}
pub struct Iter {
index: usize,
data: HashBits,
}
impl Iterator for Iter {
type Item = usize;
fn next(&mut self) -> Option<Self::Item> {
if self.index >= HASH_SIZE {
return None;
}
if self.data & 1 != 0 {
self.data >>= 1;
self.index += 1;
Some(self.index - 1)
} else {
self.data >>= 1;
self.index += 1;
self.next()
}
}
}