read_fonts/collections/
fnv.rs1use std::hash::{BuildHasherDefault, Hasher};
25
26const INITIAL_STATE: u64 = 0xcbf2_9ce4_8422_2325;
27const PRIME: u64 = 0x0100_0000_01b3;
28
29#[derive(Clone)]
30pub struct FnvHasher(u64);
31
32impl Default for FnvHasher {
33 #[inline]
34 fn default() -> FnvHasher {
35 FnvHasher(INITIAL_STATE)
36 }
37}
38
39impl Hasher for FnvHasher {
40 #[inline]
41 fn finish(&self) -> u64 {
42 self.0
43 }
44
45 #[inline]
46 fn write(&mut self, bytes: &[u8]) {
47 let FnvHasher(mut hash) = *self;
48 for byte in bytes {
49 hash ^= u64::from(*byte);
50 hash = hash.wrapping_mul(PRIME);
51 }
52 *self = FnvHasher(hash);
53 }
54}
55
56pub type FnvBuildHasher = BuildHasherDefault<FnvHasher>;
57pub type FnvHashMap<K, V> = std::collections::HashMap<K, V, FnvBuildHasher>;
58
59#[cfg(test)]
60mod test {
61 use super::*;
62 use std::hash::Hasher;
63
64 fn fnv1a(bytes: &[u8]) -> u64 {
65 let mut hasher = FnvHasher::default();
66 hasher.write(bytes);
67 hasher.finish()
68 }
69
70 #[test]
71 fn basic_tests() {
72 assert_eq!(fnv1a(b""), 0xcbf29ce484222325);
73 assert_eq!(fnv1a(b"a"), 0xaf63dc4c8601ec8c);
74 assert_eq!(fnv1a(b"b"), 0xaf63df4c8601f1a5);
75 assert_eq!(fnv1a(b"c"), 0xaf63de4c8601eff2);
76 assert_eq!(fnv1a(b"d"), 0xaf63d94c8601e773);
77 assert_eq!(fnv1a(b"e"), 0xaf63d84c8601e5c0);
78 assert_eq!(fnv1a(b"f"), 0xaf63db4c8601ead9);
79 assert_eq!(fnv1a(b"fo"), 0x08985907b541d342);
80 assert_eq!(fnv1a(b"foo"), 0xdcb27518fed9d577);
81 assert_eq!(fnv1a(b"foob"), 0xdd120e790c2512af);
82 assert_eq!(fnv1a(b"fooba"), 0xcac165afa2fef40a);
83 assert_eq!(fnv1a(b"foobar"), 0x85944171f73967e8);
84 assert_eq!(fnv1a(b"\0"), 0xaf63bd4c8601b7df);
85 assert_eq!(fnv1a(b"a\0"), 0x089be207b544f1e4);
86 assert_eq!(fnv1a(b"b\0"), 0x08a61407b54d9b5f);
87 assert_eq!(fnv1a(b"c\0"), 0x08a2ae07b54ab836);
88 assert_eq!(fnv1a(b"d\0"), 0x0891b007b53c4869);
89 assert_eq!(fnv1a(b"e\0"), 0x088e4a07b5396540);
90 assert_eq!(fnv1a(b"f\0"), 0x08987c07b5420ebb);
91 assert_eq!(fnv1a(b"fo\0"), 0xdcb28a18fed9f926);
92 assert_eq!(fnv1a(b"foo\0"), 0xdd1270790c25b935);
93 }
94}