use {
crate::RingPosition,
hash_iter::{DoubleHashHasher, HashIterHasher},
std::hash::{BuildHasher, Hash},
xxhash_rust::xxh3::Xxh3Builder,
};
pub trait Partitioner<K: Hash> {
fn position(&self, key: &K) -> RingPosition;
fn positions(&self, key: &K, k: usize) -> impl Iterator<Item = RingPosition>;
fn position_seeded(&self, key: &K, seed: RingPosition) -> RingPosition;
}
pub const DEFAULT_SEED1: u64 = 12345;
pub const DEFAULT_SEED2: u64 = 67890;
#[derive(Clone)]
pub struct Xxh3Partitioner {
hash_builder: Xxh3Builder,
hash_iter: DoubleHashHasher<u64, Xxh3Builder, Xxh3Builder>,
}
impl Default for Xxh3Partitioner {
fn default() -> Self {
Self {
hash_builder: Xxh3Builder::new(),
hash_iter: DoubleHashHasher::<u64, _, _>::with_hash_builders(
Xxh3Builder::new(),
Xxh3Builder::new(),
RingPosition::MAX,
),
}
}
}
impl Xxh3Partitioner {
pub fn new() -> Self {
Self::default()
}
pub fn hash<K: Hash>(&self, key: &K, seed: RingPosition) -> RingPosition {
self.hash_builder.with_seed(seed).hash_one(key)
}
}
impl<K: Hash> Partitioner<K> for Xxh3Partitioner {
fn position(&self, key: &K) -> RingPosition {
self.hash(key, DEFAULT_SEED1)
}
fn positions(&self, key: &K, k: usize) -> impl Iterator<Item = RingPosition> {
self.hash_iter.hash_iter(key, k)
}
fn position_seeded(&self, key: &K, seed: RingPosition) -> RingPosition {
self.hash(key, seed)
}
}
pub type DefaultPartitioner = Xxh3Partitioner;