kabu_evm_db/
fast_hasher.rs

1use std::hash::{BuildHasher, Hash, Hasher};
2
3use alloy::primitives::{Address, U256};
4
5#[derive(Clone, Eq, PartialEq)]
6pub struct HashedAddress(Address);
7
8#[derive(Clone, Eq, PartialEq)]
9pub struct HashedAddressCell(pub Address, pub U256);
10
11impl From<Address> for HashedAddress {
12    fn from(value: Address) -> Self {
13        HashedAddress(value)
14    }
15}
16
17impl Hash for HashedAddress {
18    #[inline]
19    fn hash<H: Hasher>(&self, state: &mut H) {
20        let mut array = [0u8; 8];
21        array.copy_from_slice(&self.0[0..8]);
22        let mut value = u64::from_ne_bytes(array);
23        array.copy_from_slice(&self.0[8..16]);
24        value ^= u64::from_ne_bytes(array);
25        let mut array = [0u8; 4];
26        array.copy_from_slice(&self.0[16..20]);
27        value += u32::from_ne_bytes(array) as u64;
28
29        state.write_u64(value);
30    }
31}
32
33impl Hash for HashedAddressCell {
34    #[inline]
35    fn hash<H: Hasher>(&self, state: &mut H) {
36        let mut value = 0x12345678;
37        let mut array = [0u8; 8];
38        array.copy_from_slice(&self.0[0..8]);
39        value += u64::from_ne_bytes(array);
40        array.copy_from_slice(&self.0[8..16]);
41        value ^= u64::from_ne_bytes(array);
42
43        let u_slice = self.1.as_le_slice();
44
45        array.copy_from_slice(&u_slice[0..8]);
46        value += u64::from_ne_bytes(array);
47        array.copy_from_slice(&u_slice[8..16]);
48        value ^= u64::from_ne_bytes(array);
49        array.copy_from_slice(&u_slice[16..24]);
50        value += u64::from_ne_bytes(array);
51        array.copy_from_slice(&u_slice[24..32]);
52        value ^= u64::from_ne_bytes(array);
53
54        let mut array = [0u8; 4];
55        array.copy_from_slice(&self.0[16..20]);
56        value += u32::from_ne_bytes(array) as u64;
57
58        state.write_u64(value);
59    }
60}
61
62#[derive(Default)]
63pub struct SimpleHasher {
64    state: u64,
65}
66
67impl SimpleHasher {
68    #[inline]
69    pub fn new() -> Self {
70        Self::default()
71    }
72}
73
74impl Hasher for SimpleHasher {
75    #[inline]
76    fn finish(&self) -> u64 {
77        self.state
78    }
79
80    #[inline]
81    fn write(&mut self, bytes_buf: &[u8]) {
82        if self.state == 0 {
83            self.state = 1;
84        } else {
85            let l = bytes_buf.len() / 8;
86            let r = bytes_buf.len() % 8;
87
88            let mut state: u64 = 0x12345678;
89            let mut array = [0u8; 8];
90            for i in 0..l {
91                array.copy_from_slice(&bytes_buf[i * 8..i * 8 + 8]);
92                let value = u64::from_ne_bytes(array);
93                if i % 2 == 0 {
94                    (state, _) = state.overflowing_add(value);
95                } else {
96                    state ^= value;
97                }
98            }
99            if r != 0 {
100                let mut array = [0u8; 8];
101                for i in 0..r {
102                    array[i] = bytes_buf[l * 8 + i]
103                }
104                let value = u64::from_ne_bytes(array);
105                state += value;
106            }
107
108            // let mut array = [0u8; 8];
109            // let mut state = 0x12345678;
110            // array.copy_from_slice(&bytes_buf[0..8]);
111            // let value = u64::from_ne_bytes(array);
112            // state += value;
113            // array.copy_from_slice(&bytes_buf[8..16]);
114            // let value = u64::from_ne_bytes(array);
115            // state ^= value;
116            // let mut array = [0u8; 4];
117            // array.copy_from_slice(&bytes_buf[16..20]);
118            // let value = u32::from_ne_bytes(array);
119            // state += value as u64;
120
121            self.state = state
122        }
123    }
124
125    #[inline]
126    fn write_u64(&mut self, i: u64) {
127        self.state = i;
128    }
129}
130
131#[derive(Default, Clone)]
132pub struct SimpleBuildHasher {}
133
134impl BuildHasher for SimpleBuildHasher {
135    type Hasher = SimpleHasher;
136
137    fn build_hasher(&self) -> Self::Hasher {
138        SimpleHasher::new()
139    }
140}
141
142#[cfg(test)]
143mod test {
144    use std::hash::Hash;
145
146    use alloy::primitives::Address;
147
148    use super::*;
149
150    #[test]
151    fn test_hasher() {
152        let addr = Address::random();
153
154        let mut hasher = SimpleHasher::new();
155        addr.hash(&mut hasher);
156    }
157
158    #[test]
159    fn test_hashed_address() {
160        let addr = HashedAddress::from(Address::random());
161
162        let mut hasher = SimpleBuildHasher {}.build_hasher();
163
164        addr.hash(&mut hasher);
165    }
166}