axhash_core/hasher/
core.rs1use crate::constants::SECRET;
2use crate::math::{DEFAULT_ACC, folded_multiply, seed_lane};
3
4#[derive(Clone, Debug)]
5pub struct AxHasher {
6 pub(crate) acc: u64,
7 pub(crate) sponge: u128,
8 pub(crate) sponge_bits: u8,
9}
10
11impl AxHasher {
12 #[inline(always)]
13 pub fn new() -> Self {
14 Self {
15 acc: DEFAULT_ACC,
16 sponge: 0,
17 sponge_bits: 0,
18 }
19 }
20
21 #[inline(always)]
22 pub fn new_with_seed(seed: u64) -> Self {
23 Self {
24 acc: seed_lane(seed, 0),
25 sponge: 0,
26 sponge_bits: 0,
27 }
28 }
29
30 #[inline(always)]
31 pub(crate) fn flush_sponge(&mut self) {
32 if self.sponge_bits != 0 {
33 self.flush_sponge_slow();
34 }
35 }
36
37 #[inline(always)]
38 pub(crate) fn flush_sponge_hot(&mut self) {
39 let lo = self.sponge as u64;
40 let hi = (self.sponge >> 64) as u64;
41 self.acc = folded_multiply(lo ^ self.acc, hi ^ SECRET[1]);
42 self.sponge = 0;
43 self.sponge_bits = 0;
44 }
45
46 #[inline(never)]
47 #[cold]
48 pub(crate) fn flush_sponge_slow(&mut self) {
49 self.flush_sponge_hot();
50 }
51
52 #[inline(always)]
53 pub(crate) fn push_num<T: Into<u128>>(&mut self, value: T, bits: u8) {
54 if self.sponge_bits as u16 + bits as u16 > 128 {
55 self.flush_sponge();
56 }
57
58 self.sponge |= value.into() << self.sponge_bits;
59 self.sponge_bits += bits;
60 }
61}
62
63impl Default for AxHasher {
64 #[inline(always)]
65 fn default() -> Self {
66 Self::new()
67 }
68}