osom_lib_hash/hashers/
fnv1a.rs

1use 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}