pub mod build;
pub mod calc;
pub mod query;
use alloc::{boxed::Box, vec::Vec};
use core::borrow::Borrow;
use core::hash::Hash;
#[cfg(feature = "bitcode")]
use bitcode::{Decode, Encode};
use crate::{
Filter,
hash::Fingerprint,
prelude::bfuse::Desc,
};
#[cfg_attr(feature = "bitcode", derive(Decode, Encode))]
#[derive(Debug, Clone)]
pub struct Base<T> {
pub desc: Desc,
pub fingerprints: Box<[T]>,
}
impl<T: Fingerprint> Filter<u64> for Base<T> {
#[inline(always)]
fn has<Q: ?Sized>(&self, key: &Q) -> bool
where
u64: Borrow<Q>,
Q: Hash,
{
let k = unsafe { *(key as *const Q as *const u64) };
query::contains_impl(
&k,
self.desc.seed,
&self.fingerprints,
self.desc.seg_len,
self.desc.seg_len_mask,
self.desc.seg_count_len,
)
}
#[inline(always)]
fn len(&self) -> usize {
self.fingerprints.len()
}
}
impl<T: Fingerprint> Base<T> {
pub fn from_iterator<I>(keys: I) -> Self
where
I: ExactSizeIterator<Item = u64> + Clone,
{
let (desc, fingerprints) = build::make(keys, 1000);
Self { desc, fingerprints }
}
}
impl<T: Fingerprint> From<&[u64]> for Base<T> {
fn from(keys: &[u64]) -> Self {
Self::from_iterator(keys.iter().copied())
}
}
impl<T: Fingerprint> From<&Vec<u64>> for Base<T> {
fn from(v: &Vec<u64>) -> Self {
Self::from_iterator(v.iter().copied())
}
}
impl<T: Fingerprint> From<Vec<u64>> for Base<T> {
fn from(v: Vec<u64>) -> Self {
Self::from_iterator(v.iter().copied())
}
}
pub type Bf8 = Base<u8>;
pub type Bf16 = Base<u16>;
pub type Bf32 = Base<u32>;