1use std::hash::Hasher;
2
3const C1: u32 = 0xcc9e2d51;
4const C2: u32 = 0x1b873593;
5const R1: u32 = 15;
6const R2: u32 = 13;
7const M: u32 = 5;
8const N: u32 = 0xe6546b64;
9
10#[inline(always)]
11pub fn murmur3_32(key: &[u8], seed: u32) -> u32 {
12 let mut h = seed;
13 let mut chunks = key.chunks_exact(4);
14
15 for chunk in chunks.by_ref() {
16 let mut k = u32::from_le_bytes([chunk[0], chunk[1], chunk[2], chunk[3]]);
17 k = k.wrapping_mul(C1);
18 k = k.rotate_left(R1);
19 k = k.wrapping_mul(C2);
20
21 h ^= k;
22 h = h.rotate_left(R2);
23 h = h.wrapping_mul(M).wrapping_add(N);
24 }
25
26 let remainder = chunks.remainder();
27 if !remainder.is_empty() {
28 let mut k = 0u32;
29 for (i, &byte) in remainder.iter().enumerate() {
30 k |= (byte as u32) << (i * 8);
31 }
32
33 k = k.wrapping_mul(C1);
34 k = k.rotate_left(R1);
35 k = k.wrapping_mul(C2);
36 h ^= k;
37 }
38
39 h ^= key.len() as u32;
40 h ^= h >> 16;
41 h = h.wrapping_mul(0x85ebca6b);
42 h ^= h >> 13;
43 h = h.wrapping_mul(0xc2b2ae35);
44 h ^= h >> 16;
45
46 h
47}
48
49pub fn hash_key(key: &[u8]) -> u32 {
54 #[cfg(target_arch = "x86_64")]
55 {
56 if let Some(hash) = simd::hash_key_aes_safe(key) {
57 return hash;
58 }
59 }
60 murmur3_32(key, 0)
61}
62
63#[cfg(target_arch = "x86_64")]
64pub mod simd {
65 use std::arch::x86_64::*;
66
67 pub fn hash_key_aes_safe(key: &[u8]) -> Option<u32> {
71 if is_x86_feature_detected!("aes") {
72 unsafe { Some(hash_key_aes_unsafe(key)) }
73 } else {
74 None
75 }
76 }
77
78 #[target_feature(enable = "aes")]
86 #[inline]
87 unsafe fn hash_key_aes_unsafe(key: &[u8]) -> u32 {
88 let seed = _mm_set_epi32(
90 0x9747b28c_u32 as i32,
91 0xc2b2ae35_u32 as i32,
92 0x85ebca6b_u32 as i32,
93 0xe6546b64_u32 as i32,
94 );
95 let mut hash = seed;
96
97 let mut chunks = key.chunks_exact(16);
99 for chunk in chunks.by_ref() {
100 let data = _mm_loadu_si128(chunk.as_ptr() as *const __m128i);
101 hash = _mm_xor_si128(hash, data);
103 hash = _mm_aesenc_si128(hash, seed);
105 }
106
107 let remainder = chunks.remainder();
109 if !remainder.is_empty() {
110 let mut buffer = [0u8; 16];
111 buffer[..remainder.len()].copy_from_slice(remainder);
112 buffer[15] = remainder.len() as u8;
114
115 let data = _mm_loadu_si128(buffer.as_ptr() as *const __m128i);
116 hash = _mm_xor_si128(hash, data);
117 hash = _mm_aesenc_si128(hash, seed);
118 }
119
120 let len_vec = _mm_set1_epi32(key.len() as i32);
122 hash = _mm_xor_si128(hash, len_vec);
123 hash = _mm_aesenc_si128(hash, seed);
124
125 let a = _mm_extract_epi32(hash, 0) as u32;
127 let b = _mm_extract_epi32(hash, 1) as u32;
128 let c = _mm_extract_epi32(hash, 2) as u32;
129 let d = _mm_extract_epi32(hash, 3) as u32;
130
131 let mut h = a ^ b ^ c ^ d;
133 h ^= h >> 16;
134 h = h.wrapping_mul(0x85ebca6b);
135 h ^= h >> 13;
136 h = h.wrapping_mul(0xc2b2ae35);
137 h ^= h >> 16;
138
139 h
140 }
141}
142
143pub struct MurmurHasher {
144 state: u32,
145}
146
147impl Default for MurmurHasher {
148 fn default() -> Self {
149 Self::new()
150 }
151}
152
153impl MurmurHasher {
154 pub fn new() -> Self {
155 Self { state: 0 }
156 }
157
158 pub fn with_seed(seed: u32) -> Self {
159 Self { state: seed }
160 }
161}
162
163impl Hasher for MurmurHasher {
164 fn write(&mut self, bytes: &[u8]) {
165 self.state = murmur3_32(bytes, self.state);
166 }
167
168 fn finish(&self) -> u64 {
169 self.state as u64
170 }
171}