dense_map/
lib.rs

1// Copyright 2019 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5//! A densely packed map.
6//!
7//! Defines the [`DenseMap`] data structure: A generic mapped container keyed by
8//! an internally managed pool of identifiers kept densely packed.
9
10#![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
22/// [`DenseMap`]s use `usize`s for keys.
23pub type Key = usize;
24
25/// DenseMapEntry where all free blocks are linked together.
26#[derive(PartialEq, Eq, Debug)]
27#[cfg_attr(test, derive(Clone))]
28enum DenseMapEntry<T> {
29    /// The Entry should either be allocated and contains a value...
30    Allocated(AllocatedEntry<T>),
31    /// Or it is not currently used and should be part of a freelist.
32    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/// The link of a doubly-linked list.
43#[derive(PartialEq, Eq, Debug, Clone, Copy)]
44struct ListLink {
45    /// The index of the previous free block in the list.
46    prev: Option<usize>,
47    /// The index of the next free block in the list.
48    next: Option<usize>,
49}
50
51impl Default for ListLink {
52    /// By default, an entry is not linked into the list.
53    fn default() -> Self {
54        Self { prev: None, next: None }
55    }
56}
57
58/// Stores positions of the head and tail of a doubly-linked list by
59/// `ListLink`.
60#[derive(PartialEq, Eq, Debug, Clone, Copy)]
61struct List {
62    /// The index of the first free block.
63    head: usize,
64    /// The index of the last free block.
65    tail: usize,
66}
67
68impl List {
69    /// Construct a doubly-linked list with only one element.
70    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    /// Returns a reference to the freelist link if the entry is free, otherwise None.
99    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    /// Returns a mutable reference to the freelist link if the entry is free, otherwise None.
107    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/// A generic container for `T` keyed by densely packed integers.
116///
117/// `DenseMap` is a generic container keyed by `usize` that manages its own key
118/// pool. `DenseMap` reuses keys that are free to keep its key pool as dense as
119/// possible.
120///
121/// The main guarantee provided by `DenseMap` is that all `get` operations are
122/// provided in O(1) without the need to hash the keys.
123///
124/// All operations that mutate the `DenseMap` may be O(n) during resizing or
125/// compression but averages at O(1).
126///
127/// `push` will grab the lowest free `id` and assign it to the given value,
128/// returning the assigned `id`. `insert` can be used for assigning a specific
129/// `id` to an object, and returns the previous object at that `id` if any.
130#[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    /// Creates a new empty [`DenseMap`].
140    pub fn new() -> Self {
141        Self { freelist: None, allocatedlist: None, data: Vec::new() }
142    }
143
144    /// Returns `true` if there are no items in [`DenseMap`].
145    pub fn is_empty(&self) -> bool {
146        // Because of `compress`, our map is empty if and only if the underlying
147        // vector is empty. If the underlying vector is not empty but our map is
148        // empty, it must be the case where the underlying vector contains
149        // nothing but free entries, and all these entries should be reclaimed
150        // when the last allocated entry is removed.
151        self.data.is_empty()
152    }
153
154    /// Returns a reference to the item indexed by `key`, or `None` if the `key`
155    /// doesn't exist.
156    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    /// Returns a mutable reference to the item indexed by `key`, or `None` if
164    /// the `key` doesn't exist.
165    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    /// Removes item indexed by `key` from the container.
173    ///
174    /// Returns the removed item if it exists, or `None` otherwise.
175    ///
176    /// Note: the worst case complexity of `remove` is O(key) if the backing
177    /// data structure of the [`DenseMap`] is too sparse.
178    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                // If it is currently free, we don't want to unlink the entry and
198                // link it back at the head again.
199                DenseMapEntry::Free(_) => None,
200            }
201        });
202        r.map(|AllocatedEntry { link, item }| {
203            self.unlink_entry_inner(DenseMapEntryKind::Allocated, link);
204            // If it was allocated, we add the removed entry to the head of the
205            // free-list.
206            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        // Add the key to the tail of the allocated list. There are four cases
227        // to consider. In all cases however, we update the list's tail to point
228        // to `key` and create a `ListLink` with a previous pointer that points
229        // to the current allocate list's tail and no next pointer.
230        //
231        //  1) The allocated list is empty.
232        //  2) `key` points to a free entry
233        //  3) `key` is the (non-empty) allocated list's tail.
234        //  4) `key` is in the middle of the (non-empty) allocated list.
235        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    /// Inserts `item` at `key`.
254    ///
255    /// If the [`DenseMap`] already contained an item indexed by `key`, `insert`
256    /// returns it, or `None` otherwise.
257    ///
258    /// Note: The worst case complexity of `insert` is O(key) if `key` is larger
259    /// than the number of items currently held by the [`DenseMap`].
260    pub fn insert(&mut self, key: Key, item: T) -> Option<T> {
261        if key < self.data.len() {
262            // Remove the entry from whatever list it may be in
263            self.unlink_entry(key);
264            // Add the key to the allocated list.
265            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            // We don't need to do anything with the `ListLink` since we removed
272            // the entry from the list.
273            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            // Fill the gap `start_len .. key` with free entries. Currently, the
282            // free entries introduced by `insert` is linked at the end of the
283            // free list so that hopefully these free entries near the end will
284            // get less likely to be allocated than those near the beginning,
285            // this may help reduce the memory footprint because we have
286            // increased the chance for the underlying vector to be compressed.
287            // TODO: explore whether we can reorder the list on the fly to
288            // further increase the chance for compressing.
289            for idx in start_len..key {
290                // These new free entries will be linked to each other, except:
291                // - the first entry's prev should point to the old tail.
292                // - the last entry's next should be None.
293                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`, we have inserted at least one free entry,
303            // so we have to update our freelist.
304            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            // And finally we insert our item into the map.
320            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    /// Inserts `item` into the [`DenseMap`].
327    ///
328    /// `push` inserts a new `item` into the [`DenseMap`] and returns the key value
329    /// allocated for `item`. `push` will allocate *any* key that is currently
330    /// free in the internal structure, so it may return a key that was used
331    /// previously but has since been removed.
332    ///
333    /// Note: The worst case complexity of `push` is O(n) where n is the number
334    /// of items held by the [`DenseMap`]. This can happen if the internal
335    /// structure gets fragmented.
336    pub fn push(&mut self, item: T) -> Key {
337        *self.push_entry(item).key()
338    }
339
340    /// Inserts `item` into the [`DenseMap`] and returns an [`OccupiedEntry`] for
341    /// it.
342    ///
343    /// Like [`DenseMap::push`] except that it returns an entry instead of an
344    /// index.
345    pub fn push_entry(&mut self, item: T) -> OccupiedEntry<'_, usize, T> {
346        self.push_with(|_: usize| item)
347    }
348
349    /// Creates an `item` in the `DenseMap` via functor.
350    ///
351    /// Like [`DenseMap::push`] except that the item is constructed by the provided
352    /// function, which is passed its index.
353    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            // Update the head of the freelist.
366            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            // If we run out of freelist, we simply push a new entry into the
379            // underlying vector.
380            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    /// Compresses the tail of the internal `Vec`.
388    ///
389    /// `compress` removes all trailing elements in `data` that are `None`,
390    /// shrinking the internal `Vec`.
391    fn compress(&mut self) {
392        // First, find the last non-free entry.
393        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            // Remove all the trailing free entries.
398            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            // There is nothing left in the vector.
405            self.data.clear();
406            self.freelist = None;
407        }
408    }
409
410    /// Creates an iterator over the containing items and their associated keys.
411    ///
412    /// The iterator will return items in insertion order.
413    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    /// Creates an iterator over the containing items and their associated keys.
420    ///
421    /// The iterator will return items in key order.
422    pub fn key_ordered_iter(&self) -> KeyOrderedIter<'_, T> {
423        IntoIterator::into_iter(self)
424    }
425
426    /// Creates a mutable iterator over the containing items and their
427    /// associated keys.
428    ///
429    /// The iterator will return items in key order.
430    pub fn key_ordered_iter_mut(&mut self) -> KeyOrderedIterMut<'_, T> {
431        IntoIterator::into_iter(self)
432    }
433
434    /// Consumes the `DenseMap` and returns an iterator over the contained items
435    /// and their associated keys.
436    ///
437    /// The iterator will return items in key order.
438    pub fn key_ordered_into_iter(self) -> IntoKeyOrderedIter<T> {
439        IntoIterator::into_iter(self)
440    }
441
442    /// Gets the given key's corresponding entry in the map for in-place
443    /// manipulation.
444    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    /// Retains only the elements specified by the predicate.
453    ///
454    /// In other words, remove all elements e for which f(&e) returns false. The
455    /// elements are visited in ascending key order.
456    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                    // Note the use of `remove_inner` rather than `remove`
463                    // here. `remove` calls `self.compress()`, which is an
464                    // O(n) operation. Instead, we postpone that operation
465                    // and perform it once during the last iteration so that
466                    // the overall complexity is O(n) rather than O(n^2).
467                    //
468                    // TODO(joshlf): Could we improve the performance here
469                    // by doing something smarter than just calling
470                    // `remove_inner`? E.g., perhaps we could build up a
471                    // separate linked list that we only insert into the
472                    // existing free list once at the end? That there is a
473                    // performance issue here at all is pure speculation,
474                    // and will need to be measured to determine whether
475                    // such an optimization is worth it.
476                    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                // A normal node in the middle of a list.
495                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                // The node at the tail.
500                self.data[prev].link_mut_and_check(kind).next = next;
501                list.as_mut().unwrap().tail = prev;
502            }
503            (None, Some(next)) => {
504                // The node at the head.
505                self.data[next].link_mut_and_check(kind).prev = prev;
506                list.as_mut().unwrap().head = next;
507            }
508            (None, None) => {
509                // We are the last node.
510                *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
527/// An iterator over the keys and values stored in an [`DenseMap`].
528///
529/// This iterator returns items in insertion order.
530pub 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
553/// An iterator over the keys and values stored in an [`DenseMap`].
554///
555/// This iterator returns items in key order.
556pub 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
579/// An iterator over the keys and values stored in an [`DenseMap`].
580///
581/// This iterator returns items in key order.
582pub 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
606/// An iterator over the keys and mutable values stored in an [`DenseMap`].
607///
608/// This iterator returns items in key order.
609pub 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
635/// A key providing an index into an [`DenseMap`].
636pub trait EntryKey {
637    /// Returns the index for this key.
638    fn get_key_index(&self) -> usize;
639}
640
641impl EntryKey for usize {
642    fn get_key_index(&self) -> usize {
643        *self
644    }
645}
646
647/// A view into a vacant entry in a map. It is part of the [`Entry`] enum.
648pub 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    /// Sets the value of the entry with the VacantEntry's key, and returns a
655    /// mutable reference to it.
656    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    /// Gets a reference to the key that would be used when inserting a value
668    /// through the `VacantEntry`.
669    pub fn key(&self) -> &K {
670        &self.key
671    }
672
673    /// Take ownership of the key.
674    pub fn into_key(self) -> K {
675        self.key
676    }
677
678    /// Changes the key type of this `VacantEntry` to another key `X` that still
679    /// maps to the same index in an `DenseMap`.
680    ///
681    /// # Panics
682    ///
683    /// Panics if the resulting mapped key from `f` does not return the same
684    /// value for [`EntryKey::get_key_index`] as the old key did.
685    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
698/// A view into an occupied entry in a map. It is part of the [`Entry`] enum.
699pub 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    /// Gets a reference to the key in the entry.
706    pub fn key(&self) -> &K {
707        &self.key
708    }
709
710    /// Leaves the value in the map and returns the key.
711    pub fn into_key(self) -> K {
712        self.key
713    }
714
715    /// Gets a reference to the value in the entry.
716    pub fn get(&self) -> &T {
717        // We can unwrap because value is always Some for OccupiedEntry.
718        self.id_map.get(self.key.get_key_index()).unwrap()
719    }
720
721    /// Gets a mutable reference to the value in the entry.
722    ///
723    /// If you need a reference to the `OccupiedEntry` which may outlive the
724    /// destruction of the entry value, see [`OccupiedEntry::into_mut`].
725    pub fn get_mut(&mut self) -> &mut T {
726        // We can unwrap because value is always Some for OccupiedEntry.
727        self.id_map.get_mut(self.key.get_key_index()).unwrap()
728    }
729
730    /// Converts the `OccupiedEntry` into a mutable reference to the value in
731    /// the entry with a lifetime bound to the map itself.
732    ///
733    /// If you need multiple references to the `OccupiedEntry`, see
734    /// [`OccupiedEntry::get_mut`].
735    pub fn into_mut(self) -> &'a mut T {
736        // We can unwrap because value is always Some for OccupiedEntry.
737        self.id_map.get_mut(self.key.get_key_index()).unwrap()
738    }
739
740    /// Sets the value of the entry, and returns the entry's old value.
741    pub fn insert(&mut self, value: T) -> T {
742        // We can unwrap because value is always Some for OccupiedEntry.
743        self.id_map.insert(self.key.get_key_index(), value).unwrap()
744    }
745
746    /// Takes the value out of the entry, and returns it.
747    pub fn remove(self) -> T {
748        // We can unwrap because value is always Some for OccupiedEntry.
749        self.id_map.remove(self.key.get_key_index()).unwrap()
750    }
751
752    /// Changes the key type of this `OccupiedEntry` to another key `X` that
753    /// still maps to the same index in an `DenseMap`.
754    ///
755    /// # Panics
756    ///
757    /// Panics if the resulting mapped key from `f` does not return the same
758    /// value for [`EntryKey::get_key_index`] as the old key did.
759    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
779/// A view into an in-place entry in a map that can be vacant or occupied.
780pub enum Entry<'a, K, T> {
781    /// A vacant entry.
782    Vacant(VacantEntry<'a, K, T>),
783    /// An occupied entry.
784    Occupied(OccupiedEntry<'a, K, T>),
785}
786
787impl<'a, K: EntryKey, T> Entry<'a, K, T> {
788    /// Returns a reference to this entry's key.
789    pub fn key(&self) -> &K {
790        match self {
791            Entry::Vacant(e) => e.key(),
792            Entry::Occupied(e) => e.key(),
793        }
794    }
795
796    /// Ensures a value is in the entry by inserting `default` if empty, and
797    /// returns a mutable reference to the value in the entry.
798    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    /// Ensures a value is in the entry by inserting the result of the function
809    /// `f` if empty, and returns a mutable reference to the value in the entry.
810    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    /// Ensures a value is in the entry by inserting the default value if empty,
821    /// and returns a mutable reference to the value in the entry.
822    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    /// Provides in-place mutable access to an occupied entry before any
831    /// potential inserts into the map.
832    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    /// Remove the entry from [`DenseMap`].
843    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    // Smart constructors
863    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 } = &map;
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 } = &map;
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 } = &map;
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 } = &map;
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 } = &map;
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 } = &map;
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 } = &map;
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 } = &map;
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 } = &map;
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 } = &map;
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 } = &map;
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 } = &map;
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 } = &map;
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 } = &map;
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        // Regression test for https://fxbug.dev/42171085: a sequence of inserts that creates a run of
1106        // free elements with size > 1 followed by removes can result in `freelist` = None even
1107        // though `data` contains ListLink entries.
1108        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 } = &map;
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        // The remove() call compresses the list, which leaves just the 0 element.
1129        let DenseMap { data, freelist, allocatedlist } = &map;
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 } = &map;
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 } = &map;
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 } = &map;
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        // First, test that removed entries are actually removed, and that the
1248        // remaining entries are actually left there.
1249
1250        let mut map = DenseMap::new();
1251        for i in 0..8 {
1252            assert_eq!(map.push(i), i);
1253        }
1254
1255        // Keep only the odd entries.
1256        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 } = &map;
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        // Make sure that the underlying vector gets compressed.
1285        map.key_ordered_retain(|x| *x < 5);
1286        let DenseMap { data, freelist, allocatedlist } = &map;
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 } = &map;
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 } = &map;
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 } = &map;
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 } = &map;
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 } = &map;
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 } = &map;
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 } = &map;
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 } = &map;
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            // Don't remove the last one to prevent compressing.
1500            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                // We should be able to push into the array in the same order.
1507                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 } = &map;
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            // Removing an already free entry should be a no-op.
1553            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        // Use a small range for values since we don't do anything fancy with them
1615        // so a larger range probably won't expose additional issues.
1616        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        // Traverse the free list, collecting all indices into `found`.
1644        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        // The freelist should contain all of the free data elements.
1655        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    /// Searches through the given data entries to identify the free list. Returns the indices of
1667    /// elements in the free list in order, panicking if there is any inconsistency in the list.
1668    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    /// Searches through the given data entries to identify the allocated list. Returns the indices of
1676    /// elements in the allocated list in order, panicking if there is any inconsistency in the list.
1677    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            // Add all failed seeds here.
1745            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                // Now check the invariants that the map should be guaranteeing.
1757                let DenseMap { data, freelist, allocatedlist } = &map;
1758
1759                match freelist {
1760                    None => {
1761                        // No freelist means all nodes are allocated.
1762                        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                        // No allocatedlist means all nodes are free.
1777                        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            // After all operations have completed, the contents of the map should match the source of truth.
1791            let elements : HashMap<_, i32> = map.key_ordered_iter().map(|(a, b)| (a, *b)).collect();
1792            assert_eq!(elements, reference);
1793        }
1794    }
1795}