1use std::collections::{HashMap, HashSet};
9use std::hash::{BuildHasher, Hash, Hasher};
10
11const K: u64 = 0x517cc1b727220a95;
12
13pub type FastSet<T> = HashSet<T, BuildFxHasher>;
15
16pub type FastMap<K, V> = HashMap<K, V, BuildFxHasher>;
18
19pub trait FastSetBuilder<T> {
21 #[must_use]
22 fn new() -> Self;
23 #[must_use]
24 fn with_capacity(capacity: usize) -> Self;
25 #[must_use]
26 fn build<const N: usize>(array: [T; N]) -> Self;
27}
28
29impl<T: Eq + Hash> FastSetBuilder<T> for FastSet<T> {
30 fn new() -> Self {
31 Self::with_hasher(BuildFxHasher)
32 }
33
34 fn with_capacity(capacity: usize) -> Self {
35 Self::with_capacity_and_hasher(capacity, BuildFxHasher)
36 }
37
38 fn build<const N: usize>(array: [T; N]) -> Self {
39 let mut set = Self::new();
40 set.extend(array);
41 set
42 }
43}
44
45pub trait FastMapBuilder<K, V> {
47 #[must_use]
48 fn new() -> Self;
49 #[must_use]
50 fn with_capacity(capacity: usize) -> Self;
51 #[must_use]
52 fn build<const N: usize>(array: [(K, V); N]) -> Self;
53}
54
55impl<K: Eq + Hash, V> FastMapBuilder<K, V> for FastMap<K, V> {
56 fn new() -> Self {
57 Self::with_hasher(BuildFxHasher)
58 }
59
60 fn with_capacity(capacity: usize) -> Self {
61 Self::with_capacity_and_hasher(capacity, BuildFxHasher)
62 }
63
64 fn build<const N: usize>(array: [(K, V); N]) -> Self {
65 let mut map = Self::new();
66 map.extend(array);
67 map
68 }
69}
70
71#[derive(Clone, Copy, Default)]
73pub struct BuildFxHasher;
74
75impl BuildHasher for BuildFxHasher {
76 type Hasher = FxHasher;
77
78 #[inline]
79 fn build_hasher(&self) -> Self::Hasher {
80 FxHasher { hash: 0 }
81 }
82}
83
84pub struct FxHasher {
89 hash: u64,
90}
91
92impl FxHasher {
93 #[inline]
94 fn add(&mut self, i: u64) {
95 self.hash = (self.hash.rotate_left(5) ^ i).wrapping_mul(K);
96 }
97}
98
99impl Hasher for FxHasher {
100 #[inline]
101 fn write(&mut self, mut bytes: &[u8]) {
102 while let Some((&head, tail)) = bytes.split_first_chunk() {
103 self.add(u64::from_ne_bytes(head));
104 bytes = tail;
105 }
106 if let Some((&head, tail)) = bytes.split_first_chunk() {
107 self.add(u32::from_ne_bytes(head) as u64);
108 bytes = tail;
109 }
110 if let Some((&head, tail)) = bytes.split_first_chunk() {
111 self.add(u16::from_ne_bytes(head) as u64);
112 bytes = tail;
113 }
114 if !bytes.is_empty() {
115 self.add(bytes[0] as u64);
116 }
117 }
118
119 #[inline]
120 fn write_u8(&mut self, i: u8) {
121 self.add(i as u64);
122 }
123
124 #[inline]
125 fn write_u16(&mut self, i: u16) {
126 self.add(i as u64);
127 }
128
129 #[inline]
130 fn write_u32(&mut self, i: u32) {
131 self.add(i as u64);
132 }
133
134 #[inline]
135 fn write_u64(&mut self, i: u64) {
136 self.add(i);
137 }
138
139 #[inline]
140 fn write_usize(&mut self, i: usize) {
141 self.add(i as u64);
142 }
143
144 #[inline]
145 fn finish(&self) -> u64 {
146 self.hash
147 }
148}