Skip to main content

iddqd/id_ord_map/
imp.rs

1use super::{
2    Entry, IdOrdItem, IntoIter, Iter, IterMut, OccupiedEntry, RefMut,
3    VacantEntry, tables::IdOrdMapTables,
4};
5use crate::{
6    errors::DuplicateItem,
7    internal::{ValidateChaos, ValidateCompact, ValidationError},
8    support::{
9        ItemIndex,
10        alloc::{Global, global_alloc},
11        borrow::DormantMutRef,
12        item_set::ItemSet,
13        map_hash::MapHash,
14    },
15};
16use alloc::collections::BTreeSet;
17use core::{
18    fmt,
19    hash::{BuildHasher, Hash},
20};
21use equivalent::{Comparable, Equivalent};
22
23/// An ordered map where the keys are part of the values, based on a B-Tree.
24///
25/// The storage mechanism is a list of items with an embedded free chain, with
26/// indexes to occupied slots stored in a B-Tree map.
27///
28/// # Examples
29///
30/// ```
31/// # #[cfg(feature = "default-hasher")] {
32/// use iddqd::{IdOrdItem, IdOrdMap, id_upcast};
33///
34/// // Define a struct with a key.
35/// #[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
36/// struct MyItem {
37///     id: String,
38///     value: u32,
39/// }
40///
41/// // Implement IdOrdItem for the struct.
42/// impl IdOrdItem for MyItem {
43///     // Keys can borrow from the item.
44///     type Key<'a> = &'a str;
45///
46///     fn key(&self) -> Self::Key<'_> {
47///         &self.id
48///     }
49///
50///     id_upcast!();
51/// }
52///
53/// // Create an IdOrdMap and insert items.
54/// let mut map = IdOrdMap::new();
55/// map.insert_unique(MyItem { id: "foo".to_string(), value: 42 }).unwrap();
56/// map.insert_unique(MyItem { id: "bar".to_string(), value: 20 }).unwrap();
57///
58/// // Look up items by their keys.
59/// assert_eq!(map.get("foo").unwrap().value, 42);
60/// assert_eq!(map.get("bar").unwrap().value, 20);
61/// assert!(map.get("baz").is_none());
62/// # }
63/// ```
64#[derive(Clone)]
65pub struct IdOrdMap<T> {
66    // We don't expose an allocator trait here because it isn't stable with
67    // std's BTreeMap.
68    pub(super) items: ItemSet<T, Global>,
69    // Invariant: the values (ItemIndex) in these tables are valid indexes into
70    // `items`, and are a 1:1 mapping.
71    pub(super) tables: IdOrdMapTables,
72}
73
74impl<T: IdOrdItem> Default for IdOrdMap<T> {
75    fn default() -> Self {
76        Self::new()
77    }
78}
79
80impl<T: IdOrdItem> IdOrdMap<T> {
81    /// Creates a new, empty `IdOrdMap`.
82    ///
83    /// # Examples
84    ///
85    /// ```
86    /// use iddqd::{IdOrdItem, IdOrdMap, id_upcast};
87    ///
88    /// #[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
89    /// struct Item {
90    ///     id: String,
91    ///     value: u32,
92    /// }
93    ///
94    /// impl IdOrdItem for Item {
95    ///     type Key<'a> = &'a str;
96    ///
97    ///     fn key(&self) -> Self::Key<'_> {
98    ///         &self.id
99    ///     }
100    ///
101    ///     id_upcast!();
102    /// }
103    ///
104    /// let map: IdOrdMap<Item> = IdOrdMap::new();
105    /// assert!(map.is_empty());
106    /// assert_eq!(map.len(), 0);
107    /// ```
108    #[inline]
109    pub const fn new() -> Self {
110        Self { items: ItemSet::new(), tables: IdOrdMapTables::new() }
111    }
112
113    /// Creates a new `IdOrdMap` with the given capacity.
114    ///
115    /// The capacity will be used to initialize the underlying item set.
116    ///
117    /// # Examples
118    ///
119    /// ```
120    /// use iddqd::{IdOrdItem, IdOrdMap, id_upcast};
121    ///
122    /// #[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
123    /// struct Item {
124    ///     id: String,
125    ///     value: u32,
126    /// }
127    ///
128    /// impl IdOrdItem for Item {
129    ///     type Key<'a> = &'a str;
130    ///
131    ///     fn key(&self) -> Self::Key<'_> {
132    ///         &self.id
133    ///     }
134    ///
135    ///     id_upcast!();
136    /// }
137    ///
138    /// let map: IdOrdMap<Item> = IdOrdMap::with_capacity(10);
139    /// assert!(map.capacity() >= 10);
140    /// assert!(map.is_empty());
141    /// ```
142    pub fn with_capacity(capacity: usize) -> Self {
143        Self {
144            items: ItemSet::with_capacity_in(capacity, global_alloc()),
145            tables: IdOrdMapTables::new(),
146        }
147    }
148
149    /// Returns the currently allocated capacity of the map.
150    ///
151    /// # Examples
152    ///
153    /// ```
154    /// use iddqd::{IdOrdItem, IdOrdMap, id_upcast};
155    ///
156    /// #[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
157    /// struct Item {
158    ///     id: String,
159    ///     value: u32,
160    /// }
161    ///
162    /// impl IdOrdItem for Item {
163    ///     type Key<'a> = &'a str;
164    ///
165    ///     fn key(&self) -> Self::Key<'_> {
166    ///         &self.id
167    ///     }
168    ///
169    ///     id_upcast!();
170    /// }
171    ///
172    /// let map: IdOrdMap<Item> = IdOrdMap::with_capacity(10);
173    /// assert!(map.capacity() >= 10);
174    /// ```
175    pub fn capacity(&self) -> usize {
176        // There's no self.tables.capacity.
177        self.items.capacity()
178    }
179
180    /// Constructs a new `IdOrdMap` from an iterator of values, rejecting
181    /// duplicates.
182    ///
183    /// To overwrite duplicates instead, use [`IdOrdMap::from_iter`].
184    ///
185    /// # Examples
186    ///
187    /// ```
188    /// use iddqd::{IdOrdItem, IdOrdMap, id_upcast};
189    ///
190    /// #[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
191    /// struct Item {
192    ///     id: String,
193    ///     value: u32,
194    /// }
195    ///
196    /// impl IdOrdItem for Item {
197    ///     type Key<'a> = &'a str;
198    ///
199    ///     fn key(&self) -> Self::Key<'_> {
200    ///         &self.id
201    ///     }
202    ///
203    ///     id_upcast!();
204    /// }
205    ///
206    /// let items = vec![
207    ///     Item { id: "foo".to_string(), value: 42 },
208    ///     Item { id: "bar".to_string(), value: 99 },
209    /// ];
210    ///
211    /// // Successful creation with unique keys
212    /// let map = IdOrdMap::from_iter_unique(items).unwrap();
213    /// assert_eq!(map.len(), 2);
214    /// assert_eq!(map.get("foo").unwrap().value, 42);
215    ///
216    /// // Error with duplicate keys
217    /// let duplicate_items = vec![
218    ///     Item { id: "foo".to_string(), value: 42 },
219    ///     Item { id: "foo".to_string(), value: 99 },
220    /// ];
221    /// assert!(IdOrdMap::from_iter_unique(duplicate_items).is_err());
222    /// ```
223    pub fn from_iter_unique<I: IntoIterator<Item = T>>(
224        iter: I,
225    ) -> Result<Self, DuplicateItem<T>> {
226        let iter = iter.into_iter();
227        let mut map = IdOrdMap::with_capacity(iter.size_hint().0);
228        for value in iter {
229            // It would be nice to use insert_unique here, but that would return
230            // a `DuplicateItem<T, &T>`, which can only be converted into an
231            // owned value if T: Clone. Doing this via the Entry API means we
232            // can return a `DuplicateItem<T>` without requiring T to be Clone.
233            match map.entry(value.key()) {
234                Entry::Occupied(entry) => {
235                    let duplicate = entry.remove();
236                    return Err(DuplicateItem::__internal_new(
237                        value,
238                        vec![duplicate],
239                    ));
240                }
241                Entry::Vacant(_) => {
242                    map.insert_known_unique_impl(value);
243                }
244            }
245        }
246
247        Ok(map)
248    }
249
250    /// Returns true if the map is empty.
251    ///
252    /// # Examples
253    ///
254    /// ```
255    /// use iddqd::{IdOrdItem, IdOrdMap, id_upcast};
256    ///
257    /// #[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
258    /// struct Item {
259    ///     id: String,
260    ///     value: u32,
261    /// }
262    ///
263    /// impl IdOrdItem for Item {
264    ///     type Key<'a> = &'a str;
265    ///
266    ///     fn key(&self) -> Self::Key<'_> {
267    ///         &self.id
268    ///     }
269    ///
270    ///     id_upcast!();
271    /// }
272    ///
273    /// let mut map = IdOrdMap::new();
274    /// assert!(map.is_empty());
275    ///
276    /// map.insert_unique(Item { id: "foo".to_string(), value: 42 }).unwrap();
277    /// assert!(!map.is_empty());
278    /// ```
279    #[inline]
280    pub fn is_empty(&self) -> bool {
281        self.items.is_empty()
282    }
283
284    /// Returns the number of items in the map.
285    ///
286    /// # Examples
287    ///
288    /// ```
289    /// use iddqd::{IdOrdItem, IdOrdMap, id_upcast};
290    ///
291    /// #[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
292    /// struct Item {
293    ///     id: String,
294    ///     value: u32,
295    /// }
296    ///
297    /// impl IdOrdItem for Item {
298    ///     type Key<'a> = &'a str;
299    ///
300    ///     fn key(&self) -> Self::Key<'_> {
301    ///         &self.id
302    ///     }
303    ///
304    ///     id_upcast!();
305    /// }
306    ///
307    /// let mut map = IdOrdMap::new();
308    /// assert_eq!(map.len(), 0);
309    ///
310    /// map.insert_unique(Item { id: "foo".to_string(), value: 42 }).unwrap();
311    /// map.insert_unique(Item { id: "bar".to_string(), value: 99 }).unwrap();
312    /// assert_eq!(map.len(), 2);
313    /// ```
314    #[inline]
315    pub fn len(&self) -> usize {
316        self.items.len()
317    }
318
319    /// Clears the map, removing all items.
320    ///
321    /// # Examples
322    ///
323    /// ```
324    /// use iddqd::{IdOrdItem, IdOrdMap, id_upcast};
325    ///
326    /// #[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
327    /// struct Item {
328    ///     id: String,
329    ///     value: u32,
330    /// }
331    ///
332    /// impl IdOrdItem for Item {
333    ///     type Key<'a> = &'a str;
334    ///
335    ///     fn key(&self) -> Self::Key<'_> {
336    ///         &self.id
337    ///     }
338    ///
339    ///     id_upcast!();
340    /// }
341    ///
342    /// let mut map = IdOrdMap::new();
343    /// map.insert_unique(Item { id: "foo".to_string(), value: 42 }).unwrap();
344    /// map.insert_unique(Item { id: "bar".to_string(), value: 99 }).unwrap();
345    /// assert_eq!(map.len(), 2);
346    ///
347    /// map.clear();
348    /// assert!(map.is_empty());
349    /// assert_eq!(map.len(), 0);
350    /// ```
351    pub fn clear(&mut self) {
352        // Clear the internal index before dropping items. This way, if a user
353        // `Drop` panics during `self.items.clear()`, `key_to_item` cannot retain
354        // indexes pointing to removed item slots.
355        self.tables.key_to_item.clear();
356        self.items.clear();
357    }
358
359    /// Reserves capacity for at least `additional` more elements to be inserted
360    /// in the `IdOrdMap`. The collection may reserve more space to
361    /// speculatively avoid frequent reallocations. After calling `reserve`,
362    /// capacity will be greater than or equal to `self.len() + additional`.
363    /// Does nothing if capacity is already sufficient.
364    ///
365    /// Note: This only reserves capacity in the item storage. The internal
366    /// `BTreeMap` used for key-to-item mapping does not support capacity
367    /// reservation.
368    ///
369    /// # Panics
370    ///
371    /// Panics if the new capacity overflows [`isize::MAX`] bytes, and
372    /// [`abort`]s the program in case of an allocation error.
373    ///
374    /// [`isize::MAX`]: https://doc.rust-lang.org/std/primitive.isize.html
375    /// [`abort`]: https://doc.rust-lang.org/alloc/alloc/fn.handle_alloc_error.html
376    ///
377    /// # Examples
378    ///
379    /// ```
380    /// use iddqd::{IdOrdItem, IdOrdMap, id_upcast};
381    ///
382    /// #[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
383    /// struct Item {
384    ///     id: String,
385    ///     value: u32,
386    /// }
387    ///
388    /// impl IdOrdItem for Item {
389    ///     type Key<'a> = &'a str;
390    ///     fn key(&self) -> Self::Key<'_> {
391    ///         &self.id
392    ///     }
393    ///     id_upcast!();
394    /// }
395    ///
396    /// let mut map: IdOrdMap<Item> = IdOrdMap::new();
397    /// map.reserve(100);
398    /// assert!(map.capacity() >= 100);
399    /// ```
400    pub fn reserve(&mut self, additional: usize) {
401        self.items.reserve(additional);
402    }
403
404    /// Shrinks the capacity of the map as much as possible. It will drop
405    /// down as much as possible while maintaining the internal rules
406    /// and possibly leaving some space in accordance with the resize policy.
407    ///
408    /// Note: This only shrinks the item storage capacity. The internal
409    /// `BTreeMap` used for key-to-item mapping does not support capacity
410    /// control.
411    ///
412    /// # Examples
413    ///
414    /// ```
415    /// use iddqd::{IdOrdItem, IdOrdMap, id_upcast};
416    ///
417    /// #[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
418    /// struct Item {
419    ///     id: String,
420    ///     value: u32,
421    /// }
422    ///
423    /// impl IdOrdItem for Item {
424    ///     type Key<'a> = &'a str;
425    ///     fn key(&self) -> Self::Key<'_> {
426    ///         &self.id
427    ///     }
428    ///     id_upcast!();
429    /// }
430    ///
431    /// let mut map: IdOrdMap<Item> = IdOrdMap::with_capacity(100);
432    /// map.insert_unique(Item { id: "foo".to_string(), value: 1 }).unwrap();
433    /// map.insert_unique(Item { id: "bar".to_string(), value: 2 }).unwrap();
434    /// assert!(map.capacity() >= 100);
435    /// map.shrink_to_fit();
436    /// assert!(map.capacity() >= 2);
437    /// ```
438    pub fn shrink_to_fit(&mut self) {
439        // Sequence this carefully.
440        //
441        // * First, compact the item set. This does not allocate through A
442        //   (it allocates a small remap buffer through the global allocator),
443        //   and returns a remapper.
444        // * Then, remap the table using the remapper.
445        // * Finally, shrink the capacity of the items. (BTreeMap has no
446        //   capacity to shrink.)
447        //
448        // An allocator panic during the capacity shrink leaves the table
449        // and items already in sync, because remap has already been
450        // committed.
451        let remap = self.items.compact();
452        if !remap.is_identity() {
453            self.tables.key_to_item.remap_indexes(&remap);
454        }
455        self.items.shrink_capacity_to_fit();
456    }
457
458    /// Shrinks the capacity of the map with a lower limit. It will drop
459    /// down no lower than the supplied limit while maintaining the internal
460    /// rules and possibly leaving some space in accordance with the resize
461    /// policy.
462    ///
463    /// If the current capacity is less than the lower limit, this is a no-op.
464    ///
465    /// Note: This only shrinks the item storage capacity. The internal
466    /// `BTreeMap` used for key-to-item mapping does not support capacity
467    /// control.
468    ///
469    /// # Examples
470    ///
471    /// ```
472    /// use iddqd::{IdOrdItem, IdOrdMap, id_upcast};
473    ///
474    /// #[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
475    /// struct Item {
476    ///     id: String,
477    ///     value: u32,
478    /// }
479    ///
480    /// impl IdOrdItem for Item {
481    ///     type Key<'a> = &'a str;
482    ///     fn key(&self) -> Self::Key<'_> {
483    ///         &self.id
484    ///     }
485    ///     id_upcast!();
486    /// }
487    ///
488    /// let mut map: IdOrdMap<Item> = IdOrdMap::with_capacity(100);
489    /// map.insert_unique(Item { id: "foo".to_string(), value: 1 }).unwrap();
490    /// map.insert_unique(Item { id: "bar".to_string(), value: 2 }).unwrap();
491    /// assert!(map.capacity() >= 100);
492    /// map.shrink_to(10);
493    /// assert!(map.capacity() >= 10);
494    /// map.shrink_to(0);
495    /// assert!(map.capacity() >= 2);
496    /// ```
497    pub fn shrink_to(&mut self, min_capacity: usize) {
498        // See `shrink_to_fit` for the rationale behind the sequence.
499        let remap = self.items.compact();
500        if !remap.is_identity() {
501            self.tables.key_to_item.remap_indexes(&remap);
502        }
503        self.items.shrink_capacity_to(min_capacity);
504    }
505
506    /// Iterates over the items in the map.
507    ///
508    /// Similar to [`BTreeMap`], the iteration is ordered by [`T::Key`].
509    ///
510    /// # Examples
511    ///
512    /// ```
513    /// use iddqd::{IdOrdItem, IdOrdMap, id_upcast};
514    ///
515    /// #[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
516    /// struct Item {
517    ///     id: String,
518    ///     value: u32,
519    /// }
520    ///
521    /// impl IdOrdItem for Item {
522    ///     type Key<'a> = &'a str;
523    ///
524    ///     fn key(&self) -> Self::Key<'_> {
525    ///         &self.id
526    ///     }
527    ///
528    ///     id_upcast!();
529    /// }
530    ///
531    /// let mut map = IdOrdMap::new();
532    /// map.insert_unique(Item { id: "charlie".to_string(), value: 30 }).unwrap();
533    /// map.insert_unique(Item { id: "alice".to_string(), value: 42 }).unwrap();
534    /// map.insert_unique(Item { id: "bob".to_string(), value: 99 }).unwrap();
535    ///
536    /// // Iteration is ordered by key
537    /// let mut iter = map.iter();
538    /// let item = iter.next().unwrap();
539    /// assert_eq!(item.id, "alice");
540    /// let item = iter.next().unwrap();
541    /// assert_eq!(item.id, "bob");
542    /// let item = iter.next().unwrap();
543    /// assert_eq!(item.id, "charlie");
544    /// assert!(iter.next().is_none());
545    /// ```
546    ///
547    /// [`BTreeMap`]: std::collections::BTreeMap
548    /// [`T::Key`]: crate::IdOrdItem::Key
549    #[inline]
550    pub fn iter(&self) -> Iter<'_, T> {
551        Iter::new(&self.items, &self.tables)
552    }
553
554    /// Iterates over the items in the map, allowing for mutation.
555    ///
556    /// Similar to [`BTreeMap`], the iteration is ordered by [`T::Key`].
557    ///
558    /// # Examples
559    ///
560    /// ```
561    /// use iddqd::{IdOrdItem, IdOrdMap, id_upcast};
562    ///
563    /// #[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
564    /// struct Item {
565    ///     id: String,
566    ///     value: u32,
567    /// }
568    ///
569    /// impl IdOrdItem for Item {
570    ///     type Key<'a> = &'a str;
571    ///
572    ///     fn key(&self) -> Self::Key<'_> {
573    ///         &self.id
574    ///     }
575    ///
576    ///     id_upcast!();
577    /// }
578    ///
579    /// let mut map = IdOrdMap::new();
580    /// map.insert_unique(Item { id: "foo".to_string(), value: 42 }).unwrap();
581    /// map.insert_unique(Item { id: "bar".to_string(), value: 99 }).unwrap();
582    ///
583    /// // Modify values through the mutable iterator
584    /// for mut item in map.iter_mut() {
585    ///     item.value *= 2;
586    /// }
587    ///
588    /// assert_eq!(map.get("foo").unwrap().value, 84);
589    /// assert_eq!(map.get("bar").unwrap().value, 198);
590    /// ```
591    ///
592    /// [`BTreeMap`]: std::collections::BTreeMap
593    /// [`T::Key`]: crate::IdOrdItem::Key
594    #[inline]
595    pub fn iter_mut<'a>(&'a mut self) -> IterMut<'a, T>
596    where
597        T::Key<'a>: Hash,
598    {
599        IterMut::new(&mut self.items, &self.tables)
600    }
601
602    /// Checks general invariants of the map.
603    ///
604    /// The code below always upholds these invariants, but it's useful to have
605    /// an explicit check for tests.
606    #[doc(hidden)]
607    pub fn validate(
608        &self,
609        compactness: ValidateCompact,
610        chaos: ValidateChaos,
611    ) -> Result<(), ValidationError>
612    where
613        T: fmt::Debug,
614    {
615        self.items.validate(compactness)?;
616        self.tables.validate(self.len(), compactness)?;
617
618        // Check that the indexes are all correct.
619
620        for (ix, item) in self.items.iter() {
621            let key = item.key();
622            let ix1 = match chaos {
623                ValidateChaos::Yes => {
624                    // Fall back to a linear search.
625                    self.linear_search_index(&key)
626                }
627                ValidateChaos::No => {
628                    // Use the B-Tree table to find the index.
629                    self.find_index(&key)
630                }
631            };
632            let Some(ix1) = ix1 else {
633                return Err(ValidationError::general(format!(
634                    "item at index {ix} has no key1 index"
635                )));
636            };
637
638            if ix1 != ix {
639                return Err(ValidationError::General(format!(
640                    "item at index {ix} has mismatched indexes: ix1: {ix1}",
641                )));
642            }
643        }
644
645        Ok(())
646    }
647
648    /// Checks the structural invariants of the map:
649    ///
650    /// * The item set is well-formed.
651    /// * The B-tree table holds exactly one entry per live item, with no
652    ///   duplicate `ItemIndex`es.
653    ///
654    /// Unlike [`validate`](Self::validate), this does not re-look-up keys
655    /// through the user `Ord`, so it holds regardless of whether that `Ord` is
656    /// lawful. A buggy comparator can desync the logical key to item mapping,
657    /// but it must never break these structural invariants! Doing so would
658    /// cause unsoundness, e.g. duplicate indexes enabling mutable aliasing.
659    #[doc(hidden)]
660    pub fn validate_structural(
661        &self,
662        compactness: ValidateCompact,
663    ) -> Result<(), ValidationError> {
664        self.items.validate(compactness)?;
665        self.tables.validate(self.len(), compactness)?;
666        Ok(())
667    }
668
669    /// Inserts a value into the set, returning an error if any duplicates were
670    /// added.
671    ///
672    /// # Examples
673    ///
674    /// ```
675    /// use iddqd::{IdOrdItem, IdOrdMap, id_upcast};
676    ///
677    /// #[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
678    /// struct Item {
679    ///     id: String,
680    ///     value: u32,
681    /// }
682    ///
683    /// impl IdOrdItem for Item {
684    ///     type Key<'a> = &'a str;
685    ///
686    ///     fn key(&self) -> Self::Key<'_> {
687    ///         &self.id
688    ///     }
689    ///
690    ///     id_upcast!();
691    /// }
692    ///
693    /// let mut map = IdOrdMap::new();
694    ///
695    /// // Successful insertion
696    /// assert!(
697    ///     map.insert_unique(Item { id: "foo".to_string(), value: 42 }).is_ok()
698    /// );
699    /// assert!(
700    ///     map.insert_unique(Item { id: "bar".to_string(), value: 99 }).is_ok()
701    /// );
702    ///
703    /// // Duplicate key
704    /// assert!(
705    ///     map.insert_unique(Item { id: "foo".to_string(), value: 100 }).is_err()
706    /// );
707    /// ```
708    pub fn insert_unique(
709        &mut self,
710        value: T,
711    ) -> Result<(), DuplicateItem<T, &T>> {
712        let _ = self.insert_unique_impl(value)?;
713        Ok(())
714    }
715
716    /// Inserts a value into the map, removing and returning the conflicting
717    /// item, if any.
718    ///
719    /// # Examples
720    ///
721    /// ```
722    /// use iddqd::{IdOrdItem, IdOrdMap, id_upcast};
723    ///
724    /// #[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
725    /// struct Item {
726    ///     id: String,
727    ///     value: u32,
728    /// }
729    ///
730    /// impl IdOrdItem for Item {
731    ///     type Key<'a> = &'a str;
732    ///
733    ///     fn key(&self) -> Self::Key<'_> {
734    ///         &self.id
735    ///     }
736    ///
737    ///     id_upcast!();
738    /// }
739    ///
740    /// let mut map = IdOrdMap::new();
741    ///
742    /// // First insertion - no conflict
743    /// let old = map.insert_overwrite(Item { id: "foo".to_string(), value: 42 });
744    /// assert!(old.is_none());
745    ///
746    /// // Overwrite existing key - returns old value
747    /// let old = map.insert_overwrite(Item { id: "foo".to_string(), value: 99 });
748    /// assert!(old.is_some());
749    /// assert_eq!(old.unwrap().value, 42);
750    ///
751    /// // Verify new value is in the map
752    /// assert_eq!(map.get("foo").unwrap().value, 99);
753    /// ```
754    #[doc(alias = "insert")]
755    pub fn insert_overwrite(&mut self, value: T) -> Option<T> {
756        // Go through the entry API so all user code is called before any table
757        // mutation. A panic in user code therefore leaves the map in its
758        // pre-call state.
759        //
760        // In the vacant case, the Entry lookup has already established that the
761        // key is unique. Calling `vacant.insert_entry` would route back through
762        // `insert_unique_impl` and check for duplicates again, while
763        // `vacant.insert` would also create a `RefMut` and hash the key. We use
764        // `insert_known_unique_impl` instead, which avoids both.
765        match self.entry(value.key()) {
766            Entry::Occupied(mut occupied) => Some(occupied.insert(value)),
767            Entry::Vacant(_) => {
768                self.insert_known_unique_impl(value);
769                None
770            }
771        }
772    }
773
774    /// Returns true if the map contains the given `key`.
775    ///
776    /// # Examples
777    ///
778    /// ```
779    /// use iddqd::{IdOrdItem, IdOrdMap, id_upcast};
780    ///
781    /// #[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
782    /// struct Item {
783    ///     id: String,
784    ///     value: u32,
785    /// }
786    ///
787    /// impl IdOrdItem for Item {
788    ///     type Key<'a> = &'a str;
789    ///
790    ///     fn key(&self) -> Self::Key<'_> {
791    ///         &self.id
792    ///     }
793    ///
794    ///     id_upcast!();
795    /// }
796    ///
797    /// let mut map = IdOrdMap::new();
798    /// map.insert_unique(Item { id: "foo".to_string(), value: 42 }).unwrap();
799    ///
800    /// assert!(map.contains_key("foo"));
801    /// assert!(!map.contains_key("bar"));
802    /// ```
803    pub fn contains_key<'a, Q>(&'a self, key: &Q) -> bool
804    where
805        Q: ?Sized + Comparable<T::Key<'a>>,
806    {
807        self.find_index(key).is_some()
808    }
809
810    /// Gets a reference to the value associated with the given `key`.
811    ///
812    /// # Examples
813    ///
814    /// ```
815    /// use iddqd::{IdOrdItem, IdOrdMap, id_upcast};
816    ///
817    /// #[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
818    /// struct Item {
819    ///     id: String,
820    ///     value: u32,
821    /// }
822    ///
823    /// impl IdOrdItem for Item {
824    ///     type Key<'a> = &'a str;
825    ///
826    ///     fn key(&self) -> Self::Key<'_> {
827    ///         &self.id
828    ///     }
829    ///
830    ///     id_upcast!();
831    /// }
832    ///
833    /// let mut map = IdOrdMap::new();
834    /// map.insert_unique(Item { id: "foo".to_string(), value: 42 }).unwrap();
835    ///
836    /// assert_eq!(map.get("foo").unwrap().value, 42);
837    /// assert!(map.get("bar").is_none());
838    /// ```
839    pub fn get<'a, Q>(&'a self, key: &Q) -> Option<&'a T>
840    where
841        Q: ?Sized + Comparable<T::Key<'a>>,
842    {
843        self.find(key)
844    }
845
846    /// Gets a mutable reference to the item associated with the given `key`.
847    ///
848    /// # Examples
849    ///
850    /// ```
851    /// use iddqd::{IdOrdItem, IdOrdMap, id_upcast};
852    ///
853    /// #[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
854    /// struct Item {
855    ///     id: String,
856    ///     value: u32,
857    /// }
858    ///
859    /// impl IdOrdItem for Item {
860    ///     type Key<'a> = &'a str;
861    ///
862    ///     fn key(&self) -> Self::Key<'_> {
863    ///         &self.id
864    ///     }
865    ///
866    ///     id_upcast!();
867    /// }
868    ///
869    /// let mut map = IdOrdMap::new();
870    /// map.insert_unique(Item { id: "foo".to_string(), value: 42 }).unwrap();
871    ///
872    /// if let Some(mut item) = map.get_mut("foo") {
873    ///     item.value = 99;
874    /// }
875    ///
876    /// assert_eq!(map.get("foo").unwrap().value, 99);
877    /// ```
878    pub fn get_mut<'a, Q>(&'a mut self, key: &Q) -> Option<RefMut<'a, T>>
879    where
880        Q: ?Sized + Comparable<T::Key<'a>>,
881        T::Key<'a>: Hash,
882    {
883        let (dormant_map, index) = {
884            let (map, dormant_map) = DormantMutRef::new(self);
885            let index = map.find_index(key)?;
886            (dormant_map, index)
887        };
888
889        // SAFETY: `map` is not used after this point.
890        let awakened_map = unsafe { dormant_map.awaken() };
891        let item = &mut awakened_map.items[index];
892        let state = awakened_map.tables.state().clone();
893        let (hash, dormant) = {
894            let (item, dormant) = DormantMutRef::new(item);
895            let hash = awakened_map.tables.make_hash(item);
896            (hash, dormant)
897        };
898
899        // SAFETY: the original item is not used after this point.
900        let item = unsafe { dormant.awaken() };
901        Some(RefMut::new(state, hash, item))
902    }
903
904    /// Removes an item from the map by its `key`.
905    ///
906    /// # Examples
907    ///
908    /// ```
909    /// use iddqd::{IdOrdItem, IdOrdMap, id_upcast};
910    ///
911    /// #[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
912    /// struct Item {
913    ///     id: String,
914    ///     value: u32,
915    /// }
916    ///
917    /// impl IdOrdItem for Item {
918    ///     type Key<'a> = &'a str;
919    ///
920    ///     fn key(&self) -> Self::Key<'_> {
921    ///         &self.id
922    ///     }
923    ///
924    ///     id_upcast!();
925    /// }
926    ///
927    /// let mut map = IdOrdMap::new();
928    /// map.insert_unique(Item { id: "foo".to_string(), value: 42 }).unwrap();
929    ///
930    /// let removed = map.remove("foo");
931    /// assert!(removed.is_some());
932    /// assert_eq!(removed.unwrap().value, 42);
933    /// assert!(map.is_empty());
934    ///
935    /// // Removing a non-existent key returns None
936    /// assert!(map.remove("bar").is_none());
937    /// ```
938    pub fn remove<'a, Q>(&'a mut self, key: &Q) -> Option<T>
939    where
940        Q: ?Sized + Comparable<T::Key<'a>>,
941    {
942        let (dormant_map, remove_index) = {
943            let (map, dormant_map) = DormantMutRef::new(self);
944            let remove_index = map.find_index(key)?;
945            (dormant_map, remove_index)
946        };
947
948        // SAFETY: `map` is not used after this point.
949        let awakened_map = unsafe { dormant_map.awaken() };
950        awakened_map.remove_by_index(remove_index)
951    }
952
953    /// Retrieves an entry by its `key`.
954    ///
955    /// Due to borrow checker limitations, this always accepts an owned key rather
956    /// than a borrowed form.
957    ///
958    /// # Examples
959    ///
960    /// ```
961    /// use iddqd::{IdOrdItem, IdOrdMap, id_ord_map, id_upcast};
962    ///
963    /// #[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
964    /// struct Item {
965    ///     id: String,
966    ///     value: u32,
967    /// }
968    ///
969    /// impl IdOrdItem for Item {
970    ///     type Key<'a> = &'a str;
971    ///
972    ///     fn key(&self) -> Self::Key<'_> {
973    ///         &self.id
974    ///     }
975    ///
976    ///     id_upcast!();
977    /// }
978    ///
979    /// let mut map = IdOrdMap::new();
980    ///
981    /// // Insert via vacant entry
982    /// match map.entry("foo") {
983    ///     id_ord_map::Entry::Vacant(entry) => {
984    ///         entry.insert(Item { id: "foo".to_string(), value: 42 });
985    ///     }
986    ///     id_ord_map::Entry::Occupied(_) => {}
987    /// }
988    ///
989    /// // Update via occupied entry
990    /// match map.entry("foo") {
991    ///     id_ord_map::Entry::Occupied(mut entry) => {
992    ///         entry.get_mut().value = 99;
993    ///     }
994    ///     id_ord_map::Entry::Vacant(_) => {}
995    /// }
996    ///
997    /// assert_eq!(map.get("foo").unwrap().value, 99);
998    /// ```
999    pub fn entry<'a>(&'a mut self, key: T::Key<'_>) -> Entry<'a, T> {
1000        // Why does this always take an owned key? Well, it would seem like we
1001        // should be able to pass in any Q that is equivalent. That results in
1002        // *this* code compiling fine, but callers have trouble using it because
1003        // the borrow checker believes the keys are borrowed for the full 'a
1004        // rather than a shorter lifetime.
1005        //
1006        // By accepting owned keys, we can use the upcast functions to convert
1007        // them to a shorter lifetime (so this function accepts T::Key<'_>
1008        // rather than T::Key<'a>).
1009        //
1010        // Really, the solution here is to allow GATs to require covariant
1011        // parameters. If that were allowed, the borrow checker should be able
1012        // to figure out that keys don't need to be borrowed for the full 'a,
1013        // just for some shorter lifetime.
1014        let (map, dormant_map) = DormantMutRef::new(self);
1015        let key = T::upcast_key(key);
1016        {
1017            // index is explicitly typed to show that it has a trivial Drop impl
1018            // that doesn't capture anything from map.
1019            let index: Option<ItemIndex> = map
1020                .tables
1021                .key_to_item
1022                .find_index(&key, |index| map.items[index].key());
1023            if let Some(index) = index {
1024                drop(key);
1025                return Entry::Occupied(
1026                    // SAFETY: `map` is not used after this point.
1027                    unsafe { OccupiedEntry::new(dormant_map, index) },
1028                );
1029            }
1030        }
1031        Entry::Vacant(
1032            // SAFETY: `map` is not used after this point.
1033            unsafe { VacantEntry::new(dormant_map) },
1034        )
1035    }
1036
1037    /// Returns the first item in the map. The key of this item is the minimum
1038    /// key in the map.
1039    ///
1040    /// # Examples
1041    ///
1042    /// ```
1043    /// use iddqd::{IdOrdItem, IdOrdMap, id_upcast};
1044    ///
1045    /// #[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
1046    /// struct Item {
1047    ///     id: String,
1048    ///     value: u32,
1049    /// }
1050    ///
1051    /// impl IdOrdItem for Item {
1052    ///     type Key<'a> = &'a str;
1053    ///
1054    ///     fn key(&self) -> Self::Key<'_> {
1055    ///         &self.id
1056    ///     }
1057    ///
1058    ///     id_upcast!();
1059    /// }
1060    ///
1061    /// let mut map = IdOrdMap::new();
1062    /// map.insert_unique(Item { id: "charlie".to_string(), value: 30 }).unwrap();
1063    /// map.insert_unique(Item { id: "alice".to_string(), value: 42 }).unwrap();
1064    /// map.insert_unique(Item { id: "bob".to_string(), value: 99 }).unwrap();
1065    ///
1066    /// // First item has the minimum key.
1067    /// let first = map.first().unwrap();
1068    /// assert_eq!(first.id, "alice");
1069    /// assert_eq!(first.value, 42);
1070    ///
1071    /// // Empty map returns None.
1072    /// let empty_map: IdOrdMap<Item> = IdOrdMap::new();
1073    /// assert!(empty_map.first().is_none());
1074    /// ```
1075    #[inline]
1076    pub fn first(&self) -> Option<&T> {
1077        self.tables.key_to_item.first().map(|index| &self.items[index])
1078    }
1079
1080    /// Returns the first entry in the map for in-place manipulation. The key of
1081    /// this entry is the minimum key in the map.
1082    ///
1083    /// # Examples
1084    ///
1085    /// ```
1086    /// use iddqd::{IdOrdItem, IdOrdMap, id_upcast};
1087    ///
1088    /// #[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
1089    /// struct Item {
1090    ///     id: String,
1091    ///     value: u32,
1092    /// }
1093    ///
1094    /// impl IdOrdItem for Item {
1095    ///     type Key<'a> = &'a str;
1096    ///
1097    ///     fn key(&self) -> Self::Key<'_> {
1098    ///         &self.id
1099    ///     }
1100    ///
1101    ///     id_upcast!();
1102    /// }
1103    ///
1104    /// let mut map = IdOrdMap::new();
1105    /// map.insert_unique(Item { id: "charlie".to_string(), value: 30 }).unwrap();
1106    /// map.insert_unique(Item { id: "alice".to_string(), value: 42 }).unwrap();
1107    /// map.insert_unique(Item { id: "bob".to_string(), value: 99 }).unwrap();
1108    ///
1109    /// // Modify the first entry.
1110    /// if let Some(mut entry) = map.first_entry() {
1111    ///     entry.get_mut().value = 100;
1112    /// }
1113    ///
1114    /// assert_eq!(map.get("alice").unwrap().value, 100);
1115    /// ```
1116    pub fn first_entry(&mut self) -> Option<OccupiedEntry<'_, T>> {
1117        let index = self.tables.key_to_item.first()?;
1118        let (_, dormant_map) = DormantMutRef::new(self);
1119        Some(
1120            // SAFETY: `map` is dropped immediately while creating the
1121            // DormantMutRef.
1122            unsafe { OccupiedEntry::new(dormant_map, index) },
1123        )
1124    }
1125
1126    /// Removes and returns the first element in the map. The key of this
1127    /// element is the minimum key in the map.
1128    ///
1129    /// # Examples
1130    ///
1131    /// ```
1132    /// use iddqd::{IdOrdItem, IdOrdMap, id_upcast};
1133    ///
1134    /// #[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
1135    /// struct Item {
1136    ///     id: String,
1137    ///     value: u32,
1138    /// }
1139    ///
1140    /// impl IdOrdItem for Item {
1141    ///     type Key<'a> = &'a str;
1142    ///
1143    ///     fn key(&self) -> Self::Key<'_> {
1144    ///         &self.id
1145    ///     }
1146    ///
1147    ///     id_upcast!();
1148    /// }
1149    ///
1150    /// let mut map = IdOrdMap::new();
1151    /// map.insert_unique(Item { id: "charlie".to_string(), value: 30 }).unwrap();
1152    /// map.insert_unique(Item { id: "alice".to_string(), value: 42 }).unwrap();
1153    /// map.insert_unique(Item { id: "bob".to_string(), value: 99 }).unwrap();
1154    ///
1155    /// // Remove the first element.
1156    /// let first = map.pop_first().unwrap();
1157    /// assert_eq!(first.id, "alice");
1158    /// assert_eq!(first.value, 42);
1159    /// assert_eq!(map.len(), 2);
1160    ///
1161    /// // Remove the next element.
1162    /// let first = map.pop_first().unwrap();
1163    /// assert_eq!(first.id, "bob");
1164    ///
1165    /// // Empty map returns None.
1166    /// map.pop_first();
1167    /// assert!(map.pop_first().is_none());
1168    /// ```
1169    pub fn pop_first(&mut self) -> Option<T> {
1170        let index = self.tables.key_to_item.first()?;
1171        self.remove_by_index(index)
1172    }
1173
1174    /// Returns the last item in the map. The key of this item is the maximum
1175    /// key in the map.
1176    ///
1177    /// # Examples
1178    ///
1179    /// ```
1180    /// use iddqd::{IdOrdItem, IdOrdMap, id_upcast};
1181    ///
1182    /// #[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
1183    /// struct Item {
1184    ///     id: String,
1185    ///     value: u32,
1186    /// }
1187    ///
1188    /// impl IdOrdItem for Item {
1189    ///     type Key<'a> = &'a str;
1190    ///
1191    ///     fn key(&self) -> Self::Key<'_> {
1192    ///         &self.id
1193    ///     }
1194    ///
1195    ///     id_upcast!();
1196    /// }
1197    ///
1198    /// let mut map = IdOrdMap::new();
1199    /// map.insert_unique(Item { id: "charlie".to_string(), value: 30 }).unwrap();
1200    /// map.insert_unique(Item { id: "alice".to_string(), value: 42 }).unwrap();
1201    /// map.insert_unique(Item { id: "bob".to_string(), value: 99 }).unwrap();
1202    ///
1203    /// // Last item has the maximum key.
1204    /// let last = map.last().unwrap();
1205    /// assert_eq!(last.id, "charlie");
1206    /// assert_eq!(last.value, 30);
1207    ///
1208    /// // Empty map returns None.
1209    /// let empty_map: IdOrdMap<Item> = IdOrdMap::new();
1210    /// assert!(empty_map.last().is_none());
1211    /// ```
1212    #[inline]
1213    pub fn last(&self) -> Option<&T> {
1214        self.tables.key_to_item.last().map(|index| &self.items[index])
1215    }
1216
1217    /// Returns the last entry in the map for in-place manipulation. The key of
1218    /// this entry is the maximum key in the map.
1219    ///
1220    /// # Examples
1221    ///
1222    /// ```
1223    /// use iddqd::{IdOrdItem, IdOrdMap, id_upcast};
1224    ///
1225    /// #[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
1226    /// struct Item {
1227    ///     id: String,
1228    ///     value: u32,
1229    /// }
1230    ///
1231    /// impl IdOrdItem for Item {
1232    ///     type Key<'a> = &'a str;
1233    ///
1234    ///     fn key(&self) -> Self::Key<'_> {
1235    ///         &self.id
1236    ///     }
1237    ///
1238    ///     id_upcast!();
1239    /// }
1240    ///
1241    /// let mut map = IdOrdMap::new();
1242    /// map.insert_unique(Item { id: "charlie".to_string(), value: 30 }).unwrap();
1243    /// map.insert_unique(Item { id: "alice".to_string(), value: 42 }).unwrap();
1244    /// map.insert_unique(Item { id: "bob".to_string(), value: 99 }).unwrap();
1245    ///
1246    /// // Modify the last entry.
1247    /// if let Some(mut entry) = map.last_entry() {
1248    ///     entry.get_mut().value = 200;
1249    /// }
1250    ///
1251    /// assert_eq!(map.get("charlie").unwrap().value, 200);
1252    /// ```
1253    pub fn last_entry(&mut self) -> Option<OccupiedEntry<'_, T>> {
1254        let index = self.tables.key_to_item.last()?;
1255        let (_, dormant_map) = DormantMutRef::new(self);
1256        Some(
1257            // SAFETY: `map` is dropped immediately while creating the
1258            // DormantMutRef.
1259            unsafe { OccupiedEntry::new(dormant_map, index) },
1260        )
1261    }
1262
1263    /// Removes and returns the last element in the map. The key of this
1264    /// element is the maximum key in the map.
1265    ///
1266    /// # Examples
1267    ///
1268    /// ```
1269    /// use iddqd::{IdOrdItem, IdOrdMap, id_upcast};
1270    ///
1271    /// #[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
1272    /// struct Item {
1273    ///     id: String,
1274    ///     value: u32,
1275    /// }
1276    ///
1277    /// impl IdOrdItem for Item {
1278    ///     type Key<'a> = &'a str;
1279    ///
1280    ///     fn key(&self) -> Self::Key<'_> {
1281    ///         &self.id
1282    ///     }
1283    ///
1284    ///     id_upcast!();
1285    /// }
1286    ///
1287    /// let mut map = IdOrdMap::new();
1288    /// map.insert_unique(Item { id: "charlie".to_string(), value: 30 }).unwrap();
1289    /// map.insert_unique(Item { id: "alice".to_string(), value: 42 }).unwrap();
1290    /// map.insert_unique(Item { id: "bob".to_string(), value: 99 }).unwrap();
1291    ///
1292    /// // Remove the last element.
1293    /// let last = map.pop_last().unwrap();
1294    /// assert_eq!(last.id, "charlie");
1295    /// assert_eq!(last.value, 30);
1296    /// assert_eq!(map.len(), 2);
1297    ///
1298    /// // Remove the next element.
1299    /// let last = map.pop_last().unwrap();
1300    /// assert_eq!(last.id, "bob");
1301    ///
1302    /// // Empty map returns None.
1303    /// map.pop_last();
1304    /// assert!(map.pop_last().is_none());
1305    /// ```
1306    pub fn pop_last(&mut self) -> Option<T> {
1307        let index = self.tables.key_to_item.last()?;
1308        self.remove_by_index(index)
1309    }
1310
1311    /// Retains only the elements specified by the predicate.
1312    ///
1313    /// In other words, remove all items `T` for which `f(RefMut<T>)` returns
1314    /// false. The elements are visited in ascending key order.
1315    ///
1316    /// # Examples
1317    ///
1318    /// ```
1319    /// use iddqd::{IdOrdItem, IdOrdMap, id_upcast};
1320    ///
1321    /// #[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
1322    /// struct Item {
1323    ///     id: String,
1324    ///     value: u32,
1325    /// }
1326    ///
1327    /// impl IdOrdItem for Item {
1328    ///     type Key<'a> = &'a str;
1329    ///
1330    ///     fn key(&self) -> Self::Key<'_> {
1331    ///         &self.id
1332    ///     }
1333    ///
1334    ///     id_upcast!();
1335    /// }
1336    ///
1337    /// let mut map = IdOrdMap::new();
1338    /// map.insert_unique(Item { id: "foo".to_string(), value: 42 }).unwrap();
1339    /// map.insert_unique(Item { id: "bar".to_string(), value: 20 }).unwrap();
1340    /// map.insert_unique(Item { id: "baz".to_string(), value: 99 }).unwrap();
1341    ///
1342    /// // Retain only items where value is greater than 30
1343    /// map.retain(|item| item.value > 30);
1344    ///
1345    /// assert_eq!(map.len(), 2);
1346    /// assert_eq!(map.get("foo").unwrap().value, 42);
1347    /// assert_eq!(map.get("baz").unwrap().value, 99);
1348    /// assert!(map.get("bar").is_none());
1349    /// ```
1350    pub fn retain<'a, F>(&'a mut self, mut f: F)
1351    where
1352        F: for<'b> FnMut(RefMut<'b, T>) -> bool,
1353        T::Key<'a>: Hash,
1354    {
1355        let hash_state = self.tables.state().clone();
1356        let (_, mut dormant_items) = DormantMutRef::new(&mut self.items);
1357        let mut removed_item = None;
1358
1359        self.tables.key_to_item.retain(|index| {
1360            // Drop the previously-removed item here, at the top of the next
1361            // iteration.
1362            //
1363            // By now, the prior `key_to_item` entry has been erased, so if
1364            // `drop` below panics, `key_to_item` and `items` remain in sync.
1365            // Dropping the item at the end of the prior iteration would
1366            // unwind before the BTree dropped the entry, leaving
1367            // `key_to_item` pointing at a slot we already removed from
1368            // `items`.
1369            drop(removed_item.take());
1370
1371            let (item, dormant_items) = {
1372                // SAFETY: All uses of `items` ended in the previous iteration.
1373                let items = unsafe { dormant_items.reborrow() };
1374                let (items, dormant_items) = DormantMutRef::new(items);
1375                let item: &'a mut T = items
1376                    .get_mut(index)
1377                    .expect("all indexes are present in self.items");
1378                (item, dormant_items)
1379            };
1380
1381            let (hash, dormant_item) = {
1382                let (item, dormant_item): (&'a mut T, _) =
1383                    DormantMutRef::new(item);
1384                // Use T::key(item) rather than item.key() to force the key
1385                // trait function to be called for T rather than &mut T.
1386                let key = T::key(item);
1387                let hash = hash_state.hash_one(key);
1388                (MapHash::new(hash), dormant_item)
1389            };
1390
1391            let retain = {
1392                // SAFETY: The original item is no longer used after the second
1393                // block above. dormant_items, from which item is derived, is
1394                // currently dormant.
1395                let item = unsafe { dormant_item.awaken() };
1396
1397                let ref_mut = RefMut::new(hash_state.clone(), hash, item);
1398                f(ref_mut)
1399            };
1400
1401            if retain {
1402                true
1403            } else {
1404                // SAFETY: The original items is no longer used after the first
1405                // block above, and item + dormant_item have been dropped after
1406                // being used above.
1407                let items = unsafe { dormant_items.awaken() };
1408                removed_item = Some(
1409                    items
1410                        .remove(index)
1411                        .expect("all indexes are present in self.items"),
1412                );
1413                false
1414            }
1415        });
1416
1417        // Anything in `removed_item` is implicitly dropped now.
1418    }
1419
1420    fn find<'a, Q>(&'a self, k: &Q) -> Option<&'a T>
1421    where
1422        Q: ?Sized + Comparable<T::Key<'a>>,
1423    {
1424        self.find_index(k).map(|ix| &self.items[ix])
1425    }
1426
1427    fn linear_search_index<'a, Q>(&'a self, k: &Q) -> Option<ItemIndex>
1428    where
1429        Q: ?Sized + Ord + Equivalent<T::Key<'a>>,
1430    {
1431        self.items.iter().find_map(|(index, item)| {
1432            (k.equivalent(&item.key())).then_some(index)
1433        })
1434    }
1435
1436    fn find_index<'a, Q>(&'a self, k: &Q) -> Option<ItemIndex>
1437    where
1438        Q: ?Sized + Comparable<T::Key<'a>>,
1439    {
1440        self.tables.key_to_item.find_index(k, |index| self.items[index].key())
1441    }
1442
1443    pub(super) fn get_by_index(&self, index: ItemIndex) -> Option<&T> {
1444        self.items.get(index)
1445    }
1446
1447    pub(super) fn get_by_index_mut<'a>(
1448        &'a mut self,
1449        index: ItemIndex,
1450    ) -> Option<RefMut<'a, T>>
1451    where
1452        T::Key<'a>: Hash,
1453    {
1454        let state = self.tables.state().clone();
1455        let (hash, dormant) = {
1456            let item: &'a mut T = self.items.get_mut(index)?;
1457            let (item, dormant) = DormantMutRef::new(item);
1458            let hash = self.tables.make_hash(item);
1459            (hash, dormant)
1460        };
1461
1462        // SAFETY: item is no longer used after the above point.
1463        let item = unsafe { dormant.awaken() };
1464        Some(RefMut::new(state, hash, item))
1465    }
1466
1467    pub(super) fn insert_unique_impl(
1468        &mut self,
1469        value: T,
1470    ) -> Result<ItemIndex, DuplicateItem<T, &T>> {
1471        let mut duplicates = BTreeSet::new();
1472
1473        // Check for duplicates *before* inserting the new item, because we
1474        // don't want to partially insert the new item and then have to roll
1475        // back.
1476        //
1477        // Scope this `key` to avoid lifetime issues.
1478        {
1479            let key = value.key();
1480            if let Some(index) = self
1481                .tables
1482                .key_to_item
1483                .find_index(&key, |index| self.items[index].key())
1484            {
1485                duplicates.insert(index);
1486            }
1487
1488            if !duplicates.is_empty() {
1489                drop(key);
1490                return Err(DuplicateItem::__internal_new(
1491                    value,
1492                    duplicates.iter().map(|ix| &self.items[*ix]).collect(),
1493                ));
1494            }
1495        }
1496
1497        Ok(self.insert_known_unique_impl(value))
1498    }
1499
1500    /// Inserts `value` without checking for duplicates.
1501    ///
1502    /// Only call this after verifying that `value` does not conflict with any
1503    /// existing item. Callers that haven't determined uniqueness should use
1504    /// `insert_unique_impl` instead.
1505    fn insert_known_unique_impl(&mut self, value: T) -> ItemIndex {
1506        // Take the `GrowHandle` now, after the caller has checked that `value`
1507        // does not conflict with any existing item, but before the B-tree
1508        // mutation. With this approach, a panic from `assert_can_grow` (which
1509        // means that the map is full) cannot leave the B-tree referencing an
1510        // index that was never assigned to an item.
1511        //
1512        // The handle holds `&mut self.items` and is consumed by
1513        // `GrowHandle::insert`, so the type system enforces that we cannot
1514        // reach the push without the cap check.
1515        let grow_handle = self.items.assert_can_grow();
1516        let next_index = grow_handle.next_index();
1517        let key = value.key();
1518        let insert =
1519            self.tables.key_to_item.prepare_insert(next_index, &key, |index| {
1520                grow_handle[index].key()
1521            });
1522        drop(key);
1523
1524        // Commit the item set push *before* the B-tree commit.
1525        //
1526        // This matches the *HashMap insert order and gives stronger
1527        // panic-safety against allocator panics:
1528        //
1529        // * If `grow_handle.insert` panics on allocation (what this code does
1530        //   first), the `insert` handle is dropped without committing, so
1531        //   neither the item set nor the B-tree is mutated.
1532        // * If `insert.insert` panics on allocation (a B-tree node split is the
1533        //   only way this is possible), the item set holds an orphan slot, but it's
1534        //   invisible to every map operation because no B-tree entry points to
1535        //   it.
1536        //
1537        // This isn't an issue today because the global allocator aborts on
1538        // panic, but this is defensively coded. (But in any case this is quite
1539        // theoretical -- most Rust code in the wild is likely not prepared for
1540        // allocator panics that don't abort.)
1541        grow_handle.insert(value);
1542        insert.insert();
1543
1544        next_index
1545    }
1546
1547    pub(super) fn remove_by_index(
1548        &mut self,
1549        remove_index: ItemIndex,
1550    ) -> Option<T> {
1551        // For panic safety, read the key while self.items still holds the slot,
1552        // then locate the B-tree entry before mutating self.items.
1553        //
1554        // `BTreeMap::entry` is panic-safe under user-`Ord` panics, since
1555        // comparator panics during the internal binary search abort the lookup
1556        // without modifying the tree. (This is not a documented guarantee, but
1557        // really the only reasonable way to implement a panic-safe B-tree map.)
1558        // This means that a panic at this point leaves both items and the
1559        // B-tree unmodified. After the entry has been located, `drop(key)` can
1560        // run user code, so it must happen before the B-tree or item slot is
1561        // mutated.
1562        //
1563        // If BTreeMap::entry returns normally but misses due to already-broken
1564        // tree ordering, the prepared remove falls back to exact-index cleanup
1565        // before this item slot can be reused.
1566        let key = self.items.get(remove_index)?.key();
1567        let remove = self.tables.key_to_item.prepare_remove(
1568            remove_index,
1569            &key,
1570            |index| self.items[index].key(),
1571        );
1572        drop(key);
1573        if !remove.remove() {
1574            self.tables.key_to_item.remove_exact(remove_index);
1575        }
1576        Some(
1577            self.items
1578                .remove(remove_index)
1579                .expect("items[remove_index] was Occupied above"),
1580        )
1581    }
1582
1583    pub(super) fn replace_at_index(&mut self, index: ItemIndex, value: T) -> T {
1584        // We check the key before removing it, to avoid leaving the map in an
1585        // inconsistent state.
1586        let old_key =
1587            self.get_by_index(index).expect("index is known to be valid").key();
1588        if T::upcast_key(old_key) != value.key() {
1589            panic!(
1590                "must insert a value with \
1591                 the same key used to create the entry"
1592            );
1593        }
1594
1595        // Now that we know the key is the same, we can replace the value
1596        // directly without needing to tweak any tables.
1597        self.items.replace(index, value)
1598    }
1599}
1600
1601impl<'a, T: IdOrdItem> fmt::Debug for IdOrdMap<T>
1602where
1603    T: fmt::Debug,
1604    T::Key<'a>: fmt::Debug,
1605    T: 'a,
1606{
1607    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1608        let mut map = f.debug_map();
1609
1610        for item in self.iter() {
1611            let key = item.key();
1612
1613            // SAFETY:
1614            //
1615            // * Lifetime extension: for a type T and two lifetime params 'a and
1616            //   'b, T<'a> and T<'b> aren't guaranteed to have the same layout,
1617            //   but (a) that is true today and (b) it would be shocking and
1618            //   break half the Rust ecosystem if that were to change in the
1619            //   future.
1620            // * We only use key within the scope of this block before immediately
1621            //   dropping it. In particular, map.entry calls key.fmt() without
1622            //   holding a reference to it.
1623            let key: T::Key<'a> =
1624                unsafe { core::mem::transmute::<T::Key<'_>, T::Key<'a>>(key) };
1625
1626            map.entry(&key, &item);
1627        }
1628        map.finish()
1629    }
1630}
1631
1632impl<T: IdOrdItem + PartialEq> PartialEq for IdOrdMap<T> {
1633    fn eq(&self, other: &Self) -> bool {
1634        // Items are stored in sorted order, so we can just walk over both
1635        // iterators.
1636        if self.items.len() != other.items.len() {
1637            return false;
1638        }
1639
1640        self.iter().zip(other.iter()).all(|(item1, item2)| {
1641            // Check that the items are equal.
1642            item1 == item2
1643        })
1644    }
1645}
1646
1647// The Eq bound on T ensures that the IdOrdMap forms an equivalence class.
1648impl<T: IdOrdItem + Eq> Eq for IdOrdMap<T> {}
1649
1650/// The `Extend` implementation overwrites duplicates. In the future, there will
1651/// also be an `extend_unique` method that will return an error.
1652impl<T: IdOrdItem> Extend<T> for IdOrdMap<T> {
1653    fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
1654        // Keys may already be present in the map, or multiple times in the
1655        // iterator. Reserve the entire hint lower bound if the map is empty.
1656        // Otherwise reserve half the hint (rounded up), so the map will only
1657        // resize twice in the worst case.
1658        let iter = iter.into_iter();
1659        let reserve = if self.is_empty() {
1660            iter.size_hint().0
1661        } else {
1662            iter.size_hint().0.div_ceil(2)
1663        };
1664        self.reserve(reserve);
1665        for item in iter {
1666            self.insert_overwrite(item);
1667        }
1668    }
1669}
1670
1671impl<'a, T: IdOrdItem> IntoIterator for &'a IdOrdMap<T> {
1672    type Item = &'a T;
1673    type IntoIter = Iter<'a, T>;
1674
1675    #[inline]
1676    fn into_iter(self) -> Self::IntoIter {
1677        self.iter()
1678    }
1679}
1680
1681impl<'a, T: IdOrdItem> IntoIterator for &'a mut IdOrdMap<T>
1682where
1683    T::Key<'a>: Hash,
1684{
1685    type Item = RefMut<'a, T>;
1686    type IntoIter = IterMut<'a, T>;
1687
1688    #[inline]
1689    fn into_iter(self) -> Self::IntoIter {
1690        self.iter_mut()
1691    }
1692}
1693
1694impl<T: IdOrdItem> IntoIterator for IdOrdMap<T> {
1695    type Item = T;
1696    type IntoIter = IntoIter<T>;
1697
1698    #[inline]
1699    fn into_iter(self) -> Self::IntoIter {
1700        IntoIter::new(self.items, self.tables)
1701    }
1702}
1703
1704/// The `FromIterator` implementation for `IdOrdMap` overwrites duplicate
1705/// items.
1706///
1707/// To reject duplicates, use [`IdOrdMap::from_iter_unique`].
1708///
1709/// # Examples
1710///
1711/// ```
1712/// use iddqd::{IdOrdItem, IdOrdMap, id_upcast};
1713///
1714/// #[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
1715/// struct Item {
1716///     id: String,
1717///     value: u32,
1718/// }
1719///
1720/// impl IdOrdItem for Item {
1721///     type Key<'a> = &'a str;
1722///
1723///     fn key(&self) -> Self::Key<'_> {
1724///         &self.id
1725///     }
1726///
1727///     id_upcast!();
1728/// }
1729///
1730/// let items = vec![
1731///     Item { id: "foo".to_string(), value: 42 },
1732///     Item { id: "bar".to_string(), value: 20 },
1733///     Item { id: "foo".to_string(), value: 100 }, // duplicate key, overwrites
1734/// ];
1735///
1736/// let map: IdOrdMap<Item> = items.into_iter().collect();
1737/// assert_eq!(map.len(), 2);
1738/// assert_eq!(map.get("foo").unwrap().value, 100); // last value wins
1739/// assert_eq!(map.get("bar").unwrap().value, 20);
1740/// ```
1741impl<T: IdOrdItem> FromIterator<T> for IdOrdMap<T> {
1742    fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
1743        let mut map = IdOrdMap::new();
1744        map.extend(iter);
1745        map
1746    }
1747}