1 use std::{ 2 fmt::Display, 3 hash::{Hash, Hasher}, 4 }; 5 6 const MAGIC_INIT: u64 = 0x811C_9DC5; 7 8 // TODO: Docs 9 pub trait Key: Hash + Display { key(&self) -> u6410 fn key(&self) -> u64; 11 } 12 13 impl<T> Key for T 14 where 15 T: Hash + Display, 16 { key(&self) -> u6417 fn key(&self) -> u64 { 18 let mut hasher = FnvHasher::new(); 19 self.hash(&mut hasher); 20 hasher.finish() 21 } 22 } 23 24 pub(crate) struct FnvHasher(u64); 25 26 impl FnvHasher { new() -> Self27 pub(crate) fn new() -> Self { 28 FnvHasher(MAGIC_INIT) 29 } 30 } 31 32 impl Hasher for FnvHasher { finish(&self) -> u6433 fn finish(&self) -> u64 { 34 self.0 35 } write(&mut self, bytes: &[u8])36 fn write(&mut self, bytes: &[u8]) { 37 let FnvHasher(mut hash) = *self; 38 39 for byte in bytes.iter() { 40 hash ^= u64::from(*byte); 41 hash = hash.wrapping_mul(0x0100_0000_01b3); 42 } 43 44 *self = FnvHasher(hash); 45 } 46 } 47