1use core::marker::PhantomData;
2
3use borsh::{BorshDeserialize, BorshSerialize};
4use bytes::BufMut;
5use casper_executor_wasm_common::keyspace::Keyspace;
6use const_fnv1a_hash::fnv1a_hash_64;
7
8use crate::casper::{self, read_into_vec};
9
10#[derive(BorshSerialize, BorshDeserialize, Debug, Clone, Copy, PartialEq)]
12pub struct IterableMapPtr {
13 pub(crate) hash: u64,
15 pub(crate) index: u64,
18}
19
20pub trait IterableMapHash: PartialEq + BorshSerialize + BorshDeserialize {
26 fn compute_hash(&self) -> u64 {
27 let mut bytes = Vec::new();
28 self.serialize(&mut bytes).unwrap();
29 fnv1a_hash_64(&bytes, None)
30 }
31}
32
33impl IterableMapHash for u8 {}
36impl IterableMapHash for u16 {}
37impl IterableMapHash for u32 {}
38impl IterableMapHash for u64 {}
39impl IterableMapHash for u128 {}
40impl IterableMapHash for i8 {}
41impl IterableMapHash for i16 {}
42impl IterableMapHash for i32 {}
43impl IterableMapHash for i64 {}
44impl IterableMapHash for i128 {}
45impl IterableMapHash for String {}
46
47#[derive(BorshSerialize, BorshDeserialize, Debug, Clone)]
59#[borsh(crate = "crate::serializers::borsh")]
60pub struct IterableMap<K, V> {
61 pub(crate) prefix: String,
62
63 pub(crate) tail_key_hash: Option<IterableMapPtr>,
67 _marker: PhantomData<(K, V)>,
68}
69
70#[derive(BorshSerialize, BorshDeserialize, Debug, Clone)]
72#[borsh(crate = "crate::serializers::borsh")]
73pub struct IterableMapEntry<K, V> {
74 pub(crate) key: K,
75 pub(crate) value: Option<V>,
76 pub(crate) previous: Option<IterableMapPtr>,
77}
78
79impl<K, V> IterableMap<K, V>
80where
81 K: IterableMapHash,
82 V: BorshSerialize + BorshDeserialize,
83{
84 pub fn new<S: Into<String>>(prefix: S) -> Self {
86 Self {
87 prefix: prefix.into(),
88 tail_key_hash: None,
89 _marker: PhantomData,
90 }
91 }
92
93 pub fn insert(&mut self, key: K, value: V) -> Option<V> {
102 let (ptr, at_ptr) = self.get_writable_slot(&key);
104
105 let (entry_to_write, previous) = match at_ptr {
107 Some(mut entry) => {
108 if entry.value.is_none() {
109 entry.key = key;
111 entry.previous = self.tail_key_hash;
112 entry.value = Some(value);
113 self.tail_key_hash = Some(ptr);
114 (entry, None)
115 } else {
116 let old = entry.value;
118 entry.value = Some(value);
119 (entry, old)
120 }
121 }
122 None => {
123 let entry = IterableMapEntry {
124 key,
125 value: Some(value),
126 previous: self.tail_key_hash,
127 };
128
129 self.tail_key_hash = Some(ptr);
131
132 (entry, None)
133 }
134 };
135
136 let mut entry_bytes = Vec::new();
138 entry_to_write.serialize(&mut entry_bytes).unwrap();
139
140 let prefix = self.create_prefix_from_ptr(&ptr);
141 let keyspace = Keyspace::Context(&prefix);
142 casper::write(keyspace, &entry_bytes).unwrap();
143
144 previous
145 }
146
147 pub fn get(&self, key: &K) -> Option<V> {
149 let (_, at_ptr) = self.get_writable_slot(key);
151 at_ptr.and_then(|entry| entry.value)
152 }
153
154 pub fn remove(&mut self, key: &K) -> Option<V> {
158 let (to_remove_ptr, at_remove_ptr) = self.find_slot(key)?;
160
161 let to_remove_prefix = self.create_prefix_from_ptr(&to_remove_ptr);
162 let to_remove_context_key = Keyspace::Context(&to_remove_prefix);
163
164 let to_remove_ptr_child_prefix = self.create_prefix_from_ptr(&IterableMapPtr {
167 index: to_remove_ptr.index + 1,
168 ..to_remove_ptr
169 });
170 let to_remove_ptr_child_keyspace = Keyspace::Context(&to_remove_ptr_child_prefix);
171
172 if self.get_entry(to_remove_ptr_child_keyspace).is_some() {
173 let tombstone = IterableMapEntry {
177 value: None,
178 ..at_remove_ptr
179 };
180
181 let mut entry_bytes = Vec::new();
183 tombstone.serialize(&mut entry_bytes).unwrap();
184 casper::write(to_remove_context_key, &entry_bytes).unwrap();
185 } else {
186 casper::remove(to_remove_context_key).unwrap();
188 }
189
190 if self.tail_key_hash == Some(to_remove_ptr) {
192 self.tail_key_hash = at_remove_ptr.previous;
193 return at_remove_ptr.value;
194 }
195
196 let mut current_hash = self.tail_key_hash;
198 while let Some(key) = current_hash {
199 let current_prefix = self.create_prefix_from_ptr(&key);
200 let current_context_key = Keyspace::Context(¤t_prefix);
201 let mut current_entry = self.get_entry(current_context_key).unwrap();
202
203 let Some(next_hash) = current_entry.previous else {
209 panic!("Unexpected end of IterableMap");
210 };
211
212 if next_hash == to_remove_ptr {
215 current_entry.previous = at_remove_ptr.previous;
217
218 let mut entry_bytes = Vec::new();
220 current_entry.serialize(&mut entry_bytes).unwrap();
221 casper::write(current_context_key, &entry_bytes).unwrap();
222
223 return at_remove_ptr.value;
224 }
225
226 current_hash = current_entry.previous;
228 }
229
230 None
231 }
232
233 pub fn clear(&mut self) {
235 for key in self.keys() {
236 let prefix = self.create_prefix_from_key(&key);
237 {
238 let key = Keyspace::Context(&prefix);
239 casper::remove(key).unwrap()
240 };
241 }
242
243 self.tail_key_hash = None;
244 }
245
246 pub fn contains_key(&self, key: &K) -> bool {
248 self.get(key).is_some()
249 }
250
251 pub fn keys(&self) -> impl Iterator<Item = K> + '_ {
253 self.iter().map(|(key, _)| key)
254 }
255
256 pub fn values(&self) -> impl Iterator<Item = V> + '_ {
258 self.iter().map(|(_, value)| value)
259 }
260
261 pub fn is_empty(&self) -> bool {
263 self.tail_key_hash.is_none()
264 }
265
266 pub fn iter(&self) -> IterableMapIter<K, V> {
271 IterableMapIter {
272 prefix: &self.prefix,
273 current: self.tail_key_hash,
274 _marker: PhantomData,
275 }
276 }
277
278 pub fn len(&self) -> usize {
282 self.iter().count()
283 }
284
285 fn find_slot(&self, key: &K) -> Option<(IterableMapPtr, IterableMapEntry<K, V>)> {
287 let mut bucket_ptr = self.create_root_ptr_from_key(key);
288
289 loop {
292 let prefix = self.create_prefix_from_ptr(&bucket_ptr);
293 let keyspace = Keyspace::Context(&prefix);
294
295 if let Some(entry) = self.get_entry(keyspace) {
296 if entry.key == *key && entry.value.is_some() {
298 return Some((bucket_ptr, entry));
300 } else {
301 bucket_ptr.index += 1;
304 continue;
305 }
306 } else {
307 return None;
309 }
310 }
311 }
312
313 fn get_writable_slot(&self, key: &K) -> (IterableMapPtr, Option<IterableMapEntry<K, V>>) {
316 let mut bucket_ptr = self.create_root_ptr_from_key(key);
317
318 loop {
321 let prefix = self.create_prefix_from_ptr(&bucket_ptr);
322 let keyspace = Keyspace::Context(&prefix);
323
324 if let Some(entry) = self.get_entry(keyspace) {
325 if entry.key == *key {
327 return (bucket_ptr, Some(entry));
329 } else if entry.value.is_none() {
330 return (bucket_ptr, Some(entry));
333 } else {
334 bucket_ptr.index += 1;
338 continue;
339 }
340 } else {
341 return (bucket_ptr, None);
343 }
344 }
345 }
346
347 fn get_entry(&self, keyspace: Keyspace) -> Option<IterableMapEntry<K, V>> {
348 match read_into_vec(keyspace) {
349 Ok(Some(vec)) => {
350 let entry: IterableMapEntry<K, V> = borsh::from_slice(&vec).unwrap();
351 Some(entry)
352 }
353 Ok(None) => None,
354 Err(_) => None,
355 }
356 }
357
358 fn create_prefix_from_key(&self, key: &K) -> Vec<u8> {
359 let ptr = self.create_root_ptr_from_key(key);
360 self.create_prefix_from_ptr(&ptr)
361 }
362
363 fn create_root_ptr_from_key(&self, key: &K) -> IterableMapPtr {
364 IterableMapPtr {
365 hash: key.compute_hash(),
366 index: 0,
367 }
368 }
369
370 fn create_prefix_from_ptr(&self, hash: &IterableMapPtr) -> Vec<u8> {
371 let mut context_key = Vec::new();
372 context_key.extend(self.prefix.as_bytes());
373 context_key.extend(b"_");
374 context_key.put_u64_le(hash.hash);
375 context_key.extend(b"_");
376 context_key.put_u64_le(hash.index);
377 context_key
378 }
379}
380
381pub struct IterableMapIter<'a, K, V> {
394 prefix: &'a str,
395 current: Option<IterableMapPtr>,
396 _marker: PhantomData<(K, V)>,
397}
398
399impl<'a, K, V> IntoIterator for &'a IterableMap<K, V>
400where
401 K: BorshDeserialize,
402 V: BorshDeserialize,
403{
404 type Item = (K, V);
405 type IntoIter = IterableMapIter<'a, K, V>;
406
407 fn into_iter(self) -> Self::IntoIter {
408 IterableMapIter {
409 prefix: &self.prefix,
410 current: self.tail_key_hash,
411 _marker: PhantomData,
412 }
413 }
414}
415
416impl<K, V> Iterator for IterableMapIter<'_, K, V>
417where
418 K: BorshDeserialize,
419 V: BorshDeserialize,
420{
421 type Item = (K, V);
422
423 fn next(&mut self) -> Option<Self::Item> {
424 let current_hash = self.current?;
425 let mut key_bytes = Vec::new();
426 key_bytes.extend(self.prefix.as_bytes());
427 key_bytes.extend(b"_");
428 key_bytes.put_u64_le(current_hash.hash);
429 key_bytes.extend(b"_");
430 key_bytes.put_u64_le(current_hash.index);
431
432 let context_key = Keyspace::Context(&key_bytes);
433
434 match read_into_vec(context_key) {
435 Ok(Some(vec)) => {
436 let entry: IterableMapEntry<K, V> = borsh::from_slice(&vec).unwrap();
437 self.current = entry.previous;
438 Some((
439 entry.key,
440 entry
441 .value
442 .expect("Tombstone values should be unlinked on removal"),
443 ))
444 }
445 Ok(None) => None,
446 Err(_) => None,
447 }
448 }
449}
450
451#[cfg(test)]
452mod tests {
453 use super::*;
454 use crate::casper::native::dispatch;
455
456 const TEST_MAP_PREFIX: &str = "test_map";
457
458 #[test]
459 fn insert_and_get() {
460 dispatch(|| {
461 let mut map = IterableMap::<u64, String>::new(TEST_MAP_PREFIX);
462 assert_eq!(map.len(), 0);
463
464 assert_eq!(map.get(&1), None);
465
466 map.insert(1, "a".to_string());
467 assert_eq!(map.len(), 1);
468
469 assert_eq!(map.get(&1), Some("a".to_string()));
470
471 map.insert(2, "b".to_string());
472 assert_eq!(map.len(), 2);
473
474 assert_eq!(map.get(&2), Some("b".to_string()));
475 })
476 .unwrap();
477 }
478
479 #[test]
480 fn overwrite_existing_key() {
481 dispatch(|| {
482 let mut map = IterableMap::<u64, String>::new(TEST_MAP_PREFIX);
483
484 assert_eq!(map.insert(1, "a".to_string()), None);
485 assert_eq!(map.insert(1, "b".to_string()), Some("a".to_string()));
486 assert_eq!(map.get(&1), Some("b".to_string()));
487 })
488 .unwrap();
489 }
490
491 #[test]
492 fn remove_tail_entry() {
493 dispatch(|| {
494 let mut map = IterableMap::<u64, String>::new(TEST_MAP_PREFIX);
495 assert_eq!(map.len(), 0);
496 map.insert(1, "a".to_string());
497 assert_eq!(map.len(), 1);
498 map.insert(2, "b".to_string());
499 assert_eq!(map.len(), 2);
500 assert_eq!(map.remove(&2), Some("b".to_string()));
501 assert_eq!(map.len(), 1);
502 assert_eq!(map.get(&2), None);
503 assert_eq!(map.get(&1), Some("a".to_string()));
504 })
505 .unwrap();
506 }
507
508 #[test]
509 fn remove_middle_entry() {
510 dispatch(|| {
511 let mut map = IterableMap::<u64, String>::new(TEST_MAP_PREFIX);
512 assert_eq!(map.len(), 0);
513
514 map.insert(1, "a".to_string());
515 assert_eq!(map.len(), 1);
516
517 map.insert(2, "b".to_string());
518 assert_eq!(map.len(), 2);
519
520 map.insert(3, "c".to_string());
521 assert_eq!(map.len(), 3);
522
523 assert_eq!(map.remove(&2), Some("b".to_string()));
524 assert_eq!(map.len(), 2);
525
526 assert_eq!(map.get(&2), None);
527 assert_eq!(map.get(&1), Some("a".to_string()));
528 assert_eq!(map.get(&3), Some("c".to_string()));
529
530 assert_eq!(map.len(), 2);
531 })
532 .unwrap();
533 }
534
535 #[test]
536 fn remove_nonexistent_key_does_nothing() {
537 dispatch(|| {
538 let mut map = IterableMap::<u64, String>::new(TEST_MAP_PREFIX);
539
540 map.insert(1, "a".to_string());
541
542 assert_eq!(map.remove(&999), None);
543 assert_eq!(map.get(&1), Some("a".to_string()));
544 })
545 .unwrap();
546 }
547
548 #[test]
549 fn iterates_all_entries_in_reverse_insertion_order() {
550 dispatch(|| {
551 let mut map = IterableMap::<u64, String>::new(TEST_MAP_PREFIX);
552
553 map.insert(1, "a".to_string());
554 map.insert(2, "b".to_string());
555 map.insert(3, "c".to_string());
556
557 let values: Vec<_> = map.values().collect();
558 assert_eq!(
559 values,
560 vec!["c".to_string(), "b".to_string(), "a".to_string(),]
561 );
562 })
563 .unwrap();
564 }
565
566 #[test]
567 fn iteration_skips_deleted_entries() {
568 dispatch(|| {
569 let mut map = IterableMap::<u64, String>::new(TEST_MAP_PREFIX);
570
571 map.insert(1, "a".to_string());
572 map.insert(2, "b".to_string());
573 map.insert(3, "c".to_string());
574
575 map.remove(&2);
576
577 let values: Vec<_> = map.values().collect();
578 assert_eq!(values, vec!["c".to_string(), "a".to_string(),]);
579 })
580 .unwrap();
581 }
582
583 #[test]
584 fn empty_map_behaves_sanely() {
585 dispatch(|| {
586 let mut map = IterableMap::<u64, String>::new(TEST_MAP_PREFIX);
587
588 assert_eq!(map.get(&1), None);
589 assert_eq!(map.remove(&1), None);
590 assert_eq!(map.iter().count(), 0);
591 })
592 .unwrap();
593 }
594
595 #[test]
596 fn separate_maps_do_not_conflict() {
597 dispatch(|| {
598 let mut map1 = IterableMap::<u64, String>::new("map1");
599 let mut map2 = IterableMap::<u64, String>::new("map2");
600
601 map1.insert(1, "a".to_string());
602 map2.insert(1, "b".to_string());
603
604 assert_eq!(map1.get(&1), Some("a".to_string()));
605 assert_eq!(map2.get(&1), Some("b".to_string()));
606 })
607 .unwrap();
608 }
609
610 #[test]
611 fn insert_same_value_under_different_keys() {
612 dispatch(|| {
613 let mut map = IterableMap::<u64, String>::new(TEST_MAP_PREFIX);
614
615 map.insert(1, "shared".to_string());
616 map.insert(2, "shared".to_string());
617
618 assert_eq!(map.get(&1), Some("shared".to_string()));
619 assert_eq!(map.get(&2), Some("shared".to_string()));
620 })
621 .unwrap();
622 }
623
624 #[test]
625 fn clear_removes_all_entries() {
626 dispatch(|| {
627 let mut map = IterableMap::<u64, String>::new(TEST_MAP_PREFIX);
628 map.insert(1, "a".to_string());
629 map.insert(2, "b".to_string());
630 map.clear();
631 assert!(map.is_empty());
632 assert_eq!(map.iter().count(), 0);
633 })
634 .unwrap();
635 }
636
637 #[test]
638 fn keys_returns_reverse_insertion_order() {
639 dispatch(|| {
640 let mut map = IterableMap::<u64, String>::new(TEST_MAP_PREFIX);
641 map.insert(1, "a".to_string());
642 map.insert(2, "b".to_string());
643 let hashes: Vec<_> = map.keys().collect();
644 assert_eq!(hashes, vec![2, 1]);
645 })
646 .unwrap();
647 }
648
649 #[test]
650 fn values_returns_values_in_reverse_insertion_order() {
651 dispatch(|| {
652 let mut map = IterableMap::<u64, String>::new(TEST_MAP_PREFIX);
653 map.insert(1, "a".to_string());
654 map.insert(2, "b".to_string());
655 let values: Vec<_> = map.values().collect();
656 assert_eq!(values, vec!["b".to_string(), "a".to_string()]);
657 })
658 .unwrap();
659 }
660
661 #[test]
662 fn contains_key_returns_correctly() {
663 dispatch(|| {
664 let mut map = IterableMap::<u64, String>::new(TEST_MAP_PREFIX);
665 assert!(!map.contains_key(&1));
666 map.insert(1, "a".to_string());
667 assert!(map.contains_key(&1));
668 map.remove(&1);
669 assert!(!map.contains_key(&1));
670 })
671 .unwrap();
672 }
673
674 #[test]
675 fn multiple_removals_and_insertions() {
676 dispatch(|| {
677 let mut map = IterableMap::<u64, String>::new(TEST_MAP_PREFIX);
678 map.insert(1, "a".to_string());
679 map.insert(2, "b".to_string());
680 map.insert(3, "c".to_string());
681 map.remove(&2);
682 assert_eq!(map.get(&2), None);
683 assert_eq!(map.get(&1), Some("a".to_string()));
684 assert_eq!(map.get(&3), Some("c".to_string()));
685
686 map.insert(4, "d".to_string());
687 let values: Vec<_> = map.values().collect();
688 assert_eq!(values, vec!["d", "c", "a"]);
689 })
690 .unwrap();
691 }
692
693 #[test]
694 fn struct_as_key() {
695 #[derive(BorshSerialize, BorshDeserialize, Debug, Clone, PartialEq, Eq)]
696 struct TestKey {
697 id: u64,
698 name: String,
699 }
700
701 impl IterableMapHash for TestKey {}
702
703 dispatch(|| {
704 let key1 = TestKey {
705 id: 1,
706 name: "Key1".to_string(),
707 };
708 let key2 = TestKey {
709 id: 2,
710 name: "Key2".to_string(),
711 };
712 let mut map = IterableMap::<TestKey, String>::new(TEST_MAP_PREFIX);
713
714 map.insert(key1.clone(), "a".to_string());
715 map.insert(key2.clone(), "b".to_string());
716
717 assert_eq!(map.get(&key1), Some("a".to_string()));
718 assert_eq!(map.get(&key2), Some("b".to_string()));
719 })
720 .unwrap();
721 }
722
723 #[test]
724 fn remove_middle_of_long_chain() {
725 dispatch(|| {
726 let mut map = IterableMap::<u64, String>::new(TEST_MAP_PREFIX);
727 map.insert(1, "a".to_string());
728 map.insert(2, "b".to_string());
729 map.insert(3, "c".to_string());
730 map.insert(4, "d".to_string());
731 map.insert(5, "e".to_string());
732
733 map.remove(&3); let values: Vec<_> = map.values().collect();
737 assert_eq!(values, vec!["e", "d", "b", "a"]);
738
739 let ptr4 = map.create_root_ptr_from_key(&4u64);
741 let prefix = map.create_prefix_from_ptr(&ptr4);
742 let entry = map.get_entry(Keyspace::Context(&prefix)).unwrap();
743 assert_eq!(entry.previous, Some(map.create_root_ptr_from_key(&2u64)));
744 })
745 .unwrap();
746 }
747
748 #[test]
749 fn insert_after_remove_updates_head() {
750 dispatch(|| {
751 let mut map = IterableMap::<u64, String>::new(TEST_MAP_PREFIX);
752 map.insert(1, "a".to_string());
753 map.insert(2, "b".to_string());
754 map.remove(&2);
755 map.insert(3, "c".to_string());
756
757 let values: Vec<_> = map.values().collect();
758 assert_eq!(values, vec!["c", "a"]);
759 })
760 .unwrap();
761 }
762
763 #[test]
764 fn reinsert_removed_key() {
765 dispatch(|| {
766 let mut map = IterableMap::<u64, String>::new(TEST_MAP_PREFIX);
767 map.insert(1, "a".to_string());
768 map.remove(&1);
769 map.insert(1, "b".to_string());
770
771 assert_eq!(map.get(&1), Some("b".to_string()));
772 assert_eq!(map.iter().next().unwrap().1, "b".to_string());
773 })
774 .unwrap();
775 }
776
777 #[test]
778 fn iteration_reflects_modifications() {
779 dispatch(|| {
780 let mut map = IterableMap::<u64, String>::new(TEST_MAP_PREFIX);
781 map.insert(1, "a".to_string());
782 map.insert(2, "b".to_string());
783 let mut iter = map.iter();
784 assert_eq!(iter.next().unwrap().1, "b".to_string());
785
786 map.remove(&2);
787 map.insert(3, "c".to_string());
788 let values: Vec<_> = map.values().collect();
789 assert_eq!(values, vec!["c", "a"]);
790 })
791 .unwrap();
792 }
793
794 #[test]
795 fn unit_struct_as_key() {
796 #[derive(BorshSerialize, BorshDeserialize, PartialEq)]
797 struct UnitKey;
798
799 impl IterableMapHash for UnitKey {}
800
801 dispatch(|| {
802 let mut map = IterableMap::<UnitKey, String>::new(TEST_MAP_PREFIX);
803 map.insert(UnitKey, "value".to_string());
804 assert_eq!(map.get(&UnitKey), Some("value".to_string()));
805 })
806 .unwrap();
807 }
808
809 #[derive(Debug, Clone, PartialEq, Eq, BorshSerialize, BorshDeserialize)]
810 struct CollidingKey(u64, u64);
811
812 impl IterableMapHash for CollidingKey {
813 fn compute_hash(&self) -> u64 {
814 let mut bytes = Vec::new();
815 self.0.serialize(&mut bytes).unwrap();
817 fnv1a_hash_64(&bytes, None)
818 }
819 }
820
821 #[test]
822 fn basic_collision_handling() {
823 dispatch(|| {
824 let mut map = IterableMap::<CollidingKey, String>::new(TEST_MAP_PREFIX);
825
826 let k1 = CollidingKey(42, 1);
828 let k2 = CollidingKey(42, 2);
829
830 map.insert(k1.clone(), "first".to_string());
831 map.insert(k2.clone(), "second".to_string());
832
833 assert_eq!(map.get(&k1), Some("first".to_string()));
834 assert_eq!(map.get(&k2), Some("second".to_string()));
835 })
836 .unwrap();
837 }
838
839 #[test]
840 fn tombstone_handling() {
841 dispatch(|| {
842 let mut map = IterableMap::<CollidingKey, String>::new(TEST_MAP_PREFIX);
843
844 let k1 = CollidingKey(42, 1);
845 let k2 = CollidingKey(42, 2);
846 let k3 = CollidingKey(42, 3);
847
848 map.insert(k1.clone(), "first".to_string());
849 map.insert(k2.clone(), "second".to_string());
850 map.insert(k3.clone(), "third".to_string());
851
852 assert_eq!(map.remove(&k2), Some("second".to_string()));
854
855 let (_, entry) = map.get_writable_slot(&k2);
857 assert!(entry.unwrap().value.is_none());
858
859 let values: Vec<_> = map.values().collect();
861 assert_eq!(values, vec!["third", "first"]);
862 })
863 .unwrap();
864 }
865
866 #[test]
867 fn tombstone_reuse() {
868 dispatch(|| {
869 let mut map = IterableMap::<CollidingKey, String>::new(TEST_MAP_PREFIX);
870
871 let k1 = CollidingKey(42, 1);
872 let k2 = CollidingKey(42, 2);
873
874 map.insert(k1.clone(), "first".to_string());
875 map.insert(k2.clone(), "second".to_string());
876
877 map.remove(&k1);
880
881 map.insert(k1.clone(), "reused".to_string());
883
884 assert_eq!(map.get(&k1), Some("reused".to_string()));
885 assert_eq!(map.get(&k2), Some("second".to_string()));
886 })
887 .unwrap();
888 }
889
890 #[test]
891 fn full_deletion_handling() {
892 dispatch(|| {
893 let mut map = IterableMap::<CollidingKey, String>::new(TEST_MAP_PREFIX);
894
895 let k1 = CollidingKey(42, 1);
896 map.insert(k1.clone(), "lonely".to_string());
897
898 assert_eq!(map.remove(&k1), Some("lonely".to_string()));
899
900 let (_, entry) = map.get_writable_slot(&k1);
902 assert!(entry.is_none());
903 })
904 .unwrap();
905 }
906
907 #[test]
908 fn collision_chain_iteration() {
909 dispatch(|| {
910 let mut map = IterableMap::<CollidingKey, String>::new(TEST_MAP_PREFIX);
911
912 let keys = [
913 CollidingKey(42, 1),
914 CollidingKey(42, 2),
915 CollidingKey(42, 3),
916 ];
917
918 for (i, k) in keys.iter().enumerate() {
919 map.insert(k.clone(), format!("value-{}", i));
920 }
921
922 map.remove(&keys[1]);
924
925 let values: Vec<_> = map.values().collect();
926 assert_eq!(values, vec!["value-2", "value-0"]);
927 })
928 .unwrap();
929 }
930
931 #[test]
932 fn complex_collision_chain() {
933 dispatch(|| {
934 let mut map = IterableMap::<CollidingKey, String>::new(TEST_MAP_PREFIX);
935
936 let keys: Vec<_> = (0..5).map(|i| CollidingKey(42, i)).collect();
938
939 for k in &keys {
941 map.insert(k.clone(), format!("{}", k.1));
942 }
943
944 for k in keys.iter().step_by(2) {
946 map.remove(k);
947 }
948
949 map.insert(keys[0].clone(), "reinserted".to_string());
951 map.insert(CollidingKey(42, 5), "new".to_string());
952
953 let expected = vec![
955 ("new".to_string(), 5),
956 ("reinserted".to_string(), 0),
957 ("3".to_string(), 3),
958 ("1".to_string(), 1),
959 ];
960
961 let results: Vec<_> = map.iter().map(|(k, v)| (v, k.1)).collect();
962
963 assert_eq!(results, expected);
964 })
965 .unwrap();
966 }
967
968 #[test]
969 fn cross_bucket_reference() {
970 dispatch(|| {
971 let mut map = IterableMap::<CollidingKey, String>::new(TEST_MAP_PREFIX);
972
973 let k1 = CollidingKey(1, 0);
975 let k2 = CollidingKey(2, 0);
976 let k3 = CollidingKey(1, 1); map.insert(k1.clone(), "first".to_string());
979 map.insert(k2.clone(), "second".to_string());
980 map.insert(k3.clone(), "third".to_string());
981
982 map.remove(&k2);
984
985 let values: Vec<_> = map.values().collect();
987 assert_eq!(values, vec!["third", "first"]);
988 })
989 .unwrap();
990 }
991}