osom_lib_hash/hashers/
fnv1a.rs1use core::hash::{BuildHasher, Hasher};
2
3const FNV_PRIME: u64 = 0x00000100000001B3;
4const FNV_OFFSET_BASIS: u64 = 0xCBF29CE484222325;
5
6#[must_use]
7#[repr(transparent)]
8pub struct Fnv1aHasher {
9 state: u64,
10}
11
12impl Fnv1aHasher {
13 #[inline(always)]
14 pub const fn new(initial_state: u64) -> Self {
15 Self { state: initial_state }
16 }
17
18 pub const fn update(&mut self, bytes: &[u8]) {
19 let mut state = self.state;
20 let start = bytes.as_ptr();
21 let end = bytes.len();
22 let mut idx = 0;
23 while idx < end {
24 let byte = unsafe { *start.add(idx) } as u64;
25 state ^= byte;
26 state = state.wrapping_mul(FNV_PRIME);
27 idx += 1;
28 }
29 self.state = state;
30 }
31
32 #[inline(always)]
33 #[must_use]
34 pub const fn current_state(&self) -> u64 {
35 self.state
36 }
37}
38
39impl Default for Fnv1aHasher {
40 #[inline(always)]
41 fn default() -> Self {
42 Self::new(FNV_OFFSET_BASIS)
43 }
44}
45
46impl Hasher for Fnv1aHasher {
47 fn finish(&self) -> u64 {
48 self.current_state()
49 }
50
51 fn write(&mut self, bytes: &[u8]) {
52 self.update(bytes);
53 }
54}
55
56pub struct Fnv1aHasherBuilder;
57
58impl BuildHasher for Fnv1aHasherBuilder {
59 type Hasher = Fnv1aHasher;
60
61 fn build_hasher(&self) -> Self::Hasher {
62 Fnv1aHasher::default()
63 }
64}
65
66impl Default for Fnv1aHasherBuilder {
67 fn default() -> Self {
68 Self
69 }
70}