kabu_evm_db/
fast_hasher.rs1use 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 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}