use bitm::{BitAccess, BitVec};
use ph::{BuildDefaultSeededHasher, BuildSeededHasher};
pub trait ValuesPreFiller {
fn create(&mut self, n: usize, bits_per_value: u8) -> Box<[u64]>;
#[inline(always)] fn init(&self, array: &mut [u64], index: usize, value: u64, bits_per_value: u8) {
array.set_fragment(index, value, bits_per_value);
}
}
impl ValuesPreFiller for () {
fn create(&mut self, n: usize, bits_per_value: u8) -> Box<[u64]> {
Box::<[u64]>::with_zeroed_bits(n * bits_per_value as usize)
}
#[inline(always)] fn init(&self, array: &mut [u64], index: usize, value: u64, bits_per_value: u8) {
array.init_fragment(index, value, bits_per_value);
}
}
#[derive(Copy, Clone)]
pub struct FillWithPattern(u64);
impl ValuesPreFiller for FillWithPattern {
fn create(&mut self, n: usize, bits_per_value: u8) -> Box<[u64]> {
Box::<[u64]>::with_64bit_segments(self.0, bitm::ceiling_div(n * bits_per_value as usize, 64), )
}
}
#[derive(Copy, Clone)]
pub struct FillRandomly{seed: u64}
impl ValuesPreFiller for FillRandomly {
fn create(&mut self, n: usize, bits_per_value: u8) -> Box<[u64]> {
(0..bitm::ceiling_div(n * bits_per_value as usize, 64)).map(|_| {
self.seed ^= self.seed << 13;
self.seed ^= self.seed >> 7;
self.seed ^= self.seed << 17;
self.seed
}).collect()
}
}
#[derive(Default, Copy, Clone)]
pub struct MapConf<VPF = (), S = BuildDefaultSeededHasher> {
pub hash_builder: S,
pub value_prefiller: VPF
}
impl MapConf {
#[inline] pub fn new() -> Self { Default::default() }
}
impl<S: BuildSeededHasher> MapConf<(), S> {
#[inline] pub fn hash(hash_builder: S) -> Self {
Self { hash_builder, value_prefiller: Default::default() }
}
}
impl<BM: ValuesPreFiller> MapConf<BM> {
#[inline] pub fn prefiller(value_prefiller: BM) -> Self {
Self { hash_builder: Default::default(), value_prefiller }
}
}
impl MapConf<FillWithPattern> {
#[inline] pub fn pattern(pattern: u64) -> Self {
Self::prefiller(FillWithPattern(pattern))
}
}
impl MapConf<FillRandomly> {
#[inline] pub fn randomly(seed: u64) -> Self {
Self::prefiller(FillRandomly{seed})
}
}
impl<VPF: ValuesPreFiller, S: BuildSeededHasher> MapConf<VPF, S> {
#[inline] pub fn prefiller_hash(value_prefiller: VPF, hash_builder: S) -> Self {
Self { hash_builder, value_prefiller }
}
}