use crate::{BlockedBitVec, BloomFilter, BuildHasher, DefaultHasher};
use std::hash::Hash;
#[derive(Debug, Clone)]
pub struct Builder<const BLOCK_SIZE_BITS: usize = 512, S = DefaultHasher> {
pub(crate) num_blocks: usize,
pub(crate) hasher: S,
}
impl<const BLOCK_SIZE_BITS: usize> Builder<BLOCK_SIZE_BITS> {
pub fn seed(mut self, seed: &u128) -> Self {
self.hasher = DefaultHasher::seeded(&seed.to_be_bytes());
self
}
}
impl<const BLOCK_SIZE_BITS: usize, S: BuildHasher> Builder<BLOCK_SIZE_BITS, S> {
pub fn hasher<H: BuildHasher>(self, hasher: H) -> Builder<BLOCK_SIZE_BITS, H> {
Builder::<BLOCK_SIZE_BITS, H> {
num_blocks: self.num_blocks,
hasher,
}
}
pub fn hashes(self, num_hashes: u64) -> BloomFilter<BLOCK_SIZE_BITS, S> {
BloomFilter {
bits: BlockedBitVec::<BLOCK_SIZE_BITS>::new(self.num_blocks).unwrap(),
num_hashes,
hasher: self.hasher,
}
}
pub fn expected_items(self, expected_num_items: usize) -> BloomFilter<BLOCK_SIZE_BITS, S> {
let num_hashes =
BloomFilter::<BLOCK_SIZE_BITS>::optimal_hashes(expected_num_items / self.num_blocks);
self.hashes(num_hashes)
}
pub fn items<I: IntoIterator<IntoIter = impl ExactSizeIterator<Item = impl Hash>>>(
self,
items: I,
) -> BloomFilter<BLOCK_SIZE_BITS, S> {
let into_iter = items.into_iter();
let mut filter = self.expected_items(into_iter.len());
filter.extend(into_iter);
filter
}
}
#[cfg(test)]
mod tests {
use crate::BloomFilter;
use ahash::RandomState;
#[test]
fn api() {
let _bloom = BloomFilter::builder128(10)
.hasher(RandomState::default())
.hashes(4);
}
}