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