Skip to main content

axhash_core/hash/
hasher_impl.rs

1use super::AxHasher;
2
3use crate::bytes::hash_bytes_core;
4use crate::constants::SECRET;
5use crate::math::{avalanche, folded_multiply};
6
7use core::hash::Hasher;
8
9impl Hasher for AxHasher {
10    #[inline(always)]
11    fn finish(&self) -> u64 {
12        // Compute the post-flush accumulator without mutating self.
13        // Avoids a 24-byte clone on every HashMap lookup/insert.
14        let final_acc = if self.sponge_bits == 0 {
15            self.acc
16        } else {
17            let lo = self.sponge as u64;
18            let hi = (self.sponge >> 64) as u64;
19            folded_multiply(lo ^ self.acc, hi ^ SECRET[1])
20        };
21        avalanche(final_acc)
22    }
23
24    #[inline(always)]
25    fn write(&mut self, bytes: &[u8]) {
26        self.flush_sponge();
27        self.acc = hash_bytes_core(bytes, self.acc);
28    }
29
30    #[inline(always)]
31    fn write_u8(&mut self, i: u8) {
32        self.push_num(i, 8);
33    }
34
35    #[inline(always)]
36    fn write_u16(&mut self, i: u16) {
37        self.push_num(i, 16);
38    }
39
40    #[inline(always)]
41    fn write_u32(&mut self, i: u32) {
42        self.flush_sponge();
43
44        self.acc = folded_multiply(self.acc ^ i as u64, SECRET[1]);
45    }
46
47    #[inline(always)]
48    fn write_u64(&mut self, i: u64) {
49        self.flush_sponge();
50
51        self.acc = folded_multiply(self.acc ^ i, SECRET[1]);
52    }
53
54    #[inline(always)]
55    fn write_u128(&mut self, i: u128) {
56        self.flush_sponge();
57        let lo = i as u64;
58        let hi = (i >> 64) as u64;
59        self.acc = folded_multiply(lo ^ self.acc, hi ^ SECRET[1]);
60    }
61
62    #[inline(always)]
63    fn write_usize(&mut self, i: usize) {
64        #[cfg(target_pointer_width = "32")]
65        self.write_u32(i as u32);
66        #[cfg(target_pointer_width = "64")]
67        self.write_u64(i as u64);
68    }
69
70    #[inline(always)]
71    fn write_i8(&mut self, i: i8) {
72        self.write_u8(i as u8);
73    }
74
75    #[inline(always)]
76    fn write_i16(&mut self, i: i16) {
77        self.write_u16(i as u16);
78    }
79
80    #[inline(always)]
81    fn write_i32(&mut self, i: i32) {
82        self.write_u32(i as u32);
83    }
84
85    #[inline(always)]
86    fn write_i64(&mut self, i: i64) {
87        self.write_u64(i as u64);
88    }
89
90    #[inline(always)]
91    fn write_i128(&mut self, i: i128) {
92        self.write_u128(i as u128);
93    }
94
95    #[inline(always)]
96    fn write_isize(&mut self, i: isize) {
97        self.write_usize(i as usize);
98    }
99}