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