1use std::hash::Hasher;
3use std::mem;
4use std::ptr::NonNull;
5
6use crate::{FastHash, FastHasher, HasherExt, StreamHasher};
7
8#[inline(always)]
18pub fn hash64<T: AsRef<[u8]>>(v: T) -> u64 {
19 Hash64::hash(v)
20}
21
22#[inline(always)]
33pub fn hash64_with_seed<T: AsRef<[u8]>>(v: T, seed: u64) -> u64 {
34 Hash64::hash_with_seed(v, seed)
35}
36
37#[inline(always)]
50pub fn hash128<T: AsRef<[u8]>>(v: T) -> u128 {
51 Hash128::hash(v)
52}
53
54#[inline(always)]
69pub fn hash128_with_seed<T: AsRef<[u8]>>(v: T, seed: u64) -> u128 {
70 Hash128::hash_with_seed(v, seed)
71}
72
73#[derive(Clone, Default)]
92pub struct Hash64;
93
94impl FastHash for Hash64 {
95 type Hash = u64;
96 type Seed = u64;
97
98 #[inline(always)]
99 fn hash<T: AsRef<[u8]>>(bytes: T) -> Self::Hash {
100 let bytes = bytes.as_ref();
101
102 unsafe { ffi::XXH3_64bits(bytes.as_ptr() as *const _, bytes.len()) }
103 }
104
105 #[inline(always)]
106 fn hash_with_seed<T: AsRef<[u8]>>(bytes: T, seed: Self::Seed) -> Self::Hash {
107 let bytes = bytes.as_ref();
108
109 unsafe { ffi::XXH3_64bits_withSeed(bytes.as_ptr() as *const _, bytes.len(), seed) }
110 }
111}
112
113pub struct Hasher64(NonNull<ffi::XXH3_state_t>);
131
132impl Default for Hasher64 {
133 fn default() -> Self {
134 Hasher64(unsafe { NonNull::new_unchecked(ffi::XXH3_createState()) })
135 }
136}
137
138impl Clone for Hasher64 {
139 fn clone(&self) -> Self {
140 unsafe {
141 let state = ffi::XXH3_createState();
142
143 ffi::XXH3_copyState(state, self.0.as_ptr());
144
145 Hasher64(NonNull::new_unchecked(state))
146 }
147 }
148}
149
150impl Drop for Hasher64 {
151 fn drop(&mut self) {
152 unsafe {
153 ffi::XXH3_freeState(self.0.as_ptr());
154 }
155 }
156}
157
158impl Hasher for Hasher64 {
159 #[inline(always)]
160 fn finish(&self) -> u64 {
161 unsafe { ffi::XXH3_64bits_digest(self.0.as_ptr()) }
162 }
163
164 #[inline(always)]
165 fn write(&mut self, bytes: &[u8]) {
166 unsafe {
167 ffi::XXH3_64bits_update(self.0.as_ptr(), bytes.as_ptr() as *const _, bytes.len());
168 }
169 }
170}
171
172impl FastHasher for Hasher64 {
173 type Seed = u64;
174 type Output = u64;
175
176 #[inline(always)]
177 fn with_seed(seed: u64) -> Self {
178 unsafe {
179 let state = ffi::XXH3_createState();
180
181 ffi::XXH3_64bits_reset_withSeed(state, seed);
182
183 Hasher64(NonNull::new_unchecked(state))
184 }
185 }
186}
187
188impl StreamHasher for Hasher64 {}
189
190impl_build_hasher!(Hasher64, Hash64);
191
192#[derive(Clone, Default)]
211pub struct Hash128;
212
213impl FastHash for Hash128 {
214 type Hash = u128;
215 type Seed = u64;
216
217 #[inline(always)]
218 fn hash<T: AsRef<[u8]>>(bytes: T) -> Self::Hash {
219 let bytes = bytes.as_ref();
220
221 unsafe { mem::transmute(ffi::XXH3_128bits(bytes.as_ptr() as *const _, bytes.len())) }
222 }
223
224 #[inline(always)]
225 fn hash_with_seed<T: AsRef<[u8]>>(bytes: T, seed: Self::Seed) -> Self::Hash {
226 let bytes = bytes.as_ref();
227
228 unsafe {
229 mem::transmute(ffi::XXH3_128bits_withSeed(
230 bytes.as_ptr() as *const _,
231 bytes.len(),
232 seed,
233 ))
234 }
235 }
236}
237
238pub struct Hasher128(NonNull<ffi::XXH3_state_t>);
256
257impl Default for Hasher128 {
258 fn default() -> Self {
259 Hasher128(unsafe { NonNull::new_unchecked(ffi::XXH3_createState()) })
260 }
261}
262
263impl Clone for Hasher128 {
264 fn clone(&self) -> Self {
265 unsafe {
266 let state = ffi::XXH3_createState();
267
268 ffi::XXH3_copyState(state, self.0.as_ptr());
269
270 Hasher128(NonNull::new_unchecked(state))
271 }
272 }
273}
274
275impl Drop for Hasher128 {
276 fn drop(&mut self) {
277 unsafe {
278 ffi::XXH3_freeState(self.0.as_ptr());
279 }
280 }
281}
282
283impl Hasher for Hasher128 {
284 #[inline(always)]
285 fn finish(&self) -> u64 {
286 unsafe { ffi::XXH3_128bits_digest(self.0.as_ptr()).low64 }
287 }
288
289 #[inline(always)]
290 fn write(&mut self, bytes: &[u8]) {
291 unsafe {
292 ffi::XXH3_128bits_update(self.0.as_ptr(), bytes.as_ptr() as *const _, bytes.len());
293 }
294 }
295}
296
297impl HasherExt for Hasher128 {
298 #[inline(always)]
299 fn finish_ext(&self) -> u128 {
300 let h = unsafe { ffi::XXH3_128bits_digest(self.0.as_ptr()) };
301
302 u128::from(h.low64) + (u128::from(h.high64) << 64)
303 }
304}
305
306impl FastHasher for Hasher128 {
307 type Seed = u64;
308 type Output = u128;
309
310 #[inline(always)]
311 fn with_seed(seed: u64) -> Self {
312 unsafe {
313 let state = ffi::XXH3_createState();
314
315 ffi::XXH3_128bits_reset_withSeed(state, seed);
316
317 Hasher128(NonNull::new_unchecked(state))
318 }
319 }
320}
321
322impl StreamHasher for Hasher128 {}
323
324impl_build_hasher!(Hasher128, Hash128);