use ahash::AHasher;
use std::hash::{BuildHasher, Hash, Hasher};
pub(crate) struct HashGenerator {
hash1: u64,
hash2: u64,
}
impl HashGenerator {
#[inline]
pub fn new<T: Hash>(item: &T) -> Self {
let hash1 = Self::ahash(item, 0xdead_beef_cafe_babe_u128);
let hash2 = Self::ahash(item, 0x0123_4567_89ab_cdef_u128);
let hash2 = hash2 | 1;
Self { hash1, hash2 }
}
#[inline]
pub fn nth(&self, i: usize) -> u64 {
let i = i as u64;
self.hash1
.wrapping_add(i.wrapping_mul(self.hash2))
.wrapping_add(i.wrapping_mul(i))
}
#[inline]
fn ahash<T: Hash>(item: &T, seed: u128) -> u64 {
let lo = seed as u64;
let hi = (seed >> 64) as u64;
let state = ahash::RandomState::with_seeds(lo, hi, lo ^ hi, lo.wrapping_add(hi));
let mut hasher: AHasher = state.build_hasher();
item.hash(&mut hasher);
hasher.finish()
}
}