1use std::collections::HashMap;
5use std::hash::{BuildHasherDefault, Hasher};
6
7const SEED: u64 = 0x51_7c_c1_b7_27_22_0a_95;
8
9#[derive(Default, Clone, Copy)]
10pub struct FxHasher {
11 hash: u64,
12}
13
14impl FxHasher {
15 #[inline]
16 fn add(&mut self, word: u64) {
17 self.hash = (self.hash.rotate_left(5) ^ word).wrapping_mul(SEED);
18 }
19}
20
21impl Hasher for FxHasher {
22 #[inline]
23 fn write(&mut self, bytes: &[u8]) {
24 for chunk in bytes.chunks(8) {
25 let mut word = [0u8; 8];
26 word[..chunk.len()].copy_from_slice(chunk);
27 self.add(u64::from_le_bytes(word));
28 }
29 }
30
31 #[inline]
32 fn write_u8(&mut self, value: u8) {
33 self.add(u64::from(value));
34 }
35
36 #[inline]
37 fn write_u32(&mut self, value: u32) {
38 self.add(u64::from(value));
39 }
40
41 #[inline]
42 fn write_u64(&mut self, value: u64) {
43 self.add(value);
44 }
45
46 #[inline]
47 fn write_usize(&mut self, value: usize) {
48 self.add(value as u64);
49 }
50
51 #[inline]
52 fn finish(&self) -> u64 {
53 self.hash
54 }
55}
56
57pub type FxHashMap<K, V> = HashMap<K, V, BuildHasherDefault<FxHasher>>;
58pub type FxHashSet<K> = std::collections::HashSet<K, BuildHasherDefault<FxHasher>>;