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    /// Inserts a value into the set, returning an error if any duplicates were
648    /// added.
649    ///
650    /// # Examples
651    ///
652    /// ```
653    /// use iddqd::{IdOrdItem, IdOrdMap, id_upcast};
654    ///
655    /// #[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
656    /// struct Item {
657    ///     id: String,
658    ///     value: u32,
659    /// }
660    ///
661    /// impl IdOrdItem for Item {
662    ///     type Key<'a> = &'a str;
663    ///
664    ///     fn key(&self) -> Self::Key<'_> {
665    ///         &self.id
666    ///     }
667    ///
668    ///     id_upcast!();
669    /// }
670    ///
671    /// let mut map = IdOrdMap::new();
672    ///
673    /// // Successful insertion
674    /// assert!(
675    ///     map.insert_unique(Item { id: "foo".to_string(), value: 42 }).is_ok()
676    /// );
677    /// assert!(
678    ///     map.insert_unique(Item { id: "bar".to_string(), value: 99 }).is_ok()
679    /// );
680    ///
681    /// // Duplicate key
682    /// assert!(
683    ///     map.insert_unique(Item { id: "foo".to_string(), value: 100 }).is_err()
684    /// );
685    /// ```
686    pub fn insert_unique(
687        &mut self,
688        value: T,
689    ) -> Result<(), DuplicateItem<T, &T>> {
690        let _ = self.insert_unique_impl(value)?;
691        Ok(())
692    }
693
694    /// Inserts a value into the map, removing and returning the conflicting
695    /// item, if any.
696    ///
697    /// # Examples
698    ///
699    /// ```
700    /// use iddqd::{IdOrdItem, IdOrdMap, id_upcast};
701    ///
702    /// #[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
703    /// struct Item {
704    ///     id: String,
705    ///     value: u32,
706    /// }
707    ///
708    /// impl IdOrdItem for Item {
709    ///     type Key<'a> = &'a str;
710    ///
711    ///     fn key(&self) -> Self::Key<'_> {
712    ///         &self.id
713    ///     }
714    ///
715    ///     id_upcast!();
716    /// }
717    ///
718    /// let mut map = IdOrdMap::new();
719    ///
720    /// // First insertion - no conflict
721    /// let old = map.insert_overwrite(Item { id: "foo".to_string(), value: 42 });
722    /// assert!(old.is_none());
723    ///
724    /// // Overwrite existing key - returns old value
725    /// let old = map.insert_overwrite(Item { id: "foo".to_string(), value: 99 });
726    /// assert!(old.is_some());
727    /// assert_eq!(old.unwrap().value, 42);
728    ///
729    /// // Verify new value is in the map
730    /// assert_eq!(map.get("foo").unwrap().value, 99);
731    /// ```
732    #[doc(alias = "insert")]
733    pub fn insert_overwrite(&mut self, value: T) -> Option<T> {
734        // Go through the entry API so all user code is called before any table
735        // mutation. A panic in user code therefore leaves the map in its
736        // pre-call state.
737        //
738        // We use `vacant.insert_entry` rather than `vacant.insert` to avoid
739        // creating a `RefMut`, which would (unnecessarily) re-hash the key
740        // after the mutation when that `RefMut` is created.
741        match self.entry(value.key()) {
742            Entry::Occupied(mut occupied) => Some(occupied.insert(value)),
743            Entry::Vacant(vacant) => {
744                vacant.insert_entry(value);
745                None
746            }
747        }
748    }
749
750    /// Returns true if the map contains the given `key`.
751    ///
752    /// # Examples
753    ///
754    /// ```
755    /// use iddqd::{IdOrdItem, IdOrdMap, id_upcast};
756    ///
757    /// #[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
758    /// struct Item {
759    ///     id: String,
760    ///     value: u32,
761    /// }
762    ///
763    /// impl IdOrdItem for Item {
764    ///     type Key<'a> = &'a str;
765    ///
766    ///     fn key(&self) -> Self::Key<'_> {
767    ///         &self.id
768    ///     }
769    ///
770    ///     id_upcast!();
771    /// }
772    ///
773    /// let mut map = IdOrdMap::new();
774    /// map.insert_unique(Item { id: "foo".to_string(), value: 42 }).unwrap();
775    ///
776    /// assert!(map.contains_key("foo"));
777    /// assert!(!map.contains_key("bar"));
778    /// ```
779    pub fn contains_key<'a, Q>(&'a self, key: &Q) -> bool
780    where
781        Q: ?Sized + Comparable<T::Key<'a>>,
782    {
783        self.find_index(key).is_some()
784    }
785
786    /// Gets a reference to the value associated with the given `key`.
787    ///
788    /// # Examples
789    ///
790    /// ```
791    /// use iddqd::{IdOrdItem, IdOrdMap, id_upcast};
792    ///
793    /// #[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
794    /// struct Item {
795    ///     id: String,
796    ///     value: u32,
797    /// }
798    ///
799    /// impl IdOrdItem for Item {
800    ///     type Key<'a> = &'a str;
801    ///
802    ///     fn key(&self) -> Self::Key<'_> {
803    ///         &self.id
804    ///     }
805    ///
806    ///     id_upcast!();
807    /// }
808    ///
809    /// let mut map = IdOrdMap::new();
810    /// map.insert_unique(Item { id: "foo".to_string(), value: 42 }).unwrap();
811    ///
812    /// assert_eq!(map.get("foo").unwrap().value, 42);
813    /// assert!(map.get("bar").is_none());
814    /// ```
815    pub fn get<'a, Q>(&'a self, key: &Q) -> Option<&'a T>
816    where
817        Q: ?Sized + Comparable<T::Key<'a>>,
818    {
819        self.find(key)
820    }
821
822    /// Gets a mutable reference to the item associated with the given `key`.
823    ///
824    /// # Examples
825    ///
826    /// ```
827    /// use iddqd::{IdOrdItem, IdOrdMap, id_upcast};
828    ///
829    /// #[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
830    /// struct Item {
831    ///     id: String,
832    ///     value: u32,
833    /// }
834    ///
835    /// impl IdOrdItem for Item {
836    ///     type Key<'a> = &'a str;
837    ///
838    ///     fn key(&self) -> Self::Key<'_> {
839    ///         &self.id
840    ///     }
841    ///
842    ///     id_upcast!();
843    /// }
844    ///
845    /// let mut map = IdOrdMap::new();
846    /// map.insert_unique(Item { id: "foo".to_string(), value: 42 }).unwrap();
847    ///
848    /// if let Some(mut item) = map.get_mut("foo") {
849    ///     item.value = 99;
850    /// }
851    ///
852    /// assert_eq!(map.get("foo").unwrap().value, 99);
853    /// ```
854    pub fn get_mut<'a, Q>(&'a mut self, key: &Q) -> Option<RefMut<'a, T>>
855    where
856        Q: ?Sized + Comparable<T::Key<'a>>,
857        T::Key<'a>: Hash,
858    {
859        let (dormant_map, index) = {
860            let (map, dormant_map) = DormantMutRef::new(self);
861            let index = map.find_index(key)?;
862            (dormant_map, index)
863        };
864
865        // SAFETY: `map` is not used after this point.
866        let awakened_map = unsafe { dormant_map.awaken() };
867        let item = &mut awakened_map.items[index];
868        let state = awakened_map.tables.state().clone();
869        let (hash, dormant) = {
870            let (item, dormant) = DormantMutRef::new(item);
871            let hash = awakened_map.tables.make_hash(item);
872            (hash, dormant)
873        };
874
875        // SAFETY: the original item is not used after this point.
876        let item = unsafe { dormant.awaken() };
877        Some(RefMut::new(state, hash, item))
878    }
879
880    /// Removes an item from the map by its `key`.
881    ///
882    /// # Examples
883    ///
884    /// ```
885    /// use iddqd::{IdOrdItem, IdOrdMap, id_upcast};
886    ///
887    /// #[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
888    /// struct Item {
889    ///     id: String,
890    ///     value: u32,
891    /// }
892    ///
893    /// impl IdOrdItem for Item {
894    ///     type Key<'a> = &'a str;
895    ///
896    ///     fn key(&self) -> Self::Key<'_> {
897    ///         &self.id
898    ///     }
899    ///
900    ///     id_upcast!();
901    /// }
902    ///
903    /// let mut map = IdOrdMap::new();
904    /// map.insert_unique(Item { id: "foo".to_string(), value: 42 }).unwrap();
905    ///
906    /// let removed = map.remove("foo");
907    /// assert!(removed.is_some());
908    /// assert_eq!(removed.unwrap().value, 42);
909    /// assert!(map.is_empty());
910    ///
911    /// // Removing a non-existent key returns None
912    /// assert!(map.remove("bar").is_none());
913    /// ```
914    pub fn remove<'a, Q>(&'a mut self, key: &Q) -> Option<T>
915    where
916        Q: ?Sized + Comparable<T::Key<'a>>,
917    {
918        let (dormant_map, remove_index) = {
919            let (map, dormant_map) = DormantMutRef::new(self);
920            let remove_index = map.find_index(key)?;
921            (dormant_map, remove_index)
922        };
923
924        // SAFETY: `map` is not used after this point.
925        let awakened_map = unsafe { dormant_map.awaken() };
926        awakened_map.remove_by_index(remove_index)
927    }
928
929    /// Retrieves an entry by its `key`.
930    ///
931    /// Due to borrow checker limitations, this always accepts an owned key rather
932    /// than a borrowed form.
933    ///
934    /// # Examples
935    ///
936    /// ```
937    /// use iddqd::{IdOrdItem, IdOrdMap, id_ord_map, id_upcast};
938    ///
939    /// #[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
940    /// struct Item {
941    ///     id: String,
942    ///     value: u32,
943    /// }
944    ///
945    /// impl IdOrdItem for Item {
946    ///     type Key<'a> = &'a str;
947    ///
948    ///     fn key(&self) -> Self::Key<'_> {
949    ///         &self.id
950    ///     }
951    ///
952    ///     id_upcast!();
953    /// }
954    ///
955    /// let mut map = IdOrdMap::new();
956    ///
957    /// // Insert via vacant entry
958    /// match map.entry("foo") {
959    ///     id_ord_map::Entry::Vacant(entry) => {
960    ///         entry.insert(Item { id: "foo".to_string(), value: 42 });
961    ///     }
962    ///     id_ord_map::Entry::Occupied(_) => {}
963    /// }
964    ///
965    /// // Update via occupied entry
966    /// match map.entry("foo") {
967    ///     id_ord_map::Entry::Occupied(mut entry) => {
968    ///         entry.get_mut().value = 99;
969    ///     }
970    ///     id_ord_map::Entry::Vacant(_) => {}
971    /// }
972    ///
973    /// assert_eq!(map.get("foo").unwrap().value, 99);
974    /// ```
975    pub fn entry<'a>(&'a mut self, key: T::Key<'_>) -> Entry<'a, T> {
976        // Why does this always take an owned key? Well, it would seem like we
977        // should be able to pass in any Q that is equivalent. That results in
978        // *this* code compiling fine, but callers have trouble using it because
979        // the borrow checker believes the keys are borrowed for the full 'a
980        // rather than a shorter lifetime.
981        //
982        // By accepting owned keys, we can use the upcast functions to convert
983        // them to a shorter lifetime (so this function accepts T::Key<'_>
984        // rather than T::Key<'a>).
985        //
986        // Really, the solution here is to allow GATs to require covariant
987        // parameters. If that were allowed, the borrow checker should be able
988        // to figure out that keys don't need to be borrowed for the full 'a,
989        // just for some shorter lifetime.
990        let (map, dormant_map) = DormantMutRef::new(self);
991        let key = T::upcast_key(key);
992        {
993            // index is explicitly typed to show that it has a trivial Drop impl
994            // that doesn't capture anything from map.
995            let index: Option<ItemIndex> = map
996                .tables
997                .key_to_item
998                .find_index(&key, |index| map.items[index].key());
999            if let Some(index) = index {
1000                drop(key);
1001                return Entry::Occupied(
1002                    // SAFETY: `map` is not used after this point.
1003                    unsafe { OccupiedEntry::new(dormant_map, index) },
1004                );
1005            }
1006        }
1007        Entry::Vacant(
1008            // SAFETY: `map` is not used after this point.
1009            unsafe { VacantEntry::new(dormant_map) },
1010        )
1011    }
1012
1013    /// Returns the first item in the map. The key of this item is the minimum
1014    /// key in the map.
1015    ///
1016    /// # Examples
1017    ///
1018    /// ```
1019    /// use iddqd::{IdOrdItem, IdOrdMap, id_upcast};
1020    ///
1021    /// #[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
1022    /// struct Item {
1023    ///     id: String,
1024    ///     value: u32,
1025    /// }
1026    ///
1027    /// impl IdOrdItem for Item {
1028    ///     type Key<'a> = &'a str;
1029    ///
1030    ///     fn key(&self) -> Self::Key<'_> {
1031    ///         &self.id
1032    ///     }
1033    ///
1034    ///     id_upcast!();
1035    /// }
1036    ///
1037    /// let mut map = IdOrdMap::new();
1038    /// map.insert_unique(Item { id: "charlie".to_string(), value: 30 }).unwrap();
1039    /// map.insert_unique(Item { id: "alice".to_string(), value: 42 }).unwrap();
1040    /// map.insert_unique(Item { id: "bob".to_string(), value: 99 }).unwrap();
1041    ///
1042    /// // First item has the minimum key.
1043    /// let first = map.first().unwrap();
1044    /// assert_eq!(first.id, "alice");
1045    /// assert_eq!(first.value, 42);
1046    ///
1047    /// // Empty map returns None.
1048    /// let empty_map: IdOrdMap<Item> = IdOrdMap::new();
1049    /// assert!(empty_map.first().is_none());
1050    /// ```
1051    #[inline]
1052    pub fn first(&self) -> Option<&T> {
1053        self.tables.key_to_item.first().map(|index| &self.items[index])
1054    }
1055
1056    /// Returns the first entry in the map for in-place manipulation. The key of
1057    /// this entry is the minimum key in the map.
1058    ///
1059    /// # Examples
1060    ///
1061    /// ```
1062    /// use iddqd::{IdOrdItem, IdOrdMap, id_upcast};
1063    ///
1064    /// #[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
1065    /// struct Item {
1066    ///     id: String,
1067    ///     value: u32,
1068    /// }
1069    ///
1070    /// impl IdOrdItem for Item {
1071    ///     type Key<'a> = &'a str;
1072    ///
1073    ///     fn key(&self) -> Self::Key<'_> {
1074    ///         &self.id
1075    ///     }
1076    ///
1077    ///     id_upcast!();
1078    /// }
1079    ///
1080    /// let mut map = IdOrdMap::new();
1081    /// map.insert_unique(Item { id: "charlie".to_string(), value: 30 }).unwrap();
1082    /// map.insert_unique(Item { id: "alice".to_string(), value: 42 }).unwrap();
1083    /// map.insert_unique(Item { id: "bob".to_string(), value: 99 }).unwrap();
1084    ///
1085    /// // Modify the first entry.
1086    /// if let Some(mut entry) = map.first_entry() {
1087    ///     entry.get_mut().value = 100;
1088    /// }
1089    ///
1090    /// assert_eq!(map.get("alice").unwrap().value, 100);
1091    /// ```
1092    pub fn first_entry(&mut self) -> Option<OccupiedEntry<'_, T>> {
1093        let index = self.tables.key_to_item.first()?;
1094        let (_, dormant_map) = DormantMutRef::new(self);
1095        Some(
1096            // SAFETY: `map` is dropped immediately while creating the
1097            // DormantMutRef.
1098            unsafe { OccupiedEntry::new(dormant_map, index) },
1099        )
1100    }
1101
1102    /// Removes and returns the first element in the map. The key of this
1103    /// element is the minimum key in the map.
1104    ///
1105    /// # Examples
1106    ///
1107    /// ```
1108    /// use iddqd::{IdOrdItem, IdOrdMap, id_upcast};
1109    ///
1110    /// #[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
1111    /// struct Item {
1112    ///     id: String,
1113    ///     value: u32,
1114    /// }
1115    ///
1116    /// impl IdOrdItem for Item {
1117    ///     type Key<'a> = &'a str;
1118    ///
1119    ///     fn key(&self) -> Self::Key<'_> {
1120    ///         &self.id
1121    ///     }
1122    ///
1123    ///     id_upcast!();
1124    /// }
1125    ///
1126    /// let mut map = IdOrdMap::new();
1127    /// map.insert_unique(Item { id: "charlie".to_string(), value: 30 }).unwrap();
1128    /// map.insert_unique(Item { id: "alice".to_string(), value: 42 }).unwrap();
1129    /// map.insert_unique(Item { id: "bob".to_string(), value: 99 }).unwrap();
1130    ///
1131    /// // Remove the first element.
1132    /// let first = map.pop_first().unwrap();
1133    /// assert_eq!(first.id, "alice");
1134    /// assert_eq!(first.value, 42);
1135    /// assert_eq!(map.len(), 2);
1136    ///
1137    /// // Remove the next element.
1138    /// let first = map.pop_first().unwrap();
1139    /// assert_eq!(first.id, "bob");
1140    ///
1141    /// // Empty map returns None.
1142    /// map.pop_first();
1143    /// assert!(map.pop_first().is_none());
1144    /// ```
1145    pub fn pop_first(&mut self) -> Option<T> {
1146        let index = self.tables.key_to_item.first()?;
1147        self.remove_by_index(index)
1148    }
1149
1150    /// Returns the last item in the map. The key of this item is the maximum
1151    /// key in the map.
1152    ///
1153    /// # Examples
1154    ///
1155    /// ```
1156    /// use iddqd::{IdOrdItem, IdOrdMap, id_upcast};
1157    ///
1158    /// #[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
1159    /// struct Item {
1160    ///     id: String,
1161    ///     value: u32,
1162    /// }
1163    ///
1164    /// impl IdOrdItem for Item {
1165    ///     type Key<'a> = &'a str;
1166    ///
1167    ///     fn key(&self) -> Self::Key<'_> {
1168    ///         &self.id
1169    ///     }
1170    ///
1171    ///     id_upcast!();
1172    /// }
1173    ///
1174    /// let mut map = IdOrdMap::new();
1175    /// map.insert_unique(Item { id: "charlie".to_string(), value: 30 }).unwrap();
1176    /// map.insert_unique(Item { id: "alice".to_string(), value: 42 }).unwrap();
1177    /// map.insert_unique(Item { id: "bob".to_string(), value: 99 }).unwrap();
1178    ///
1179    /// // Last item has the maximum key.
1180    /// let last = map.last().unwrap();
1181    /// assert_eq!(last.id, "charlie");
1182    /// assert_eq!(last.value, 30);
1183    ///
1184    /// // Empty map returns None.
1185    /// let empty_map: IdOrdMap<Item> = IdOrdMap::new();
1186    /// assert!(empty_map.last().is_none());
1187    /// ```
1188    #[inline]
1189    pub fn last(&self) -> Option<&T> {
1190        self.tables.key_to_item.last().map(|index| &self.items[index])
1191    }
1192
1193    /// Returns the last entry in the map for in-place manipulation. The key of
1194    /// this entry is the maximum key in the map.
1195    ///
1196    /// # Examples
1197    ///
1198    /// ```
1199    /// use iddqd::{IdOrdItem, IdOrdMap, id_upcast};
1200    ///
1201    /// #[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
1202    /// struct Item {
1203    ///     id: String,
1204    ///     value: u32,
1205    /// }
1206    ///
1207    /// impl IdOrdItem for Item {
1208    ///     type Key<'a> = &'a str;
1209    ///
1210    ///     fn key(&self) -> Self::Key<'_> {
1211    ///         &self.id
1212    ///     }
1213    ///
1214    ///     id_upcast!();
1215    /// }
1216    ///
1217    /// let mut map = IdOrdMap::new();
1218    /// map.insert_unique(Item { id: "charlie".to_string(), value: 30 }).unwrap();
1219    /// map.insert_unique(Item { id: "alice".to_string(), value: 42 }).unwrap();
1220    /// map.insert_unique(Item { id: "bob".to_string(), value: 99 }).unwrap();
1221    ///
1222    /// // Modify the last entry.
1223    /// if let Some(mut entry) = map.last_entry() {
1224    ///     entry.get_mut().value = 200;
1225    /// }
1226    ///
1227    /// assert_eq!(map.get("charlie").unwrap().value, 200);
1228    /// ```
1229    pub fn last_entry(&mut self) -> Option<OccupiedEntry<'_, T>> {
1230        let index = self.tables.key_to_item.last()?;
1231        let (_, dormant_map) = DormantMutRef::new(self);
1232        Some(
1233            // SAFETY: `map` is dropped immediately while creating the
1234            // DormantMutRef.
1235            unsafe { OccupiedEntry::new(dormant_map, index) },
1236        )
1237    }
1238
1239    /// Removes and returns the last element in the map. The key of this
1240    /// element is the maximum key in the map.
1241    ///
1242    /// # Examples
1243    ///
1244    /// ```
1245    /// use iddqd::{IdOrdItem, IdOrdMap, id_upcast};
1246    ///
1247    /// #[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
1248    /// struct Item {
1249    ///     id: String,
1250    ///     value: u32,
1251    /// }
1252    ///
1253    /// impl IdOrdItem for Item {
1254    ///     type Key<'a> = &'a str;
1255    ///
1256    ///     fn key(&self) -> Self::Key<'_> {
1257    ///         &self.id
1258    ///     }
1259    ///
1260    ///     id_upcast!();
1261    /// }
1262    ///
1263    /// let mut map = IdOrdMap::new();
1264    /// map.insert_unique(Item { id: "charlie".to_string(), value: 30 }).unwrap();
1265    /// map.insert_unique(Item { id: "alice".to_string(), value: 42 }).unwrap();
1266    /// map.insert_unique(Item { id: "bob".to_string(), value: 99 }).unwrap();
1267    ///
1268    /// // Remove the last element.
1269    /// let last = map.pop_last().unwrap();
1270    /// assert_eq!(last.id, "charlie");
1271    /// assert_eq!(last.value, 30);
1272    /// assert_eq!(map.len(), 2);
1273    ///
1274    /// // Remove the next element.
1275    /// let last = map.pop_last().unwrap();
1276    /// assert_eq!(last.id, "bob");
1277    ///
1278    /// // Empty map returns None.
1279    /// map.pop_last();
1280    /// assert!(map.pop_last().is_none());
1281    /// ```
1282    pub fn pop_last(&mut self) -> Option<T> {
1283        let index = self.tables.key_to_item.last()?;
1284        self.remove_by_index(index)
1285    }
1286
1287    /// Retains only the elements specified by the predicate.
1288    ///
1289    /// In other words, remove all items `T` for which `f(RefMut<T>)` returns
1290    /// false. The elements are visited in ascending key order.
1291    ///
1292    /// # Examples
1293    ///
1294    /// ```
1295    /// use iddqd::{IdOrdItem, IdOrdMap, id_upcast};
1296    ///
1297    /// #[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
1298    /// struct Item {
1299    ///     id: String,
1300    ///     value: u32,
1301    /// }
1302    ///
1303    /// impl IdOrdItem for Item {
1304    ///     type Key<'a> = &'a str;
1305    ///
1306    ///     fn key(&self) -> Self::Key<'_> {
1307    ///         &self.id
1308    ///     }
1309    ///
1310    ///     id_upcast!();
1311    /// }
1312    ///
1313    /// let mut map = IdOrdMap::new();
1314    /// map.insert_unique(Item { id: "foo".to_string(), value: 42 }).unwrap();
1315    /// map.insert_unique(Item { id: "bar".to_string(), value: 20 }).unwrap();
1316    /// map.insert_unique(Item { id: "baz".to_string(), value: 99 }).unwrap();
1317    ///
1318    /// // Retain only items where value is greater than 30
1319    /// map.retain(|item| item.value > 30);
1320    ///
1321    /// assert_eq!(map.len(), 2);
1322    /// assert_eq!(map.get("foo").unwrap().value, 42);
1323    /// assert_eq!(map.get("baz").unwrap().value, 99);
1324    /// assert!(map.get("bar").is_none());
1325    /// ```
1326    pub fn retain<'a, F>(&'a mut self, mut f: F)
1327    where
1328        F: for<'b> FnMut(RefMut<'b, T>) -> bool,
1329        T::Key<'a>: Hash,
1330    {
1331        let hash_state = self.tables.state().clone();
1332        let (_, mut dormant_items) = DormantMutRef::new(&mut self.items);
1333        let mut removed_item = None;
1334
1335        self.tables.key_to_item.retain(|index| {
1336            // Drop the previously-removed item here, at the top of the next
1337            // iteration.
1338            //
1339            // By now, the prior `key_to_item` entry has been erased, so if
1340            // `drop` below panics, `key_to_item` and `items` remain in sync.
1341            // Dropping the item at the end of the prior iteration would
1342            // unwind before the BTree dropped the entry, leaving
1343            // `key_to_item` pointing at a slot we already removed from
1344            // `items`.
1345            drop(removed_item.take());
1346
1347            let (item, dormant_items) = {
1348                // SAFETY: All uses of `items` ended in the previous iteration.
1349                let items = unsafe { dormant_items.reborrow() };
1350                let (items, dormant_items) = DormantMutRef::new(items);
1351                let item: &'a mut T = items
1352                    .get_mut(index)
1353                    .expect("all indexes are present in self.items");
1354                (item, dormant_items)
1355            };
1356
1357            let (hash, dormant_item) = {
1358                let (item, dormant_item): (&'a mut T, _) =
1359                    DormantMutRef::new(item);
1360                // Use T::key(item) rather than item.key() to force the key
1361                // trait function to be called for T rather than &mut T.
1362                let key = T::key(item);
1363                let hash = hash_state.hash_one(key);
1364                (MapHash::new(hash), dormant_item)
1365            };
1366
1367            let retain = {
1368                // SAFETY: The original item is no longer used after the second
1369                // block above. dormant_items, from which item is derived, is
1370                // currently dormant.
1371                let item = unsafe { dormant_item.awaken() };
1372
1373                let ref_mut = RefMut::new(hash_state.clone(), hash, item);
1374                f(ref_mut)
1375            };
1376
1377            if retain {
1378                true
1379            } else {
1380                // SAFETY: The original items is no longer used after the first
1381                // block above, and item + dormant_item have been dropped after
1382                // being used above.
1383                let items = unsafe { dormant_items.awaken() };
1384                removed_item = Some(
1385                    items
1386                        .remove(index)
1387                        .expect("all indexes are present in self.items"),
1388                );
1389                false
1390            }
1391        });
1392
1393        // Anything in `removed_item` is implicitly dropped now.
1394    }
1395
1396    fn find<'a, Q>(&'a self, k: &Q) -> Option<&'a T>
1397    where
1398        Q: ?Sized + Comparable<T::Key<'a>>,
1399    {
1400        self.find_index(k).map(|ix| &self.items[ix])
1401    }
1402
1403    fn linear_search_index<'a, Q>(&'a self, k: &Q) -> Option<ItemIndex>
1404    where
1405        Q: ?Sized + Ord + Equivalent<T::Key<'a>>,
1406    {
1407        self.items.iter().find_map(|(index, item)| {
1408            (k.equivalent(&item.key())).then_some(index)
1409        })
1410    }
1411
1412    fn find_index<'a, Q>(&'a self, k: &Q) -> Option<ItemIndex>
1413    where
1414        Q: ?Sized + Comparable<T::Key<'a>>,
1415    {
1416        self.tables.key_to_item.find_index(k, |index| self.items[index].key())
1417    }
1418
1419    pub(super) fn get_by_index(&self, index: ItemIndex) -> Option<&T> {
1420        self.items.get(index)
1421    }
1422
1423    pub(super) fn get_by_index_mut<'a>(
1424        &'a mut self,
1425        index: ItemIndex,
1426    ) -> Option<RefMut<'a, T>>
1427    where
1428        T::Key<'a>: Hash,
1429    {
1430        let state = self.tables.state().clone();
1431        let (hash, dormant) = {
1432            let item: &'a mut T = self.items.get_mut(index)?;
1433            let (item, dormant) = DormantMutRef::new(item);
1434            let hash = self.tables.make_hash(item);
1435            (hash, dormant)
1436        };
1437
1438        // SAFETY: item is no longer used after the above point.
1439        let item = unsafe { dormant.awaken() };
1440        Some(RefMut::new(state, hash, item))
1441    }
1442
1443    pub(super) fn insert_unique_impl(
1444        &mut self,
1445        value: T,
1446    ) -> Result<ItemIndex, DuplicateItem<T, &T>> {
1447        let mut duplicates = BTreeSet::new();
1448
1449        // Check for duplicates *before* inserting the new item, because we
1450        // don't want to partially insert the new item and then have to roll
1451        // back.
1452        //
1453        // Scope this `key` to avoid lifetime issues.
1454        {
1455            let key = value.key();
1456            if let Some(index) = self
1457                .tables
1458                .key_to_item
1459                .find_index(&key, |index| self.items[index].key())
1460            {
1461                duplicates.insert(index);
1462            }
1463
1464            if !duplicates.is_empty() {
1465                drop(key);
1466                return Err(DuplicateItem::__internal_new(
1467                    value,
1468                    duplicates.iter().map(|ix| &self.items[*ix]).collect(),
1469                ));
1470            }
1471        }
1472
1473        // Take the `GrowHandle` after the read-only duplicate check but before
1474        // the B-tree mutation. With this approach, a panic from
1475        // `assert_can_grow` (which means that the map is full) cannot leave the
1476        // B-tree referencing an index that was never assigned to an item.
1477        //
1478        // The handle holds `&mut self.items` and is consumed by
1479        // `GrowHandle::insert`, so the type system enforces that we cannot
1480        // reach the push without the cap check.
1481        let grow_handle = self.items.assert_can_grow();
1482        let next_index = grow_handle.next_index();
1483        let key = value.key();
1484        let insert =
1485            self.tables.key_to_item.prepare_insert(next_index, &key, |index| {
1486                grow_handle[index].key()
1487            });
1488        drop(key);
1489
1490        // Commit the item set push *before* the B-tree commit.
1491        //
1492        // This matches the *HashMap insert order and gives stronger
1493        // panic-safety against allocator panics:
1494        //
1495        // * If `grow_handle.insert` panics on allocation (what this code does
1496        //   first), the `insert` handle is dropped without committing, so
1497        //   neither the item set nor the B-tree is mutated.
1498        // * If `insert.insert` panics on allocation (a B-tree node split is the
1499        //   only way this is possible), the item set holds an orphan slot, but it's
1500        //   invisible to every map operation because no B-tree entry points to
1501        //   it.
1502        //
1503        // This isn't an issue today because the global allocator aborts on
1504        // panic, but this is defensively coded. (But in any case this is quite
1505        // theoretical -- most Rust code in the wild is likely not prepared for
1506        // allocator panics that don't abort.)
1507        grow_handle.insert(value);
1508        insert.insert();
1509
1510        Ok(next_index)
1511    }
1512
1513    pub(super) fn remove_by_index(
1514        &mut self,
1515        remove_index: ItemIndex,
1516    ) -> Option<T> {
1517        // For panic safety, read the key while self.items still holds the slot,
1518        // then locate the B-tree entry before mutating self.items.
1519        //
1520        // `BTreeMap::entry` is panic-safe under user-`Ord` panics, since
1521        // comparator panics during the internal binary search abort the lookup
1522        // without modifying the tree. (This is not a documented guarantee, but
1523        // really the only reasonable way to implement a panic-safe B-tree map.)
1524        // This means that a panic at this point leaves both items and the
1525        // B-tree unmodified. After the entry has been located, `drop(key)` can
1526        // run user code, so it must happen before the B-tree or item slot is
1527        // mutated.
1528        //
1529        // If BTreeMap::entry returns normally but misses due to already-broken
1530        // tree ordering, the prepared remove falls back to exact-index cleanup
1531        // before this item slot can be reused.
1532        let key = self.items.get(remove_index)?.key();
1533        let remove = self.tables.key_to_item.prepare_remove(
1534            remove_index,
1535            &key,
1536            |index| self.items[index].key(),
1537        );
1538        drop(key);
1539        if !remove.remove() {
1540            self.tables.key_to_item.remove_exact(remove_index);
1541        }
1542        Some(
1543            self.items
1544                .remove(remove_index)
1545                .expect("items[remove_index] was Occupied above"),
1546        )
1547    }
1548
1549    pub(super) fn replace_at_index(&mut self, index: ItemIndex, value: T) -> T {
1550        // We check the key before removing it, to avoid leaving the map in an
1551        // inconsistent state.
1552        let old_key =
1553            self.get_by_index(index).expect("index is known to be valid").key();
1554        if T::upcast_key(old_key) != value.key() {
1555            panic!(
1556                "must insert a value with \
1557                 the same key used to create the entry"
1558            );
1559        }
1560
1561        // Now that we know the key is the same, we can replace the value
1562        // directly without needing to tweak any tables.
1563        self.items.replace(index, value)
1564    }
1565}
1566
1567impl<'a, T: IdOrdItem> fmt::Debug for IdOrdMap<T>
1568where
1569    T: fmt::Debug,
1570    T::Key<'a>: fmt::Debug,
1571    T: 'a,
1572{
1573    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1574        let mut map = f.debug_map();
1575
1576        for item in self.iter() {
1577            let key = item.key();
1578
1579            // SAFETY:
1580            //
1581            // * Lifetime extension: for a type T and two lifetime params 'a and
1582            //   'b, T<'a> and T<'b> aren't guaranteed to have the same layout,
1583            //   but (a) that is true today and (b) it would be shocking and
1584            //   break half the Rust ecosystem if that were to change in the
1585            //   future.
1586            // * We only use key within the scope of this block before immediately
1587            //   dropping it. In particular, map.entry calls key.fmt() without
1588            //   holding a reference to it.
1589            let key: T::Key<'a> =
1590                unsafe { core::mem::transmute::<T::Key<'_>, T::Key<'a>>(key) };
1591
1592            map.entry(&key, &item);
1593        }
1594        map.finish()
1595    }
1596}
1597
1598impl<T: IdOrdItem + PartialEq> PartialEq for IdOrdMap<T> {
1599    fn eq(&self, other: &Self) -> bool {
1600        // Items are stored in sorted order, so we can just walk over both
1601        // iterators.
1602        if self.items.len() != other.items.len() {
1603            return false;
1604        }
1605
1606        self.iter().zip(other.iter()).all(|(item1, item2)| {
1607            // Check that the items are equal.
1608            item1 == item2
1609        })
1610    }
1611}
1612
1613// The Eq bound on T ensures that the IdOrdMap forms an equivalence class.
1614impl<T: IdOrdItem + Eq> Eq for IdOrdMap<T> {}
1615
1616/// The `Extend` implementation overwrites duplicates. In the future, there will
1617/// also be an `extend_unique` method that will return an error.
1618impl<T: IdOrdItem> Extend<T> for IdOrdMap<T> {
1619    fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
1620        // Keys may already be present in the map, or multiple times in the
1621        // iterator. Reserve the entire hint lower bound if the map is empty.
1622        // Otherwise reserve half the hint (rounded up), so the map will only
1623        // resize twice in the worst case.
1624        let iter = iter.into_iter();
1625        let reserve = if self.is_empty() {
1626            iter.size_hint().0
1627        } else {
1628            iter.size_hint().0.div_ceil(2)
1629        };
1630        self.reserve(reserve);
1631        for item in iter {
1632            self.insert_overwrite(item);
1633        }
1634    }
1635}
1636
1637impl<'a, T: IdOrdItem> IntoIterator for &'a IdOrdMap<T> {
1638    type Item = &'a T;
1639    type IntoIter = Iter<'a, T>;
1640
1641    #[inline]
1642    fn into_iter(self) -> Self::IntoIter {
1643        self.iter()
1644    }
1645}
1646
1647impl<'a, T: IdOrdItem> IntoIterator for &'a mut IdOrdMap<T>
1648where
1649    T::Key<'a>: Hash,
1650{
1651    type Item = RefMut<'a, T>;
1652    type IntoIter = IterMut<'a, T>;
1653
1654    #[inline]
1655    fn into_iter(self) -> Self::IntoIter {
1656        self.iter_mut()
1657    }
1658}
1659
1660impl<T: IdOrdItem> IntoIterator for IdOrdMap<T> {
1661    type Item = T;
1662    type IntoIter = IntoIter<T>;
1663
1664    #[inline]
1665    fn into_iter(self) -> Self::IntoIter {
1666        IntoIter::new(self.items, self.tables)
1667    }
1668}
1669
1670/// The `FromIterator` implementation for `IdOrdMap` overwrites duplicate
1671/// items.
1672///
1673/// To reject duplicates, use [`IdOrdMap::from_iter_unique`].
1674///
1675/// # Examples
1676///
1677/// ```
1678/// use iddqd::{IdOrdItem, IdOrdMap, id_upcast};
1679///
1680/// #[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
1681/// struct Item {
1682///     id: String,
1683///     value: u32,
1684/// }
1685///
1686/// impl IdOrdItem for Item {
1687///     type Key<'a> = &'a str;
1688///
1689///     fn key(&self) -> Self::Key<'_> {
1690///         &self.id
1691///     }
1692///
1693///     id_upcast!();
1694/// }
1695///
1696/// let items = vec![
1697///     Item { id: "foo".to_string(), value: 42 },
1698///     Item { id: "bar".to_string(), value: 20 },
1699///     Item { id: "foo".to_string(), value: 100 }, // duplicate key, overwrites
1700/// ];
1701///
1702/// let map: IdOrdMap<Item> = items.into_iter().collect();
1703/// assert_eq!(map.len(), 2);
1704/// assert_eq!(map.get("foo").unwrap().value, 100); // last value wins
1705/// assert_eq!(map.get("bar").unwrap().value, 20);
1706/// ```
1707impl<T: IdOrdItem> FromIterator<T> for IdOrdMap<T> {
1708    fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
1709        let mut map = IdOrdMap::new();
1710        map.extend(iter);
1711        map
1712    }
1713}