1#![no_std]
11#![deny(missing_docs, unreachable_patterns)]
12
13extern crate fakealloc as alloc;
14
15pub mod collection;
16#[cfg(test)]
17mod testutil;
18
19use alloc::vec::Vec;
20use core::fmt::Debug;
21
22pub type Key = usize;
24
25#[derive(PartialEq, Eq, Debug)]
27#[cfg_attr(test, derive(Clone))]
28enum DenseMapEntry<T> {
29 Allocated(AllocatedEntry<T>),
31 Free(ListLink),
33}
34
35#[derive(PartialEq, Eq, Debug)]
36#[cfg_attr(test, derive(Clone))]
37struct AllocatedEntry<T> {
38 link: ListLink,
39 item: T,
40}
41
42#[derive(PartialEq, Eq, Debug, Clone, Copy)]
44struct ListLink {
45 prev: Option<usize>,
47 next: Option<usize>,
49}
50
51impl Default for ListLink {
52 fn default() -> Self {
54 Self { prev: None, next: None }
55 }
56}
57
58#[derive(PartialEq, Eq, Debug, Clone, Copy)]
61struct List {
62 head: usize,
64 tail: usize,
66}
67
68impl List {
69 fn singleton(elem: usize) -> List {
71 List { head: elem, tail: elem }
72 }
73}
74
75#[derive(Copy, Clone, Debug, Eq, PartialEq)]
76enum DenseMapEntryKind {
77 Allocated,
78 Free,
79}
80
81impl<T> DenseMapEntry<T> {
82 fn link(&self) -> (&ListLink, DenseMapEntryKind) {
83 match self {
84 DenseMapEntry::Allocated(entry) => (&entry.link, DenseMapEntryKind::Allocated),
85 DenseMapEntry::Free(link) => (&link, DenseMapEntryKind::Free),
86 }
87 }
88
89 fn link_mut_and_check(&mut self, expected_kind: DenseMapEntryKind) -> &mut ListLink {
90 let (link, got_kind) = match self {
91 DenseMapEntry::Allocated(entry) => (&mut entry.link, DenseMapEntryKind::Allocated),
92 DenseMapEntry::Free(link) => (link, DenseMapEntryKind::Free),
93 };
94 assert_eq!(expected_kind, got_kind);
95 link
96 }
97
98 fn as_free_or_none(&self) -> Option<&ListLink> {
100 match self {
101 DenseMapEntry::Free(link) => Some(link),
102 DenseMapEntry::Allocated(_) => None,
103 }
104 }
105
106 fn as_free_or_none_mut(&mut self) -> Option<&mut ListLink> {
108 match self {
109 DenseMapEntry::Free(link) => Some(link),
110 DenseMapEntry::Allocated(_) => None,
111 }
112 }
113}
114
115#[derive(Debug)]
131#[cfg_attr(test, derive(Clone))]
132pub struct DenseMap<T> {
133 freelist: Option<List>,
134 allocatedlist: Option<List>,
135 data: Vec<DenseMapEntry<T>>,
136}
137
138impl<T> DenseMap<T> {
139 pub fn new() -> Self {
141 Self { freelist: None, allocatedlist: None, data: Vec::new() }
142 }
143
144 pub fn is_empty(&self) -> bool {
146 self.data.is_empty()
152 }
153
154 pub fn get(&self, key: Key) -> Option<&T> {
157 self.data.get(key).and_then(|v| match v {
158 DenseMapEntry::Allocated(AllocatedEntry { link: _, item }) => Some(item),
159 DenseMapEntry::Free(_) => None,
160 })
161 }
162
163 pub fn get_mut(&mut self, key: Key) -> Option<&mut T> {
166 self.data.get_mut(key).and_then(|v| match v {
167 DenseMapEntry::Allocated(AllocatedEntry { link: _, item }) => Some(item),
168 DenseMapEntry::Free(_) => None,
169 })
170 }
171
172 pub fn remove(&mut self, key: Key) -> Option<T> {
179 let r = self.remove_inner(key);
180 if r.is_some() {
181 self.compress();
182 }
183 r
184 }
185
186 fn remove_inner(&mut self, key: Key) -> Option<T> {
187 let r = self.data.get_mut(key).and_then(|v| {
188 match v {
189 DenseMapEntry::Allocated(_) => {
190 let old_head = self.freelist.map(|l| l.head);
191 let new_link = DenseMapEntry::Free(ListLink { prev: None, next: old_head });
192 match core::mem::replace(v, new_link) {
193 DenseMapEntry::Allocated(entry) => Some(entry),
194 DenseMapEntry::Free(_) => unreachable!("already matched"),
195 }
196 }
197 DenseMapEntry::Free(_) => None,
200 }
201 });
202 r.map(|AllocatedEntry { link, item }| {
203 self.unlink_entry_inner(DenseMapEntryKind::Allocated, link);
204 match self.freelist.as_mut() {
207 Some(List { head, .. }) => {
208 self.data[*head]
209 .as_free_or_none_mut()
210 .unwrap_or_else(|| panic!("freelist head node {} is not free", head))
211 .prev = Some(key);
212 *head = key;
213 }
214 None => self.freelist = Some(List::singleton(key)),
215 }
216
217 item
218 })
219 }
220
221 fn allocated_link(
222 allocatedlist: &mut Option<List>,
223 data: &mut [DenseMapEntry<T>],
224 key: Key,
225 ) -> ListLink {
226 if let Some(List { head: _, tail }) = allocatedlist {
236 match data[*tail] {
237 DenseMapEntry::Allocated(ref mut entry) => {
238 assert_eq!(None, core::mem::replace(&mut entry.link.next, Some(key)));
239 ListLink { next: None, prev: Some(core::mem::replace(tail, key)) }
240 }
241 DenseMapEntry::Free(_) => unreachable!(
242 "allocated list tail entry is free; key = {}; tail = {}",
243 key, tail,
244 ),
245 }
246 } else {
247 *allocatedlist = Some(List { head: key, tail: key });
248
249 ListLink { next: None, prev: None }
250 }
251 }
252
253 pub fn insert(&mut self, key: Key, item: T) -> Option<T> {
261 if key < self.data.len() {
262 self.unlink_entry(key);
264 let link = Self::allocated_link(&mut self.allocatedlist, &mut self.data, key);
266
267 let prev = core::mem::replace(
268 &mut self.data[key],
269 DenseMapEntry::Allocated(AllocatedEntry { link, item }),
270 );
271 match prev {
274 DenseMapEntry::Free(ListLink { .. }) => None,
275 DenseMapEntry::Allocated(AllocatedEntry { link: ListLink { .. }, item }) => {
276 Some(item)
277 }
278 }
279 } else {
280 let start_len = self.data.len();
281 for idx in start_len..key {
290 self.data.push(DenseMapEntry::Free(ListLink {
294 prev: if idx == start_len {
295 self.freelist.map(|l| l.tail)
296 } else {
297 Some(idx - 1)
298 },
299 next: if idx == key - 1 { None } else { Some(idx + 1) },
300 }));
301 }
302 if key > start_len {
305 let new_tail = key - 1;
306 match self.freelist.as_mut() {
307 Some(List { tail, .. }) => {
308 self.data[*tail]
309 .as_free_or_none_mut()
310 .unwrap_or_else(|| panic!("freelist tail node {} is not free", tail))
311 .next = Some(start_len);
312 *tail = new_tail;
313 }
314 None => {
315 self.freelist = Some(List { head: start_len, tail: new_tail });
316 }
317 }
318 }
319 let link = Self::allocated_link(&mut self.allocatedlist, &mut self.data, key);
321 self.data.push(DenseMapEntry::Allocated(AllocatedEntry { link, item }));
322 None
323 }
324 }
325
326 pub fn push(&mut self, item: T) -> Key {
337 *self.push_entry(item).key()
338 }
339
340 pub fn push_entry(&mut self, item: T) -> OccupiedEntry<'_, usize, T> {
346 self.push_with(|_: usize| item)
347 }
348
349 pub fn push_with(&mut self, make_item: impl FnOnce(Key) -> T) -> OccupiedEntry<'_, usize, T> {
354 let Self { freelist, allocatedlist, data } = self;
355 if let Some(List { head, .. }) = freelist.as_mut() {
356 let ret = *head;
357 let link = Self::allocated_link(allocatedlist, data, ret);
358 let old = core::mem::replace(
359 data.get_mut(ret).unwrap(),
360 DenseMapEntry::Allocated(AllocatedEntry { link, item: make_item(ret) }),
361 );
362 let old_link = old
363 .as_free_or_none()
364 .unwrap_or_else(|| panic!("freelist head node {} is not free", head));
365 match old_link.next {
367 Some(new_head) => {
368 *head = new_head;
369 data[new_head]
370 .as_free_or_none_mut()
371 .unwrap_or_else(|| panic!("new free list head {} is not free", new_head))
372 .prev = None;
373 }
374 None => *freelist = None,
375 }
376 OccupiedEntry { key: ret, id_map: self }
377 } else {
378 let key = data.len();
381 let link = Self::allocated_link(allocatedlist, data, key);
382 data.push(DenseMapEntry::Allocated(AllocatedEntry { link, item: make_item(key) }));
383 OccupiedEntry { key, id_map: self }
384 }
385 }
386
387 fn compress(&mut self) {
392 if let Some(idx) = self.data.iter().enumerate().rev().find_map(|(k, v)| match v {
394 DenseMapEntry::Allocated(_) => Some(k),
395 DenseMapEntry::Free(_) => None,
396 }) {
397 for i in idx + 1..self.data.len() {
399 let link = *self.data[i].as_free_or_none().expect("already confirmed as free");
400 self.unlink_entry_inner(DenseMapEntryKind::Free, link);
401 }
402 self.data.truncate(idx + 1);
403 } else {
404 self.data.clear();
406 self.freelist = None;
407 }
408 }
409
410 pub fn insertion_ordered_iter(&self) -> InsertionOrderedIter<'_, T> {
414 let Self { data, freelist: _, allocatedlist } = self;
415 let next_idx = allocatedlist.map(|l| l.head);
416 InsertionOrderedIter { next_idx, map: data.as_ref() }
417 }
418
419 pub fn key_ordered_iter(&self) -> KeyOrderedIter<'_, T> {
423 IntoIterator::into_iter(self)
424 }
425
426 pub fn key_ordered_iter_mut(&mut self) -> KeyOrderedIterMut<'_, T> {
431 IntoIterator::into_iter(self)
432 }
433
434 pub fn key_ordered_into_iter(self) -> IntoKeyOrderedIter<T> {
439 IntoIterator::into_iter(self)
440 }
441
442 pub fn entry(&mut self, key: usize) -> Entry<'_, usize, T> {
445 if let Some(DenseMapEntry::Allocated(_)) = self.data.get(key) {
446 Entry::Occupied(OccupiedEntry { key, id_map: self })
447 } else {
448 Entry::Vacant(VacantEntry { key, id_map: self })
449 }
450 }
451
452 pub fn key_ordered_retain<F: FnMut(&T) -> bool>(&mut self, mut should_retain: F) {
457 (0..self.data.len()).for_each(|k| {
458 if let DenseMapEntry::Allocated(AllocatedEntry { link: _, item }) =
459 self.data.get_mut(k).unwrap()
460 {
461 if !should_retain(item) {
462 let _: T = self.remove_inner(k).unwrap();
477 }
478 }
479 });
480
481 self.compress();
482 }
483
484 fn unlink_entry_inner(&mut self, kind: DenseMapEntryKind, link: ListLink) {
485 let ListLink { next, prev } = link;
486
487 let list = match kind {
488 DenseMapEntryKind::Allocated => &mut self.allocatedlist,
489 DenseMapEntryKind::Free => &mut self.freelist,
490 };
491
492 match (prev, next) {
493 (Some(prev), Some(next)) => {
494 self.data[prev].link_mut_and_check(kind).next = Some(next);
496 self.data[next].link_mut_and_check(kind).prev = Some(prev);
497 }
498 (Some(prev), None) => {
499 self.data[prev].link_mut_and_check(kind).next = next;
501 list.as_mut().unwrap().tail = prev;
502 }
503 (None, Some(next)) => {
504 self.data[next].link_mut_and_check(kind).prev = prev;
506 list.as_mut().unwrap().head = next;
507 }
508 (None, None) => {
509 *list = None;
511 }
512 }
513 }
514
515 fn unlink_entry(&mut self, i: Key) {
516 let (link, kind) = self.data[i].link();
517 self.unlink_entry_inner(kind, *link);
518 }
519}
520
521impl<T> Default for DenseMap<T> {
522 fn default() -> Self {
523 Self::new()
524 }
525}
526
527pub struct InsertionOrderedIter<'s, T> {
531 next_idx: Option<usize>,
532 map: &'s [DenseMapEntry<T>],
533}
534
535impl<'a, T> Iterator for InsertionOrderedIter<'a, T> {
536 type Item = (Key, &'a T);
537
538 fn next(&mut self) -> Option<Self::Item> {
539 let Self { next_idx, map } = self;
540 let k = (*next_idx)?;
541 match &map[k] {
542 DenseMapEntry::Allocated(AllocatedEntry { link: ListLink { next, prev: _ }, item }) => {
543 *next_idx = *next;
544 Some((k, item))
545 }
546 DenseMapEntry::Free(_) => {
547 unreachable!("free entry found in allocated list @ idx={}", k)
548 }
549 }
550 }
551}
552
553pub struct IntoKeyOrderedIter<T>(core::iter::Enumerate<alloc::vec::IntoIter<DenseMapEntry<T>>>);
557
558impl<T> Iterator for IntoKeyOrderedIter<T> {
559 type Item = (Key, T);
560 fn next(&mut self) -> Option<Self::Item> {
561 let Self(it) = self;
562 it.filter_map(|(k, v)| match v {
563 DenseMapEntry::Allocated(AllocatedEntry { link: _, item }) => Some((k, item)),
564 DenseMapEntry::Free(_) => None,
565 })
566 .next()
567 }
568}
569
570impl<T> IntoIterator for DenseMap<T> {
571 type Item = (Key, T);
572 type IntoIter = IntoKeyOrderedIter<T>;
573
574 fn into_iter(self) -> Self::IntoIter {
575 IntoKeyOrderedIter(self.data.into_iter().enumerate())
576 }
577}
578
579pub struct KeyOrderedIter<'s, T>(core::iter::Enumerate<core::slice::Iter<'s, DenseMapEntry<T>>>);
583
584impl<'a, T> Iterator for KeyOrderedIter<'a, T> {
585 type Item = (Key, &'a T);
586
587 fn next(&mut self) -> Option<Self::Item> {
588 let Self(it) = self;
589 it.filter_map(|(k, v)| match v {
590 DenseMapEntry::Allocated(AllocatedEntry { link: _, item }) => Some((k, item)),
591 DenseMapEntry::Free(_) => None,
592 })
593 .next()
594 }
595}
596
597impl<'a, T> IntoIterator for &'a DenseMap<T> {
598 type Item = (Key, &'a T);
599 type IntoIter = KeyOrderedIter<'a, T>;
600
601 fn into_iter(self) -> Self::IntoIter {
602 KeyOrderedIter(self.data.iter().enumerate())
603 }
604}
605
606pub struct KeyOrderedIterMut<'s, T>(
610 core::iter::Enumerate<core::slice::IterMut<'s, DenseMapEntry<T>>>,
611);
612
613impl<'a, T> Iterator for KeyOrderedIterMut<'a, T> {
614 type Item = (Key, &'a mut T);
615
616 fn next(&mut self) -> Option<Self::Item> {
617 let Self(it) = self;
618 it.filter_map(|(k, v)| match v {
619 DenseMapEntry::Allocated(AllocatedEntry { link: _, item }) => Some((k, item)),
620 DenseMapEntry::Free(_) => None,
621 })
622 .next()
623 }
624}
625
626impl<'a, T> IntoIterator for &'a mut DenseMap<T> {
627 type Item = (Key, &'a mut T);
628 type IntoIter = KeyOrderedIterMut<'a, T>;
629
630 fn into_iter(self) -> Self::IntoIter {
631 KeyOrderedIterMut(self.data.iter_mut().enumerate())
632 }
633}
634
635pub trait EntryKey {
637 fn get_key_index(&self) -> usize;
639}
640
641impl EntryKey for usize {
642 fn get_key_index(&self) -> usize {
643 *self
644 }
645}
646
647pub struct VacantEntry<'a, K, T> {
649 key: K,
650 id_map: &'a mut DenseMap<T>,
651}
652
653impl<'a, K, T> VacantEntry<'a, K, T> {
654 pub fn insert(self, value: T) -> &'a mut T
657 where
658 K: EntryKey,
659 {
660 assert!(self.id_map.insert(self.key.get_key_index(), value).is_none());
661 match &mut self.id_map.data[self.key.get_key_index()] {
662 DenseMapEntry::Allocated(AllocatedEntry { link: _, item }) => item,
663 DenseMapEntry::Free(_) => unreachable!("entry is known to be vacant"),
664 }
665 }
666
667 pub fn key(&self) -> &K {
670 &self.key
671 }
672
673 pub fn into_key(self) -> K {
675 self.key
676 }
677
678 pub(crate) fn map_key<X, F>(self, f: F) -> VacantEntry<'a, X, T>
686 where
687 K: EntryKey,
688 X: EntryKey,
689 F: FnOnce(K) -> X,
690 {
691 let idx = self.key.get_key_index();
692 let key = f(self.key);
693 assert_eq!(idx, key.get_key_index());
694 VacantEntry { key, id_map: self.id_map }
695 }
696}
697
698pub struct OccupiedEntry<'a, K, T> {
700 key: K,
701 id_map: &'a mut DenseMap<T>,
702}
703
704impl<'a, K: EntryKey, T> OccupiedEntry<'a, K, T> {
705 pub fn key(&self) -> &K {
707 &self.key
708 }
709
710 pub fn into_key(self) -> K {
712 self.key
713 }
714
715 pub fn get(&self) -> &T {
717 self.id_map.get(self.key.get_key_index()).unwrap()
719 }
720
721 pub fn get_mut(&mut self) -> &mut T {
726 self.id_map.get_mut(self.key.get_key_index()).unwrap()
728 }
729
730 pub fn into_mut(self) -> &'a mut T {
736 self.id_map.get_mut(self.key.get_key_index()).unwrap()
738 }
739
740 pub fn insert(&mut self, value: T) -> T {
742 self.id_map.insert(self.key.get_key_index(), value).unwrap()
744 }
745
746 pub fn remove(self) -> T {
748 self.id_map.remove(self.key.get_key_index()).unwrap()
750 }
751
752 pub(crate) fn map_key<X, F>(self, f: F) -> OccupiedEntry<'a, X, T>
760 where
761 K: EntryKey,
762 X: EntryKey,
763 F: FnOnce(K) -> X,
764 {
765 let idx = self.key.get_key_index();
766 let key = f(self.key);
767 assert_eq!(idx, key.get_key_index());
768 OccupiedEntry { key, id_map: self.id_map }
769 }
770}
771
772impl<'a, K: Debug, T> Debug for OccupiedEntry<'a, K, T> {
773 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
774 let Self { key, id_map: _ } = self;
775 f.debug_struct("OccupiedEntry").field("key", key).field("id_map", &"_").finish()
776 }
777}
778
779pub enum Entry<'a, K, T> {
781 Vacant(VacantEntry<'a, K, T>),
783 Occupied(OccupiedEntry<'a, K, T>),
785}
786
787impl<'a, K: EntryKey, T> Entry<'a, K, T> {
788 pub fn key(&self) -> &K {
790 match self {
791 Entry::Vacant(e) => e.key(),
792 Entry::Occupied(e) => e.key(),
793 }
794 }
795
796 pub fn or_insert(self, default: T) -> &'a mut T
799 where
800 K: EntryKey,
801 {
802 match self {
803 Entry::Vacant(e) => e.insert(default),
804 Entry::Occupied(e) => e.into_mut(),
805 }
806 }
807
808 pub fn or_insert_with<F: FnOnce() -> T>(self, f: F) -> &'a mut T
811 where
812 K: EntryKey,
813 {
814 match self {
815 Entry::Vacant(e) => e.insert(f()),
816 Entry::Occupied(e) => e.into_mut(),
817 }
818 }
819
820 pub fn or_default(self) -> &'a mut T
823 where
824 T: Default,
825 K: EntryKey,
826 {
827 self.or_insert_with(<T as Default>::default)
828 }
829
830 pub fn and_modify<F: FnOnce(&mut T)>(self, f: F) -> Self {
833 match self {
834 Entry::Vacant(e) => Entry::Vacant(e),
835 Entry::Occupied(mut e) => {
836 f(e.get_mut());
837 Entry::Occupied(e)
838 }
839 }
840 }
841
842 pub fn remove(self) -> Option<T> {
844 match self {
845 Entry::Vacant(_) => None,
846 Entry::Occupied(e) => Some(e.remove()),
847 }
848 }
849}
850
851#[cfg(test)]
852mod tests {
853 use alloc::collections::HashMap;
854 use alloc::vec;
855
856 use rand::seq::SliceRandom as _;
857
858 use crate::testutil::assert_empty;
859 use crate::DenseMapEntry::{Allocated, Free};
860 use crate::*;
861
862 fn free<T>(prev: usize, next: usize) -> DenseMapEntry<T> {
864 Free(ListLink { prev: Some(prev), next: Some(next) })
865 }
866
867 fn free_head<T>(next: usize) -> DenseMapEntry<T> {
868 Free(ListLink { prev: None, next: Some(next) })
869 }
870
871 fn free_tail<T>(prev: usize) -> DenseMapEntry<T> {
872 Free(ListLink { prev: Some(prev), next: None })
873 }
874
875 fn free_none<T>() -> DenseMapEntry<T> {
876 Free(ListLink::default())
877 }
878
879 #[test]
880 fn test_push() {
881 let mut map = DenseMap::new();
882 assert_eq!(map.insert(1, 2), None);
883 let DenseMap { data, freelist, allocatedlist } = ↦
884 assert_eq!(
885 data,
886 &vec![
887 free_none(),
888 Allocated(AllocatedEntry { link: ListLink { prev: None, next: None }, item: 2 })
889 ]
890 );
891 assert_eq!(freelist, &Some(List::singleton(0)));
892 assert_eq!(allocatedlist, &Some(List { head: 1, tail: 1 }));
893 assert_eq!(map.push(1), 0);
894 let DenseMap { data, freelist, allocatedlist } = ↦
895 assert_eq!(
896 data,
897 &vec![
898 Allocated(AllocatedEntry { link: ListLink { prev: Some(1), next: None }, item: 1 }),
899 Allocated(AllocatedEntry { link: ListLink { prev: None, next: Some(0) }, item: 2 })
900 ]
901 );
902 assert_eq!(freelist, &None);
903 assert_eq!(allocatedlist, &Some(List { head: 1, tail: 0 }));
904 assert_eq!(map.push(3), 2);
905 let DenseMap { data, freelist, allocatedlist } = ↦
906 assert_eq!(
907 data,
908 &vec![
909 Allocated(AllocatedEntry {
910 link: ListLink { prev: Some(1), next: Some(2) },
911 item: 1
912 }),
913 Allocated(AllocatedEntry { link: ListLink { prev: None, next: Some(0) }, item: 2 }),
914 Allocated(AllocatedEntry { link: ListLink { prev: Some(0), next: None }, item: 3 })
915 ]
916 );
917 assert_eq!(freelist, &None);
918 assert_eq!(allocatedlist, &Some(List { head: 1, tail: 2 }));
919 }
920
921 #[test]
922 fn test_get() {
923 let mut map = DenseMap::new();
924 assert_eq!(map.push(1), 0);
925 assert_eq!(map.insert(2, 3), None);
926 let DenseMap { data, freelist, allocatedlist } = ↦
927 assert_eq!(
928 data,
929 &vec![
930 Allocated(AllocatedEntry { link: ListLink { prev: None, next: Some(2) }, item: 1 }),
931 free_none(),
932 Allocated(AllocatedEntry { link: ListLink { prev: Some(0), next: None }, item: 3 })
933 ]
934 );
935 assert_eq!(freelist, &Some(List::singleton(1)));
936 assert_eq!(allocatedlist, &Some(List { head: 0, tail: 2 }));
937 assert_eq!(*map.get(0).unwrap(), 1);
938 assert_eq!(map.get(1), None);
939 assert_eq!(*map.get(2).unwrap(), 3);
940 assert_eq!(map.get(3), None);
941 }
942
943 #[test]
944 fn test_get_mut() {
945 let mut map = DenseMap::new();
946 assert_eq!(map.push(1), 0);
947 assert_eq!(map.insert(2, 3), None);
948 let DenseMap { data, freelist, allocatedlist } = ↦
949 assert_eq!(
950 data,
951 &vec![
952 Allocated(AllocatedEntry { link: ListLink { prev: None, next: Some(2) }, item: 1 }),
953 free_none(),
954 Allocated(AllocatedEntry { link: ListLink { prev: Some(0), next: None }, item: 3 })
955 ]
956 );
957 assert_eq!(freelist, &Some(List::singleton(1)));
958 assert_eq!(allocatedlist, &Some(List { head: 0, tail: 2 }));
959 *map.get_mut(2).unwrap() = 10;
960 assert_eq!(*map.get(0).unwrap(), 1);
961 assert_eq!(*map.get(2).unwrap(), 10);
962
963 assert_eq!(map.get_mut(1), None);
964 assert_eq!(map.get_mut(3), None);
965 }
966
967 #[test]
968 fn test_is_empty() {
969 let mut map = DenseMap::<i32>::new();
970 assert!(map.is_empty());
971 assert_eq!(map.push(1), 0);
972 assert!(!map.is_empty());
973 }
974
975 #[test]
976 fn test_remove() {
977 let mut map = DenseMap::new();
978 assert_eq!(map.push(1), 0);
979 assert_eq!(map.push(2), 1);
980 assert_eq!(map.push(3), 2);
981 let DenseMap { data, freelist, allocatedlist } = ↦
982 assert_eq!(
983 data,
984 &vec![
985 Allocated(AllocatedEntry { link: ListLink { prev: None, next: Some(1) }, item: 1 }),
986 Allocated(AllocatedEntry {
987 link: ListLink { prev: Some(0), next: Some(2) },
988 item: 2
989 }),
990 Allocated(AllocatedEntry { link: ListLink { prev: Some(1), next: None }, item: 3 })
991 ]
992 );
993 assert_eq!(freelist, &None);
994 assert_eq!(allocatedlist, &Some(List { head: 0, tail: 2 }));
995 assert_eq!(map.remove(1).unwrap(), 2);
996
997 assert_eq!(map.remove(1), None);
998 let DenseMap { data, freelist, allocatedlist } = ↦
999 assert_eq!(
1000 data,
1001 &vec![
1002 Allocated(AllocatedEntry { link: ListLink { prev: None, next: Some(2) }, item: 1 }),
1003 free_none(),
1004 Allocated(AllocatedEntry { link: ListLink { prev: Some(0), next: None }, item: 3 })
1005 ]
1006 );
1007 assert_eq!(freelist, &Some(List::singleton(1)));
1008 assert_eq!(allocatedlist, &Some(List { head: 0, tail: 2 }));
1009 }
1010
1011 #[test]
1012 fn test_remove_compress() {
1013 let mut map = DenseMap::new();
1014 assert_eq!(map.insert(0, 1), None);
1015 assert_eq!(map.insert(2, 3), None);
1016 let DenseMap { data, freelist, allocatedlist } = ↦
1017 assert_eq!(
1018 data,
1019 &vec![
1020 Allocated(AllocatedEntry { link: ListLink { prev: None, next: Some(2) }, item: 1 }),
1021 free_none(),
1022 Allocated(AllocatedEntry { link: ListLink { prev: Some(0), next: None }, item: 3 })
1023 ]
1024 );
1025 assert_eq!(freelist, &Some(List::singleton(1)));
1026 assert_eq!(allocatedlist, &Some(List { head: 0, tail: 2 }));
1027 assert_eq!(map.remove(2).unwrap(), 3);
1028 let DenseMap { data, freelist, allocatedlist } = ↦
1029 assert_eq!(
1030 data,
1031 &vec![Allocated(AllocatedEntry { link: ListLink { prev: None, next: None }, item: 1 })]
1032 );
1033 assert_eq!(freelist, &None);
1034 assert_eq!(allocatedlist, &Some(List { head: 0, tail: 0 }));
1035 assert_eq!(map.remove(0).unwrap(), 1);
1036 let DenseMap { data, freelist, allocatedlist } = ↦
1037 assert_empty(data);
1038 assert_eq!(freelist, &None);
1039 assert_eq!(allocatedlist, &None);
1040 }
1041
1042 #[test]
1043 fn test_insert() {
1044 let mut map = DenseMap::new();
1045 assert_eq!(map.insert(1, 2), None);
1046 let DenseMap { data, freelist, allocatedlist } = ↦
1047 assert_eq!(
1048 data,
1049 &vec![
1050 free_none(),
1051 Allocated(AllocatedEntry { link: ListLink { prev: None, next: None }, item: 2 })
1052 ]
1053 );
1054 assert_eq!(freelist, &Some(List::singleton(0)));
1055 assert_eq!(allocatedlist, &Some(List { head: 1, tail: 1 }));
1056 assert_eq!(map.insert(3, 4), None);
1057 let DenseMap { data, freelist, allocatedlist } = ↦
1058 assert_eq!(
1059 data,
1060 &vec![
1061 free_head(2),
1062 Allocated(AllocatedEntry { link: ListLink { prev: None, next: Some(3) }, item: 2 }),
1063 free_tail(0),
1064 Allocated(AllocatedEntry { link: ListLink { prev: Some(1), next: None }, item: 4 })
1065 ]
1066 );
1067 assert_eq!(freelist, &Some(List { head: 0, tail: 2 }));
1068 assert_eq!(allocatedlist, &Some(List { head: 1, tail: 3 }));
1069 assert_eq!(map.insert(0, 1), None);
1070 let DenseMap { data, freelist, allocatedlist } = ↦
1071 assert_eq!(
1072 data,
1073 &vec![
1074 Allocated(AllocatedEntry { link: ListLink { prev: Some(3), next: None }, item: 1 }),
1075 Allocated(AllocatedEntry { link: ListLink { prev: None, next: Some(3) }, item: 2 }),
1076 free_none(),
1077 Allocated(AllocatedEntry {
1078 link: ListLink { prev: Some(1), next: Some(0) },
1079 item: 4
1080 })
1081 ]
1082 );
1083 assert_eq!(freelist, &Some(List::singleton(2)));
1084 assert_eq!(allocatedlist, &Some(List { head: 1, tail: 0 }));
1085 assert_eq!(map.insert(3, 5).unwrap(), 4);
1086 let DenseMap { data, freelist, allocatedlist } = ↦
1087 assert_eq!(
1088 data,
1089 &vec![
1090 Allocated(AllocatedEntry {
1091 link: ListLink { prev: Some(1), next: Some(3) },
1092 item: 1
1093 }),
1094 Allocated(AllocatedEntry { link: ListLink { prev: None, next: Some(0) }, item: 2 }),
1095 free_none(),
1096 Allocated(AllocatedEntry { link: ListLink { prev: Some(0), next: None }, item: 5 })
1097 ]
1098 );
1099 assert_eq!(freelist, &Some(List::singleton(2)));
1100 assert_eq!(allocatedlist, &Some(List { head: 1, tail: 3 }));
1101 }
1102
1103 #[test]
1104 fn test_insert_gap() {
1105 let mut map = DenseMap::new();
1109 assert_eq!(map.insert(0, 0), None);
1110 assert_eq!(map.insert(3, 5), None);
1111 let DenseMap { data, freelist, allocatedlist } = ↦
1112 assert_eq!(
1113 data,
1114 &vec![
1115 Allocated(AllocatedEntry { link: ListLink { prev: None, next: Some(3) }, item: 0 }),
1116 free_head(2),
1117 free_tail(1),
1118 Allocated(AllocatedEntry { link: ListLink { prev: Some(0), next: None }, item: 5 })
1119 ]
1120 );
1121 assert_eq!(freelist, &Some(List { head: 1, tail: 2 }));
1122 assert_eq!(allocatedlist, &Some(List { head: 0, tail: 3 }));
1123
1124 assert_eq!(map.push(6), 1);
1125 assert_eq!(map.remove(1), Some(6));
1126 assert_eq!(map.remove(3), Some(5));
1127
1128 let DenseMap { data, freelist, allocatedlist } = ↦
1130 assert_eq!(
1131 data,
1132 &vec![Allocated(AllocatedEntry { link: ListLink { prev: None, next: None }, item: 0 })]
1133 );
1134 assert_eq!(freelist, &None);
1135 assert_eq!(allocatedlist, &Some(List { head: 0, tail: 0 }));
1136 }
1137
1138 #[test]
1139 fn test_key_ordered_iter() {
1140 let mut map = DenseMap::new();
1141 assert_eq!(map.insert(1, 0), None);
1142 assert_eq!(map.insert(3, 1), None);
1143 assert_eq!(map.insert(6, 2), None);
1144 let DenseMap { data, freelist, allocatedlist } = ↦
1145 assert_eq!(
1146 data,
1147 &vec![
1148 free_head(2),
1149 Allocated(AllocatedEntry { link: ListLink { prev: None, next: Some(3) }, item: 0 }),
1150 free(0, 4),
1151 Allocated(AllocatedEntry {
1152 link: ListLink { prev: Some(1), next: Some(6) },
1153 item: 1
1154 }),
1155 free(2, 5),
1156 free_tail(4),
1157 Allocated(AllocatedEntry { link: ListLink { prev: Some(3), next: None }, item: 2 }),
1158 ]
1159 );
1160 assert_eq!(freelist, &Some(List { head: 0, tail: 5 }));
1161 assert_eq!(allocatedlist, &Some(List { head: 1, tail: 6 }));
1162 let mut c = 0;
1163 let mut last_k = None;
1164 for (i, (k, v)) in map.key_ordered_iter().enumerate() {
1165 assert_eq!(i, *v as usize);
1166 assert_eq!(map.get(k).unwrap(), v);
1167 assert!(last_k < Some(k));
1168 last_k = Some(k);
1169 c += 1;
1170 }
1171 assert_eq!(c, 3);
1172 }
1173
1174 #[test]
1175 fn test_insertion_ordered_iter() {
1176 let mut map = DenseMap::new();
1177 assert_eq!(map.insert(6, 0), None);
1178 assert_eq!(map.insert(3, 2), None);
1179 assert_eq!(map.push(1), 0);
1180 assert_eq!(map.insertion_ordered_iter().collect::<Vec<_>>(), [(6, &0), (3, &2), (0, &1)]);
1181
1182 assert_eq!(map.insert(3, 0), Some(2));
1183 assert_eq!(map.insertion_ordered_iter().collect::<Vec<_>>(), [(6, &0), (0, &1), (3, &0)]);
1184 }
1185
1186 #[test]
1187 fn test_iter_mut() {
1188 let mut map = DenseMap::new();
1189 assert_eq!(map.insert(1, 0), None);
1190 assert_eq!(map.insert(3, 1), None);
1191 assert_eq!(map.insert(6, 2), None);
1192 let DenseMap { data, freelist, allocatedlist } = ↦
1193 assert_eq!(
1194 data,
1195 &vec![
1196 free_head(2),
1197 Allocated(AllocatedEntry { link: ListLink { prev: None, next: Some(3) }, item: 0 }),
1198 free(0, 4),
1199 Allocated(AllocatedEntry {
1200 link: ListLink { prev: Some(1), next: Some(6) },
1201 item: 1
1202 }),
1203 free(2, 5),
1204 free_tail(4),
1205 Allocated(AllocatedEntry { link: ListLink { prev: Some(3), next: None }, item: 2 }),
1206 ]
1207 );
1208 assert_eq!(freelist, &Some(List { head: 0, tail: 5 }));
1209 assert_eq!(allocatedlist, &Some(List { head: 1, tail: 6 }));
1210 let mut last_k = None;
1211 for (k, v) in map.key_ordered_iter_mut() {
1212 *v += k as u32;
1213 assert!(last_k < Some(k));
1214 last_k = Some(k);
1215 }
1216 let DenseMap { data, freelist, allocatedlist } = ↦
1217 assert_eq!(
1218 data,
1219 &vec![
1220 free_head(2),
1221 Allocated(AllocatedEntry { link: ListLink { prev: None, next: Some(3) }, item: 1 }),
1222 free(0, 4),
1223 Allocated(AllocatedEntry {
1224 link: ListLink { prev: Some(1), next: Some(6) },
1225 item: 4
1226 }),
1227 free(2, 5),
1228 free_tail(4),
1229 Allocated(AllocatedEntry { link: ListLink { prev: Some(3), next: None }, item: 8 }),
1230 ]
1231 );
1232 assert_eq!(freelist, &Some(List { head: 0, tail: 5 }));
1233 assert_eq!(allocatedlist, &Some(List { head: 1, tail: 6 }));
1234 }
1235
1236 #[test]
1237 fn test_into_iter() {
1238 let mut map = DenseMap::new();
1239 assert_eq!(map.insert(1, 0), None);
1240 assert_eq!(map.insert(3, 1), None);
1241 assert_eq!(map.insert(6, 2), None);
1242 assert_eq!(map.into_iter().collect::<Vec<_>>(), &[(1, 0), (3, 1), (6, 2)]);
1243 }
1244
1245 #[test]
1246 fn test_key_ordered_retain() {
1247 let mut map = DenseMap::new();
1251 for i in 0..8 {
1252 assert_eq!(map.push(i), i);
1253 }
1254
1255 map.key_ordered_retain(|x: &usize| *x % 2 != 0);
1257 let remaining: Vec<_> =
1258 map.key_ordered_iter().map(|(key, entry)| (key, entry.clone())).collect();
1259 assert_eq!(remaining.as_slice(), [(1, 1), (3, 3), (5, 5), (7, 7)]);
1260
1261 let DenseMap { data, freelist, allocatedlist } = ↦
1262 assert_eq!(
1263 data,
1264 &[
1265 free_tail(2),
1266 Allocated(AllocatedEntry { link: ListLink { prev: None, next: Some(3) }, item: 1 }),
1267 free(4, 0),
1268 Allocated(AllocatedEntry {
1269 link: ListLink { prev: Some(1), next: Some(5) },
1270 item: 3
1271 }),
1272 free(6, 2),
1273 Allocated(AllocatedEntry {
1274 link: ListLink { prev: Some(3), next: Some(7) },
1275 item: 5
1276 }),
1277 free_head(4),
1278 Allocated(AllocatedEntry { link: ListLink { prev: Some(5), next: None }, item: 7 }),
1279 ]
1280 );
1281 assert_eq!(freelist, &Some(List { head: 6, tail: 0 }));
1282 assert_eq!(allocatedlist, &Some(List { head: 1, tail: 7 }));
1283
1284 map.key_ordered_retain(|x| *x < 5);
1286 let DenseMap { data, freelist, allocatedlist } = ↦
1287 assert_eq!(
1288 data,
1289 &[
1290 free_tail(2),
1291 Allocated(AllocatedEntry { link: ListLink { prev: None, next: Some(3) }, item: 1 }),
1292 free_head(0),
1293 Allocated(AllocatedEntry { link: ListLink { prev: Some(1), next: None }, item: 3 }),
1294 ]
1295 );
1296 assert_eq!(freelist, &Some(List { head: 2, tail: 0 }));
1297 assert_eq!(allocatedlist, &Some(List { head: 1, tail: 3 }));
1298 }
1299
1300 #[test]
1301 fn test_entry() {
1302 let mut map = DenseMap::new();
1303 assert_eq!(*map.entry(1).or_insert(2), 2);
1304 let DenseMap { data, freelist, allocatedlist } = ↦
1305 assert_eq!(
1306 data,
1307 &vec![
1308 free_none(),
1309 Allocated(AllocatedEntry { link: ListLink { prev: None, next: None }, item: 2 })
1310 ]
1311 );
1312 assert_eq!(freelist, &Some(List::singleton(0)));
1313 assert_eq!(allocatedlist, &Some(List::singleton(1)));
1314 assert_eq!(
1315 *map.entry(1)
1316 .and_modify(|v| {
1317 *v = 10;
1318 })
1319 .or_insert(5),
1320 10
1321 );
1322 let DenseMap { data, freelist, allocatedlist } = ↦
1323 assert_eq!(
1324 data,
1325 &vec![
1326 free_none(),
1327 Allocated(AllocatedEntry { link: ListLink { prev: None, next: None }, item: 10 })
1328 ]
1329 );
1330 assert_eq!(freelist, &Some(List::singleton(0)));
1331 assert_eq!(allocatedlist, &Some(List::singleton(1)));
1332 assert_eq!(
1333 *map.entry(2)
1334 .and_modify(|v| {
1335 *v = 10;
1336 })
1337 .or_insert(5),
1338 5
1339 );
1340 let DenseMap { data, freelist, allocatedlist } = ↦
1341 assert_eq!(
1342 data,
1343 &vec![
1344 free_none(),
1345 Allocated(AllocatedEntry {
1346 link: ListLink { prev: None, next: Some(2) },
1347 item: 10
1348 }),
1349 Allocated(AllocatedEntry { link: ListLink { prev: Some(1), next: None }, item: 5 }),
1350 ]
1351 );
1352 assert_eq!(freelist, &Some(List::singleton(0)));
1353 assert_eq!(allocatedlist, &Some(List { head: 1, tail: 2 }));
1354 assert_eq!(*map.entry(4).or_default(), 0);
1355 let DenseMap { data, freelist, allocatedlist } = ↦
1356 assert_eq!(
1357 data,
1358 &vec![
1359 free_head(3),
1360 Allocated(AllocatedEntry {
1361 link: ListLink { prev: None, next: Some(2) },
1362 item: 10
1363 }),
1364 Allocated(AllocatedEntry {
1365 link: ListLink { prev: Some(1), next: Some(4) },
1366 item: 5
1367 }),
1368 free_tail(0),
1369 Allocated(AllocatedEntry { link: ListLink { prev: Some(2), next: None }, item: 0 })
1370 ]
1371 );
1372 assert_eq!(freelist, &Some(List { head: 0, tail: 3 }));
1373 assert_eq!(allocatedlist, &Some(List { head: 1, tail: 4 }));
1374 assert_eq!(*map.entry(3).or_insert_with(|| 7), 7);
1375 let DenseMap { data, freelist, allocatedlist } = ↦
1376 assert_eq!(
1377 data,
1378 &vec![
1379 free_none(),
1380 Allocated(AllocatedEntry {
1381 link: ListLink { prev: None, next: Some(2) },
1382 item: 10
1383 }),
1384 Allocated(AllocatedEntry {
1385 link: ListLink { prev: Some(1), next: Some(4) },
1386 item: 5
1387 }),
1388 Allocated(AllocatedEntry { link: ListLink { prev: Some(4), next: None }, item: 7 }),
1389 Allocated(AllocatedEntry {
1390 link: ListLink { prev: Some(2), next: Some(3) },
1391 item: 0
1392 })
1393 ]
1394 );
1395 assert_eq!(freelist, &Some(List::singleton(0)));
1396 assert_eq!(allocatedlist, &Some(List { head: 1, tail: 3 }));
1397 assert_eq!(*map.entry(0).or_insert(1), 1);
1398 let DenseMap { data, freelist, allocatedlist } = ↦
1399 assert_eq!(
1400 data,
1401 &vec![
1402 Allocated(AllocatedEntry { link: ListLink { prev: Some(3), next: None }, item: 1 }),
1403 Allocated(AllocatedEntry {
1404 link: ListLink { prev: None, next: Some(2) },
1405 item: 10
1406 }),
1407 Allocated(AllocatedEntry {
1408 link: ListLink { prev: Some(1), next: Some(4) },
1409 item: 5
1410 }),
1411 Allocated(AllocatedEntry {
1412 link: ListLink { prev: Some(4), next: Some(0) },
1413 item: 7
1414 }),
1415 Allocated(AllocatedEntry {
1416 link: ListLink { prev: Some(2), next: Some(3) },
1417 item: 0
1418 })
1419 ]
1420 );
1421 assert_eq!(freelist, &None);
1422 assert_eq!(allocatedlist, &Some(List { head: 1, tail: 0 }));
1423 match map.entry(0) {
1424 Entry::Occupied(mut e) => {
1425 assert_eq!(*e.key(), 0);
1426 assert_eq!(*e.get(), 1);
1427 *e.get_mut() = 2;
1428 assert_eq!(*e.get(), 2);
1429 assert_eq!(e.remove(), 2);
1430 }
1431 _ => panic!("Wrong entry type, should be occupied"),
1432 }
1433 let DenseMap { data, freelist, allocatedlist } = ↦
1434 assert_eq!(
1435 data,
1436 &vec![
1437 free_none(),
1438 Allocated(AllocatedEntry {
1439 link: ListLink { prev: None, next: Some(2) },
1440 item: 10
1441 }),
1442 Allocated(AllocatedEntry {
1443 link: ListLink { prev: Some(1), next: Some(4) },
1444 item: 5
1445 }),
1446 Allocated(AllocatedEntry { link: ListLink { prev: Some(4), next: None }, item: 7 }),
1447 Allocated(AllocatedEntry {
1448 link: ListLink { prev: Some(2), next: Some(3) },
1449 item: 0
1450 })
1451 ]
1452 );
1453 assert_eq!(freelist, &Some(List::singleton(0)));
1454 assert_eq!(allocatedlist, &Some(List { head: 1, tail: 3 }));
1455
1456 match map.entry(0) {
1457 Entry::Vacant(e) => {
1458 assert_eq!(*e.key(), 0);
1459 assert_eq!(*e.insert(4), 4);
1460 }
1461 _ => panic!("Wrong entry type, should be vacant"),
1462 }
1463 let DenseMap { data, freelist, allocatedlist } = ↦
1464 assert_eq!(
1465 data,
1466 &vec![
1467 Allocated(AllocatedEntry { link: ListLink { prev: Some(3), next: None }, item: 4 }),
1468 Allocated(AllocatedEntry {
1469 link: ListLink { prev: None, next: Some(2) },
1470 item: 10
1471 }),
1472 Allocated(AllocatedEntry {
1473 link: ListLink { prev: Some(1), next: Some(4) },
1474 item: 5
1475 }),
1476 Allocated(AllocatedEntry {
1477 link: ListLink { prev: Some(4), next: Some(0) },
1478 item: 7
1479 }),
1480 Allocated(AllocatedEntry {
1481 link: ListLink { prev: Some(2), next: Some(3) },
1482 item: 0
1483 })
1484 ]
1485 );
1486 assert_eq!(freelist, &None);
1487 assert_eq!(allocatedlist, &Some(List { head: 1, tail: 0 }));
1488 }
1489
1490 #[test]
1491 fn test_freelist_order() {
1492 let mut rng = crate::testutil::new_rng(1234981);
1493 const NELEMS: usize = 1_000;
1494 for _ in 0..1_000 {
1495 let mut map = DenseMap::new();
1496 for i in 0..NELEMS {
1497 assert_eq!(map.push(i), i);
1498 }
1499 let mut remove_seq: Vec<usize> = (0..NELEMS - 1).collect();
1501 remove_seq.shuffle(&mut rng);
1502 for i in &remove_seq {
1503 assert_ne!(map.remove(*i), None);
1504 }
1505 for i in remove_seq.iter().rev() {
1506 assert_eq!(map.push(*i), *i);
1508 }
1509 assert_ne!(map.remove(NELEMS - 1), None);
1510 for i in &remove_seq {
1511 assert_ne!(map.remove(*i), None);
1512 }
1513 assert_empty(map.key_ordered_iter());
1514 }
1515 }
1516
1517 #[test]
1518 fn test_compress_freelist() {
1519 let mut map = DenseMap::new();
1520 for i in 0..100 {
1521 assert_eq!(map.push(0), i);
1522 }
1523 for i in 0..100 {
1524 assert_eq!(map.remove(i), Some(0));
1525 }
1526 let DenseMap { data, freelist, allocatedlist } = ↦
1527 assert_empty(data.iter());
1528 assert_eq!(freelist, &None);
1529 assert_eq!(allocatedlist, &None);
1530 }
1531
1532 #[test]
1533 fn test_insert_beyond_end_freelist() {
1534 let mut map = DenseMap::new();
1535 for i in 0..10 {
1536 assert_eq!(map.insert(2 * i + 1, 0), None);
1537 }
1538 for i in 0..10 {
1539 assert_eq!(map.push(1), 2 * i);
1540 }
1541 }
1542
1543 #[test]
1544 fn test_double_free() {
1545 const MAX_KEY: usize = 100;
1546 let mut map1 = DenseMap::new();
1547 assert_eq!(map1.insert(MAX_KEY, 2), None);
1548 let mut map2 = DenseMap::new();
1549 assert_eq!(map2.insert(MAX_KEY, 2), None);
1550 for i in 0..MAX_KEY {
1551 assert_eq!(map1.remove(i), None);
1552 assert_eq!(map1.data, map2.data);
1554 assert_eq!(map1.freelist, map2.freelist);
1555 }
1556 }
1557
1558 #[derive(Debug)]
1559 enum Operation<K, V> {
1560 Get { key: K },
1561 Insert { key: K, value: V },
1562 Remove { key: K },
1563 Push { value: V },
1564 }
1565
1566 impl<V> Operation<usize, V>
1567 where
1568 V: Copy + core::cmp::PartialEq + core::fmt::Debug,
1569 {
1570 fn apply(self, map: &mut DenseMap<V>, source_of_truth: &mut HashMap<usize, V>) {
1571 match self {
1572 Self::Get { key } => {
1573 assert_eq!(
1574 map.get(key),
1575 source_of_truth.get(&key),
1576 "key={} map.get == truth.get",
1577 key
1578 );
1579 }
1580 Self::Insert { key, value } => {
1581 assert_eq!(
1582 map.insert(key, value),
1583 source_of_truth.insert(key, value),
1584 "key={}, map.insert == truth.insert",
1585 key
1586 );
1587 }
1588 Self::Remove { key } => {
1589 assert_eq!(
1590 map.remove(key),
1591 source_of_truth.remove(&key),
1592 "key={} map.remove == truth.remove",
1593 key,
1594 );
1595 }
1596 Self::Push { value } => {
1597 let key = map.push(value);
1598 assert_eq!(
1599 source_of_truth.insert(key, value),
1600 None,
1601 "pushed key={}, value={:?}",
1602 key,
1603 value
1604 );
1605 }
1606 }
1607 }
1608 }
1609
1610 use proptest::strategy::Strategy;
1611
1612 fn operation_strategy() -> impl Strategy<Value = Operation<usize, i32>> {
1613 let key_strategy = || 0..20usize;
1614 let value_strategy = || 0..10i32;
1617
1618 proptest::prop_oneof![
1619 key_strategy().prop_map(|key| Operation::Get { key }),
1620 (key_strategy(), value_strategy())
1621 .prop_map(|(key, value)| Operation::Insert { key, value }),
1622 key_strategy().prop_map(|key| Operation::Remove { key }),
1623 value_strategy().prop_map(|value| Operation::Push { value }),
1624 ]
1625 }
1626
1627 fn find_elements<T>(
1628 data: &[DenseMapEntry<T>],
1629 get_link: impl Fn(&DenseMapEntry<T>) -> Option<&ListLink>,
1630 ) -> Vec<usize> {
1631 let head = data.iter().enumerate().find_map(|(i, e)| {
1632 let link = get_link(e)?;
1633 let ListLink { prev, next: _ } = link;
1634 if prev == &None {
1635 Some((i, *link))
1636 } else {
1637 None
1638 }
1639 });
1640 let mut found = Vec::new();
1641 let mut next = head;
1642
1643 while let Some((index, link)) = next {
1645 found.push(index);
1646 next = link.next.map(|next_i| {
1647 let next_entry =
1648 *get_link(&data[next_i]).expect("entry should match target link type");
1649 assert_eq!(Some(index), next_entry.prev, "data[{}] and data[{}]", index, next_i);
1650 (next_i, next_entry)
1651 })
1652 }
1653
1654 data.iter().enumerate().for_each(|(i, e)| {
1656 assert_eq!(
1657 found.contains(&i),
1658 get_link(e).is_some(),
1659 "data[{}] should be in found list if link type matches",
1660 i,
1661 )
1662 });
1663 found
1664 }
1665
1666 fn find_free_elements<T>(data: &[DenseMapEntry<T>]) -> Vec<usize> {
1669 find_elements(data, |entry| match entry {
1670 DenseMapEntry::Free(link) => Some(link),
1671 DenseMapEntry::Allocated(_) => None,
1672 })
1673 }
1674
1675 fn find_allocated_elements<T>(data: &[DenseMapEntry<T>]) -> Vec<usize> {
1678 find_elements(data, |entry| match entry {
1679 DenseMapEntry::Allocated(AllocatedEntry { item: _, link }) => Some(link),
1680 DenseMapEntry::Free(_) => None,
1681 })
1682 }
1683
1684 #[test]
1685 fn test_find_free_elements() {
1686 let data = vec![
1687 Allocated(AllocatedEntry { link: ListLink { prev: None, next: None }, item: 1 }),
1688 free_tail(2),
1689 free(3, 1),
1690 free_head(2),
1691 ];
1692 assert_eq!(find_free_elements(&data), vec![3, 2, 1]);
1693 }
1694
1695 #[test]
1696 fn test_find_free_elements_none_free() {
1697 let data = vec![
1698 Allocated(AllocatedEntry { link: ListLink { prev: None, next: None }, item: 1 }),
1699 Allocated(AllocatedEntry { link: ListLink { prev: None, next: None }, item: 2 }),
1700 Allocated(AllocatedEntry { link: ListLink { prev: None, next: None }, item: 3 }),
1701 Allocated(AllocatedEntry { link: ListLink { prev: None, next: None }, item: 2 }),
1702 ];
1703 assert_eq!(find_free_elements(&data), vec![]);
1704 }
1705
1706 #[test]
1707 #[should_panic(expected = "entry should match target link type")]
1708 fn test_find_free_elements_includes_allocated() {
1709 let data = vec![
1710 Allocated(AllocatedEntry { link: ListLink { prev: None, next: None }, item: 1 }),
1711 free_head(0),
1712 free_tail(0),
1713 ];
1714 let _ = find_free_elements(&data);
1715 }
1716
1717 #[test]
1718 #[should_panic(expected = "should be in found list if link type matches")]
1719 fn test_find_free_elements_in_cycle() {
1720 let data = vec![
1721 free(2, 1),
1722 free(0, 2),
1723 free(1, 0),
1724 Allocated(AllocatedEntry { link: ListLink { prev: None, next: None }, item: 5 }),
1725 ];
1726 let _ = find_free_elements(&data);
1727 }
1728
1729 #[test]
1730 #[should_panic(expected = "should be in found list if link type matches")]
1731 fn test_find_free_elements_multiple_lists() {
1732 let data = vec![
1733 free_head(1),
1734 free_tail(0),
1735 Allocated(AllocatedEntry { link: ListLink { prev: None, next: None }, item: 13 }),
1736 free_head(4),
1737 free_tail(3),
1738 ];
1739 let _ = find_free_elements(&data);
1740 }
1741
1742 proptest::proptest! {
1743 #![proptest_config(proptest::test_runner::Config {
1744 failure_persistence: proptest_support::failed_seeds_no_std!(),
1746 ..proptest::test_runner::Config::default()
1747 })]
1748
1749 #[test]
1750 fn test_arbitrary_operations(operations in proptest::collection::vec(operation_strategy(), 10)) {
1751 let mut map = DenseMap::new();
1752 let mut reference = HashMap::new();
1753 for op in operations {
1754 op.apply(&mut map, &mut reference);
1755
1756 let DenseMap { data, freelist, allocatedlist } = ↦
1758
1759 match freelist {
1760 None => {
1761 data.iter().enumerate().for_each(|(i, d)| match d {
1763 DenseMapEntry::Free(_) => panic!("no freelist but data[{}] is free", i),
1764 DenseMapEntry::Allocated(_) => (),
1765 })
1766 },
1767 Some(List {head, tail}) => {
1768 let free = find_free_elements(data);
1769 assert_eq!(free.first(), Some(head));
1770 assert_eq!(free.last(), Some(tail));
1771 }
1772 }
1773
1774 match allocatedlist {
1775 None => {
1776 data.iter().enumerate().for_each(|(i, d)| match d {
1778 DenseMapEntry::Allocated(_) => panic!("no allocatedlist but data[{}] is allocated", i),
1779 DenseMapEntry::Free(_) => (),
1780 })
1781 },
1782 Some(List {head, tail}) => {
1783 let allocated = find_allocated_elements(data);
1784 assert_eq!(allocated.first(), Some(head));
1785 assert_eq!(allocated.last(), Some(tail));
1786 }
1787 }
1788 }
1789
1790 let elements : HashMap<_, i32> = map.key_ordered_iter().map(|(a, b)| (a, *b)).collect();
1792 assert_eq!(elements, reference);
1793 }
1794 }
1795}