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