use crate::Filter;
use alloc::vec::Vec;
use core::hash::{Hash, Hasher};
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
#[cfg(feature = "bincode")]
use bincode::{Decode, Encode};
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "bincode", derive(Encode, Decode))]
pub struct HashProxy<T, H, F>
where
T: Hash,
H: Hasher + Default,
F: Filter<u64>,
{
filter: F,
_hasher: core::marker::PhantomData<H>,
_type: core::marker::PhantomData<T>,
}
#[inline]
fn hash<T: Hash, H: Hasher + Default>(key: &T) -> u64 {
let mut hasher = H::default();
key.hash(&mut hasher);
hasher.finish()
}
impl<T, H, F> Filter<T> for HashProxy<T, H, F>
where
T: Hash,
H: Hasher + Default,
F: Filter<u64>,
{
fn contains(&self, key: &T) -> bool {
self.filter.contains(&hash::<T, H>(key))
}
fn len(&self) -> usize {
self.filter.len()
}
}
impl<T, H, F> From<&[T]> for HashProxy<T, H, F>
where
T: Hash,
H: Hasher + Default,
F: Filter<u64> + From<Vec<u64>>,
{
fn from(keys: &[T]) -> Self {
let keys: Vec<u64> = keys.iter().map(hash::<T, H>).collect();
Self {
filter: F::from(keys),
_hasher: core::marker::PhantomData,
_type: core::marker::PhantomData,
}
}
}
impl<T, H, F> From<&Vec<T>> for HashProxy<T, H, F>
where
T: Hash,
H: Hasher + Default,
F: Filter<u64> + From<Vec<u64>>,
{
fn from(v: &Vec<T>) -> Self {
Self::from(v.as_slice())
}
}
#[cfg(test)]
mod test {
use crate::{xor16::Xor16, xor32::Xor32, xor8::Xor8};
use crate::{Filter, HashProxy};
use alloc::vec::Vec;
use rand::distributions::Alphanumeric;
use rand::Rng;
extern crate std;
use std::collections::hash_map::DefaultHasher;
use std::string::String;
#[test]
fn test_initialization_from() {
const SAMPLE_SIZE: usize = 1_000_000;
let keys: Vec<String> = (0..SAMPLE_SIZE)
.map(|_| {
rand::thread_rng()
.sample_iter(&Alphanumeric)
.take(15)
.map(char::from)
.collect()
})
.collect();
macro_rules! drive_test {
($xorf:ident) => {{
let keys = keys.clone();
let filter: HashProxy<_, DefaultHasher, $xorf> = HashProxy::from(&keys);
for key in keys {
assert!(filter.contains(&key));
}
}};
}
drive_test!(Xor8);
drive_test!(Xor16);
drive_test!(Xor32);
}
}