1use crate::value::Value;
2
3pub fn murmurhash3_finalize(mut h: u64) -> u64 {
9 h ^= h >> 33;
10 h = h.wrapping_mul(0xff51afd7ed558ccd);
11 h ^= h >> 33;
12 h = h.wrapping_mul(0xc4ceb9fe1a85ec53);
13 h ^= h >> 33;
14 h
15}
16
17pub fn murmurhash3(data: &[u8]) -> u64 {
19 const SEED: u64 = 0x5f3759df;
20 let mut h = SEED;
21 let chunks = data.len() / 8;
23 for i in 0..chunks {
24 let mut k = [0u8; 8];
25 k.copy_from_slice(&data[i * 8..(i + 1) * 8]);
26 let k = u64::from_le_bytes(k);
27 let k = k.wrapping_mul(0x87c37b91114253d5);
28 let k = k.rotate_left(31);
29 let k = k.wrapping_mul(0x4cf5ad432745937f);
30 h ^= k;
31 h = h.rotate_left(27);
32 h = h.wrapping_mul(5).wrapping_add(0x52dce729);
33 }
34 let tail = &data[chunks * 8..];
36 let mut k: u64 = 0;
37 for (i, &b) in tail.iter().enumerate() {
38 k |= (b as u64) << (i * 8);
39 }
40 if !tail.is_empty() {
41 let k = k.wrapping_mul(0x87c37b91114253d5);
42 let k = k.rotate_left(31);
43 let k = k.wrapping_mul(0x4cf5ad432745937f);
44 h ^= k;
45 }
46 h ^= data.len() as u64;
47 murmurhash3_finalize(h)
48}
49
50pub fn value_hash(val: &Value) -> u64 {
52 match val {
53 Value::Int(n) => murmurhash3(&n.to_le_bytes()),
54 Value::Float(f) => murmurhash3(&f.to_bits().to_le_bytes()),
55 Value::Bool(b) => murmurhash3(&[*b as u8]),
56 Value::String(s) => murmurhash3(s.as_bytes()),
57 Value::Bytes(b) => murmurhash3(&b.borrow()),
58 Value::ByteSlice(b) => murmurhash3(b),
59 Value::StrView(b) => murmurhash3(b),
60 Value::U8(v) => murmurhash3(&[*v]),
61 Value::Bf16(v) => murmurhash3(&v.0.to_le_bytes()),
62 Value::Enum {
63 enum_name,
64 variant,
65 fields,
66 } => {
67 let mut h = murmurhash3(enum_name.as_bytes());
69 h ^= murmurhash3(variant.as_bytes());
70 for f in fields {
71 h ^= value_hash(f);
72 }
73 h
74 }
75 Value::Void => murmurhash3(&[0xff]),
76 _ => murmurhash3(&[0xfe]),
77 }
78}
79
80#[derive(Debug, Clone)]
83pub struct DetMap {
84 entries: Vec<Option<(u64, Value, Value)>>,
86 order: Vec<usize>,
88 len: usize,
89 capacity: usize,
90}
91
92const FIBONACCI_CONSTANT: u64 = 11400714819323198485; impl DetMap {
95 pub fn new() -> Self {
96 let capacity = 8;
97 DetMap {
98 entries: vec![None; capacity],
99 order: Vec::new(),
100 len: 0,
101 capacity,
102 }
103 }
104
105 fn slot_index(&self, hash: u64) -> usize {
106 let shift = 64 - (self.capacity.trailing_zeros() as u64);
107 (hash.wrapping_mul(FIBONACCI_CONSTANT) >> shift) as usize
108 }
109
110 pub fn insert(&mut self, key: Value, value: Value) {
111 if self.len * 4 >= self.capacity * 3 {
112 self.grow();
113 }
114 let hash = value_hash(&key);
115 let mut slot = self.slot_index(hash);
116 loop {
117 match &self.entries[slot] {
118 None => {
119 self.entries[slot] = Some((hash, key, value));
120 self.order.push(slot);
121 self.len += 1;
122 return;
123 }
124 Some((h, k, _)) => {
125 if *h == hash && values_equal_static(k, &key) {
126 self.entries[slot] = Some((hash, key, value));
128 return;
129 }
130 slot = (slot + 1) % self.capacity;
131 }
132 }
133 }
134 }
135
136 pub fn get(&self, key: &Value) -> Option<&Value> {
137 let hash = value_hash(key);
138 let mut slot = self.slot_index(hash);
139 let start = slot;
140 loop {
141 match &self.entries[slot] {
142 None => return None,
143 Some((h, k, v)) => {
144 if *h == hash && values_equal_static(k, key) {
145 return Some(v);
146 }
147 slot = (slot + 1) % self.capacity;
148 if slot == start {
149 return None;
150 }
151 }
152 }
153 }
154 }
155
156 pub fn contains_key(&self, key: &Value) -> bool {
157 self.get(key).is_some()
158 }
159
160 pub fn remove(&mut self, key: &Value) -> Option<Value> {
161 let hash = value_hash(key);
162 let mut slot = self.slot_index(hash);
163 let start = slot;
164 loop {
165 match &self.entries[slot] {
166 None => return None,
167 Some((h, k, _)) => {
168 if *h == hash && values_equal_static(k, key) {
169 let (_, _, v) = self.entries[slot].take().unwrap();
170 self.len -= 1;
171 self.order.retain(|&s| s != slot);
172 let mut next = (slot + 1) % self.capacity;
175 while self.entries[next].is_some() {
176 let entry = self.entries[next].take().unwrap();
177 let old_slot = next;
178 let rehash = entry.0;
179 let rkey = entry.1;
180 let rval = entry.2;
181 let mut new_slot = self.slot_index(rehash);
183 while self.entries[new_slot].is_some() {
184 new_slot = (new_slot + 1) % self.capacity;
185 }
186 self.entries[new_slot] = Some((rehash, rkey, rval));
187 for s in &mut self.order {
190 if *s == old_slot {
191 *s = new_slot;
192 break;
193 }
194 }
195 next = (next + 1) % self.capacity;
196 }
197 return Some(v);
198 }
199 slot = (slot + 1) % self.capacity;
200 if slot == start {
201 return None;
202 }
203 }
204 }
205 }
206 }
207
208 pub fn iter(&self) -> impl Iterator<Item = (&Value, &Value)> {
210 self.order.iter().filter_map(move |&slot| {
211 self.entries[slot]
212 .as_ref()
213 .map(|(_, k, v)| (k, v))
214 })
215 }
216
217 pub fn keys(&self) -> Vec<Value> {
218 self.iter().map(|(k, _)| k.clone()).collect()
219 }
220
221 pub fn values_vec(&self) -> Vec<Value> {
222 self.iter().map(|(_, v)| v.clone()).collect()
223 }
224
225 pub fn len(&self) -> usize {
226 self.len
227 }
228
229 pub fn is_empty(&self) -> bool {
230 self.len == 0
231 }
232
233 fn grow(&mut self) {
234 let new_capacity = self.capacity * 2;
235 let old_order = self.order.clone();
236 let old_entries: Vec<_> = old_order
237 .iter()
238 .filter_map(|&slot| self.entries[slot].clone())
239 .collect();
240
241 self.entries = vec![None; new_capacity];
242 self.order = Vec::new();
243 self.len = 0;
244 self.capacity = new_capacity;
245
246 for (hash, key, value) in old_entries {
247 let _ = hash; self.insert(key, value);
249 }
250 }
251}
252
253impl Default for DetMap {
254 fn default() -> Self {
255 Self::new()
256 }
257}
258
259pub fn values_equal_static(a: &Value, b: &Value) -> bool {
261 match (a, b) {
262 (Value::Int(a), Value::Int(b)) => a == b,
263 (Value::Float(a), Value::Float(b)) => a.to_bits() == b.to_bits(),
264 (Value::Bool(a), Value::Bool(b)) => a == b,
265 (Value::String(a), Value::String(b)) => a == b,
266 (Value::Bytes(a), Value::Bytes(b)) => *a.borrow() == *b.borrow(),
267 (Value::ByteSlice(a), Value::ByteSlice(b)) => **a == **b,
268 (Value::StrView(a), Value::StrView(b)) => **a == **b,
269 (Value::U8(a), Value::U8(b)) => a == b,
270 (Value::Bf16(a), Value::Bf16(b)) => a.0 == b.0,
271 (
272 Value::Enum {
273 enum_name: en1,
274 variant: v1,
275 fields: f1,
276 },
277 Value::Enum {
278 enum_name: en2,
279 variant: v2,
280 fields: f2,
281 },
282 ) => {
283 en1 == en2
284 && v1 == v2
285 && f1.len() == f2.len()
286 && f1
287 .iter()
288 .zip(f2.iter())
289 .all(|(a, b)| values_equal_static(a, b))
290 }
291 (Value::Void, Value::Void) => true,
292 _ => false,
293 }
294}
295