use core::hash::{BuildHasher, Hasher};
#[derive(Clone, Default)]
pub struct FxHasher {
hash: u64,
}
const FX_K: u64 = 0x517c_c1b7_2722_0a95;
impl FxHasher {
#[inline]
fn add_to_hash(&mut self, i: u64) {
self.hash = (self.hash.rotate_left(5) ^ i).wrapping_mul(FX_K);
}
}
impl Hasher for FxHasher {
#[inline]
fn write(&mut self, bytes: &[u8]) {
for b in bytes {
self.add_to_hash(*b as u64);
}
}
#[inline]
fn write_u8(&mut self, i: u8) {
self.add_to_hash(i as u64);
}
#[inline]
fn write_u16(&mut self, i: u16) {
self.add_to_hash(i as u64);
}
#[inline]
fn write_u32(&mut self, i: u32) {
self.add_to_hash(i as u64);
}
#[inline]
fn write_u64(&mut self, i: u64) {
self.add_to_hash(i);
}
#[inline]
fn write_usize(&mut self, i: usize) {
self.add_to_hash(i as u64);
}
#[inline]
fn write_u128(&mut self, i: u128) {
self.add_to_hash(i as u64);
self.add_to_hash((i >> 64) as u64);
}
#[inline]
fn finish(&self) -> u64 {
self.hash
}
}
#[derive(Clone, Copy, Default)]
pub struct FxBuildHasher;
impl BuildHasher for FxBuildHasher {
type Hasher = FxHasher;
#[inline]
fn build_hasher(&self) -> FxHasher {
FxHasher { hash: 0 }
}
}
pub type HashMap<K, V> = hashbrown::HashMap<K, V, FxBuildHasher>;
pub type HashSet<T> = hashbrown::HashSet<T, FxBuildHasher>;