cityhash_sys/hasher.rs
1use crate::{city_hash_128_to_64, city_hash_128, city_hash_128_with_seed, city_hash_32, city_hash_64, city_hash_64_with_seed};
2use core::hash::{BuildHasher, BuildHasherDefault, Hasher};
3
4/// 64-bits CityHash hasher
5#[derive(Debug, Default)]
6pub struct CityHash64Hasher {
7 key: Option<u64>,
8}
9
10impl CityHash64Hasher {
11 /// Create a new [CityHash64Hasher] initiated with a hash key
12 pub fn with_seed(seed: u64) -> CityHash64Hasher {
13 CityHash64Hasher { key: Some(seed) }
14 }
15}
16
17impl Hasher for CityHash64Hasher {
18 /// Returns the hash value for the values written so far.
19 ///
20 /// # Example
21 ///
22 /// ```
23 /// use cityhash_sys::CityHash64Hasher;
24 /// use core::hash::Hasher;
25 ///
26 /// let hasher = CityHash64Hasher::with_seed(0xB4BFA9E87732C149);
27 /// assert_eq!(hasher.finish(), 0xB4BFA9E87732C149);
28 /// ```
29 fn finish(&self) -> u64 {
30 self.key.unwrap_or(0)
31 }
32
33 /// Writes some data into the [CityHash64Hasher].
34 ///
35 /// # Example
36 ///
37 /// ```
38 /// use cityhash_sys::CityHash64Hasher;
39 /// use core::hash::Hasher;
40 ///
41 /// let mut hasher = CityHash64Hasher::default();
42 /// hasher.write(b"hash me!");
43 /// ```
44 fn write(&mut self, bytes: &[u8]) {
45 self.key = Some(match self.key {
46 None => city_hash_64(bytes),
47 Some(seed) => city_hash_64_with_seed(bytes, seed),
48 })
49 }
50}
51
52impl BuildHasher for CityHash64Hasher {
53 type Hasher = CityHash64Hasher;
54
55 /// Creates a new [CityHash64Hasher].
56 fn build_hasher(&self) -> Self::Hasher {
57 CityHash64Hasher::default()
58 }
59}
60
61/// 32-bits CityHash hasher
62#[derive(Debug, Default)]
63pub struct CityHash32Hasher {
64 key: Option<u32>,
65}
66
67impl CityHash32Hasher {
68 /// Create a new [CityHash32Hasher] initiated with a hash key
69 pub fn with_seed(seed: u32) -> CityHash32Hasher {
70 CityHash32Hasher { key: Some(seed) }
71 }
72}
73
74impl Hasher for CityHash32Hasher {
75 /// Returns the hash value for the values written so far.
76 ///
77 /// # Example
78 ///
79 /// ```
80 /// use cityhash_sys::CityHash32Hasher;
81 /// use core::hash::Hasher;
82 ///
83 /// let hasher = CityHash32Hasher::with_seed(0xB4BFA9E);
84 /// assert_eq!(hasher.finish(), 0xB4BFA9E);
85 /// ```
86 fn finish(&self) -> u64 {
87 if let Some(hash) = self.key {
88 hash as u64
89 } else {
90 0
91 }
92 }
93
94 /// Writes some data into the [CityHash32Hasher].
95 ///
96 /// # Example
97 ///
98 /// ```
99 /// use cityhash_sys::CityHash32Hasher;
100 /// use core::hash::Hasher;
101 ///
102 /// let mut hasher = CityHash32Hasher::default();
103 /// hasher.write(b"hash me!");
104 /// ```
105 fn write(&mut self, bytes: &[u8]) {
106 self.key = Some(match self.key {
107 None => city_hash_32(bytes),
108 Some(mut seed) => {
109 let mut key = city_hash_32(bytes);
110
111 // Mix of 2 u32 based on Murmur3.
112 // Magic numbers for 32-bit hashing.
113 const C1: u32 = 0xcc9e2d51;
114 const C2: u32 = 0x1b873593;
115
116 // Combine 2 32-bits values from Murmur3
117 key = key.wrapping_mul(C1);
118 key = key.rotate_right(17);
119 key = key.wrapping_mul(C2);
120 seed ^= key;
121 seed = seed.rotate_right(19);
122 seed.wrapping_mul(5).wrapping_add(0xe6546b64)
123 }
124 })
125 }
126}
127
128impl BuildHasher for CityHash32Hasher {
129 type Hasher = CityHash32Hasher;
130
131 /// Creates a new [CityHash32Hasher].
132 fn build_hasher(&self) -> Self::Hasher {
133 CityHash32Hasher::default()
134 }
135}
136
137/// 128-bits CityHash hasher
138#[derive(Debug, Default)]
139pub struct CityHash128Hasher {
140 key: Option<u128>,
141}
142
143impl CityHash128Hasher {
144 /// Create a new [CityHash128Hasher] initiated with a hash key
145 pub fn with_seed(seed: u128) -> CityHash128Hasher {
146 CityHash128Hasher { key: Some(seed) }
147 }
148}
149
150impl Hasher for CityHash128Hasher {
151 /// Returns the hash value for the values written so far.
152 /// The hash is compress to a 64-bits with [city_hash_128_to_64]
153 ///
154 /// # Example
155 ///
156 /// ```
157 /// use cityhash_sys::CityHash128Hasher;
158 /// use core::hash::Hasher;
159 ///
160 /// let hasher = CityHash128Hasher::with_seed(0xAAAAAAAAAAAAAAAABBBBBBBBBBBBBBBB);
161 /// assert_eq!(hasher.finish(), 0x88FC029FFEBB98B4);
162 /// ```
163 fn finish(&self) -> u64 {
164 if let Some(hash) = self.key {
165 city_hash_128_to_64(hash)
166 } else {
167 0
168 }
169 }
170
171 /// Writes some data into the [CityHash128Hasher].
172 ///
173 /// # Example
174 ///
175 /// ```
176 /// use cityhash_sys::CityHash128Hasher;
177 /// use core::hash::Hasher;
178 ///
179 /// let mut hasher = CityHash128Hasher::default();
180 /// hasher.write(b"hash me!");
181 /// ```
182 fn write(&mut self, bytes: &[u8]) {
183 self.key = Some(match self.key {
184 None => city_hash_128(bytes),
185 Some(seed) => city_hash_128_with_seed(bytes, seed),
186 })
187 }
188}
189
190impl BuildHasher for CityHash128Hasher {
191 type Hasher = CityHash128Hasher;
192
193 /// Creates a new [CityHash128Hasher].
194 fn build_hasher(&self) -> Self::Hasher {
195 CityHash128Hasher::default()
196 }
197}
198
199/// A builder for default 32-bits CityHash hashers.
200pub type CityHash32BuildHasher = BuildHasherDefault<CityHash32Hasher>;
201
202/// A builder for default 64-bits CityHash hashers.
203pub type CityHash64BuildHasher = BuildHasherDefault<CityHash64Hasher>;
204
205/// A builder for default 128-bits CityHash hashers.
206pub type CityHash128BuildHasher = BuildHasherDefault<CityHash128Hasher>;
207
208/// A builder for default CityHash hashers.
209pub type CityHashBuildHasher = CityHash64BuildHasher;