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        alloc::{Global, global_alloc},
10        borrow::DormantMutRef,
11        item_set::ItemSet,
12    },
13};
14use alloc::collections::BTreeSet;
15use core::{fmt, hash::Hash};
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 fast hash table of integer indexes to items, with
21/// the indexes 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: IdOrdItem> {
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 (usize) 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 fn new() -> Self {
105        Self { items: ItemSet::default(), 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 hash table.
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 mut map = IdOrdMap::new();
222        for value in iter {
223            // It would be nice to use insert_overwrite here, but that would
224            // return a `DuplicateItem<T, &T>`, which can only be converted into
225            // an owned value if T: Clone. Doing this via the Entry API means we
226            // can return a `DuplicateItem<T>` without requiring T to be Clone.
227            match map.entry(value.key()) {
228                Entry::Occupied(entry) => {
229                    let duplicate = entry.remove();
230                    return Err(DuplicateItem::__internal_new(
231                        value,
232                        vec![duplicate],
233                    ));
234                }
235                Entry::Vacant(entry) => {
236                    entry.insert_ref(value);
237                }
238            }
239        }
240
241        Ok(map)
242    }
243
244    /// Returns true if the map is empty.
245    ///
246    /// # Examples
247    ///
248    /// ```
249    /// use iddqd::{IdOrdItem, IdOrdMap, id_upcast};
250    ///
251    /// #[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
252    /// struct Item {
253    ///     id: String,
254    ///     value: u32,
255    /// }
256    ///
257    /// impl IdOrdItem for Item {
258    ///     type Key<'a> = &'a str;
259    ///
260    ///     fn key(&self) -> Self::Key<'_> {
261    ///         &self.id
262    ///     }
263    ///
264    ///     id_upcast!();
265    /// }
266    ///
267    /// let mut map = IdOrdMap::new();
268    /// assert!(map.is_empty());
269    ///
270    /// map.insert_unique(Item { id: "foo".to_string(), value: 42 }).unwrap();
271    /// assert!(!map.is_empty());
272    /// ```
273    #[inline]
274    pub fn is_empty(&self) -> bool {
275        self.items.is_empty()
276    }
277
278    /// Returns the number of items in the map.
279    ///
280    /// # Examples
281    ///
282    /// ```
283    /// use iddqd::{IdOrdItem, IdOrdMap, id_upcast};
284    ///
285    /// #[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
286    /// struct Item {
287    ///     id: String,
288    ///     value: u32,
289    /// }
290    ///
291    /// impl IdOrdItem for Item {
292    ///     type Key<'a> = &'a str;
293    ///
294    ///     fn key(&self) -> Self::Key<'_> {
295    ///         &self.id
296    ///     }
297    ///
298    ///     id_upcast!();
299    /// }
300    ///
301    /// let mut map = IdOrdMap::new();
302    /// assert_eq!(map.len(), 0);
303    ///
304    /// map.insert_unique(Item { id: "foo".to_string(), value: 42 }).unwrap();
305    /// map.insert_unique(Item { id: "bar".to_string(), value: 99 }).unwrap();
306    /// assert_eq!(map.len(), 2);
307    /// ```
308    #[inline]
309    pub fn len(&self) -> usize {
310        self.items.len()
311    }
312
313    /// Iterates over the items in the map.
314    ///
315    /// Similar to [`BTreeMap`], the iteration is ordered by [`T::Key`].
316    ///
317    /// # Examples
318    ///
319    /// ```
320    /// use iddqd::{IdOrdItem, IdOrdMap, id_upcast};
321    ///
322    /// #[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
323    /// struct Item {
324    ///     id: String,
325    ///     value: u32,
326    /// }
327    ///
328    /// impl IdOrdItem for Item {
329    ///     type Key<'a> = &'a str;
330    ///
331    ///     fn key(&self) -> Self::Key<'_> {
332    ///         &self.id
333    ///     }
334    ///
335    ///     id_upcast!();
336    /// }
337    ///
338    /// let mut map = IdOrdMap::new();
339    /// map.insert_unique(Item { id: "charlie".to_string(), value: 30 }).unwrap();
340    /// map.insert_unique(Item { id: "alice".to_string(), value: 42 }).unwrap();
341    /// map.insert_unique(Item { id: "bob".to_string(), value: 99 }).unwrap();
342    ///
343    /// // Iteration is ordered by key
344    /// let mut iter = map.iter();
345    /// let item = iter.next().unwrap();
346    /// assert_eq!(item.id, "alice");
347    /// let item = iter.next().unwrap();
348    /// assert_eq!(item.id, "bob");
349    /// let item = iter.next().unwrap();
350    /// assert_eq!(item.id, "charlie");
351    /// assert!(iter.next().is_none());
352    /// ```
353    ///
354    /// [`BTreeMap`]: std::collections::BTreeMap
355    /// [`T::Key`]: crate::IdOrdItem::Key
356    #[inline]
357    pub fn iter(&self) -> Iter<'_, T> {
358        Iter::new(&self.items, &self.tables)
359    }
360
361    /// Iterates over the items in the map, allowing for mutation.
362    ///
363    /// Similar to [`BTreeMap`], the iteration is ordered by [`T::Key`].
364    ///
365    /// # Examples
366    ///
367    /// ```
368    /// use iddqd::{IdOrdItem, IdOrdMap, id_upcast};
369    ///
370    /// #[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
371    /// struct Item {
372    ///     id: String,
373    ///     value: u32,
374    /// }
375    ///
376    /// impl IdOrdItem for Item {
377    ///     type Key<'a> = &'a str;
378    ///
379    ///     fn key(&self) -> Self::Key<'_> {
380    ///         &self.id
381    ///     }
382    ///
383    ///     id_upcast!();
384    /// }
385    ///
386    /// let mut map = IdOrdMap::new();
387    /// map.insert_unique(Item { id: "foo".to_string(), value: 42 }).unwrap();
388    /// map.insert_unique(Item { id: "bar".to_string(), value: 99 }).unwrap();
389    ///
390    /// // Modify values through the mutable iterator
391    /// for mut item in map.iter_mut() {
392    ///     item.value *= 2;
393    /// }
394    ///
395    /// assert_eq!(map.get("foo").unwrap().value, 84);
396    /// assert_eq!(map.get("bar").unwrap().value, 198);
397    /// ```
398    ///
399    /// [`BTreeMap`]: std::collections::BTreeMap
400    /// [`T::Key`]: crate::IdOrdItem::Key
401    #[inline]
402    pub fn iter_mut<'a>(&'a mut self) -> IterMut<'a, T>
403    where
404        T::Key<'a>: Hash,
405    {
406        IterMut::new(&mut self.items, &self.tables)
407    }
408
409    /// Checks general invariants of the map.
410    ///
411    /// The code below always upholds these invariants, but it's useful to have
412    /// an explicit check for tests.
413    #[doc(hidden)]
414    pub fn validate(
415        &self,
416        compactness: ValidateCompact,
417        chaos: ValidateChaos,
418    ) -> Result<(), ValidationError>
419    where
420        T: fmt::Debug,
421    {
422        self.items.validate(compactness)?;
423        self.tables.validate(self.len(), compactness)?;
424
425        // Check that the indexes are all correct.
426
427        for (&ix, item) in self.items.iter() {
428            let key = item.key();
429            let ix1 = match chaos {
430                ValidateChaos::Yes => {
431                    // Fall back to a linear search.
432                    self.linear_search_index(&key)
433                }
434                ValidateChaos::No => {
435                    // Use the B-Tree table to find the index.
436                    self.find_index(&key)
437                }
438            };
439            let Some(ix1) = ix1 else {
440                return Err(ValidationError::general(format!(
441                    "item at index {ix} has no key1 index"
442                )));
443            };
444
445            if ix1 != ix {
446                return Err(ValidationError::General(format!(
447                    "item at index {ix} has mismatched indexes: ix1: {ix1}",
448                )));
449            }
450        }
451
452        Ok(())
453    }
454
455    /// Inserts a value into the set, returning an error if any duplicates were
456    /// added.
457    ///
458    /// # Examples
459    ///
460    /// ```
461    /// use iddqd::{IdOrdItem, IdOrdMap, id_upcast};
462    ///
463    /// #[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
464    /// struct Item {
465    ///     id: String,
466    ///     value: u32,
467    /// }
468    ///
469    /// impl IdOrdItem for Item {
470    ///     type Key<'a> = &'a str;
471    ///
472    ///     fn key(&self) -> Self::Key<'_> {
473    ///         &self.id
474    ///     }
475    ///
476    ///     id_upcast!();
477    /// }
478    ///
479    /// let mut map = IdOrdMap::new();
480    ///
481    /// // Successful insertion
482    /// assert!(
483    ///     map.insert_unique(Item { id: "foo".to_string(), value: 42 }).is_ok()
484    /// );
485    /// assert!(
486    ///     map.insert_unique(Item { id: "bar".to_string(), value: 99 }).is_ok()
487    /// );
488    ///
489    /// // Duplicate key
490    /// assert!(
491    ///     map.insert_unique(Item { id: "foo".to_string(), value: 100 }).is_err()
492    /// );
493    /// ```
494    pub fn insert_unique(
495        &mut self,
496        value: T,
497    ) -> Result<(), DuplicateItem<T, &T>> {
498        let _ = self.insert_unique_impl(value)?;
499        Ok(())
500    }
501
502    /// Inserts a value into the map, removing and returning the conflicting
503    /// item, if any.
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    ///
528    /// // First insertion - no conflict
529    /// let old = map.insert_overwrite(Item { id: "foo".to_string(), value: 42 });
530    /// assert!(old.is_none());
531    ///
532    /// // Overwrite existing key - returns old value
533    /// let old = map.insert_overwrite(Item { id: "foo".to_string(), value: 99 });
534    /// assert!(old.is_some());
535    /// assert_eq!(old.unwrap().value, 42);
536    ///
537    /// // Verify new value is in the map
538    /// assert_eq!(map.get("foo").unwrap().value, 99);
539    /// ```
540    #[doc(alias = "insert")]
541    pub fn insert_overwrite(&mut self, value: T) -> Option<T> {
542        // Trying to write this function for maximal efficiency can get very
543        // tricky, requiring delicate handling of indexes. We follow a very
544        // simple approach instead:
545        //
546        // 1. Remove the item corresponding to the key that is already in the map.
547        // 2. Add the item to the map.
548
549        let duplicate = self.remove(&value.key());
550
551        if self.insert_unique(value).is_err() {
552            // We should never get here, because we just removed all the
553            // duplicates.
554            panic!("insert_unique failed after removing duplicates");
555        }
556
557        duplicate
558    }
559
560    /// Returns true if the map contains the given `key`.
561    ///
562    /// # Examples
563    ///
564    /// ```
565    /// use iddqd::{IdOrdItem, IdOrdMap, id_upcast};
566    ///
567    /// #[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
568    /// struct Item {
569    ///     id: String,
570    ///     value: u32,
571    /// }
572    ///
573    /// impl IdOrdItem for Item {
574    ///     type Key<'a> = &'a str;
575    ///
576    ///     fn key(&self) -> Self::Key<'_> {
577    ///         &self.id
578    ///     }
579    ///
580    ///     id_upcast!();
581    /// }
582    ///
583    /// let mut map = IdOrdMap::new();
584    /// map.insert_unique(Item { id: "foo".to_string(), value: 42 }).unwrap();
585    ///
586    /// assert!(map.contains_key("foo"));
587    /// assert!(!map.contains_key("bar"));
588    /// ```
589    pub fn contains_key<'a, Q>(&'a self, key: &Q) -> bool
590    where
591        Q: ?Sized + Comparable<T::Key<'a>>,
592    {
593        self.find_index(key).is_some()
594    }
595
596    /// Gets a reference to the value associated with the given `key`.
597    ///
598    /// # Examples
599    ///
600    /// ```
601    /// use iddqd::{IdOrdItem, IdOrdMap, id_upcast};
602    ///
603    /// #[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
604    /// struct Item {
605    ///     id: String,
606    ///     value: u32,
607    /// }
608    ///
609    /// impl IdOrdItem for Item {
610    ///     type Key<'a> = &'a str;
611    ///
612    ///     fn key(&self) -> Self::Key<'_> {
613    ///         &self.id
614    ///     }
615    ///
616    ///     id_upcast!();
617    /// }
618    ///
619    /// let mut map = IdOrdMap::new();
620    /// map.insert_unique(Item { id: "foo".to_string(), value: 42 }).unwrap();
621    ///
622    /// assert_eq!(map.get("foo").unwrap().value, 42);
623    /// assert!(map.get("bar").is_none());
624    /// ```
625    pub fn get<'a, Q>(&'a self, key: &Q) -> Option<&'a T>
626    where
627        Q: ?Sized + Comparable<T::Key<'a>>,
628    {
629        self.find(key)
630    }
631
632    /// Gets a mutable reference to the item associated with the given `key`.
633    ///
634    /// # Examples
635    ///
636    /// ```
637    /// use iddqd::{IdOrdItem, IdOrdMap, id_upcast};
638    ///
639    /// #[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
640    /// struct Item {
641    ///     id: String,
642    ///     value: u32,
643    /// }
644    ///
645    /// impl IdOrdItem for Item {
646    ///     type Key<'a> = &'a str;
647    ///
648    ///     fn key(&self) -> Self::Key<'_> {
649    ///         &self.id
650    ///     }
651    ///
652    ///     id_upcast!();
653    /// }
654    ///
655    /// let mut map = IdOrdMap::new();
656    /// map.insert_unique(Item { id: "foo".to_string(), value: 42 }).unwrap();
657    ///
658    /// if let Some(mut item) = map.get_mut("foo") {
659    ///     item.value = 99;
660    /// }
661    ///
662    /// assert_eq!(map.get("foo").unwrap().value, 99);
663    /// ```
664    pub fn get_mut<'a, Q>(&'a mut self, key: &Q) -> Option<RefMut<'a, T>>
665    where
666        Q: ?Sized + Comparable<T::Key<'a>>,
667        T::Key<'a>: Hash,
668    {
669        let (dormant_map, index) = {
670            let (map, dormant_map) = DormantMutRef::new(self);
671            let index = map.find_index(key)?;
672            (dormant_map, index)
673        };
674
675        // SAFETY: `map` is not used after this point.
676        let awakened_map = unsafe { dormant_map.awaken() };
677        let item = &mut awakened_map.items[index];
678        let (hash, dormant) = {
679            let (item, dormant) = DormantMutRef::new(item);
680            let hash = awakened_map.tables.make_hash(item);
681            (hash, dormant)
682        };
683
684        // SAFETY: the original item is not used after this point.
685        let item = unsafe { dormant.awaken() };
686        Some(RefMut::new(hash, item))
687    }
688
689    /// Removes an item from the map by its `key`.
690    ///
691    /// # Examples
692    ///
693    /// ```
694    /// use iddqd::{IdOrdItem, IdOrdMap, id_upcast};
695    ///
696    /// #[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
697    /// struct Item {
698    ///     id: String,
699    ///     value: u32,
700    /// }
701    ///
702    /// impl IdOrdItem for Item {
703    ///     type Key<'a> = &'a str;
704    ///
705    ///     fn key(&self) -> Self::Key<'_> {
706    ///         &self.id
707    ///     }
708    ///
709    ///     id_upcast!();
710    /// }
711    ///
712    /// let mut map = IdOrdMap::new();
713    /// map.insert_unique(Item { id: "foo".to_string(), value: 42 }).unwrap();
714    ///
715    /// let removed = map.remove("foo");
716    /// assert!(removed.is_some());
717    /// assert_eq!(removed.unwrap().value, 42);
718    /// assert!(map.is_empty());
719    ///
720    /// // Removing a non-existent key returns None
721    /// assert!(map.remove("bar").is_none());
722    /// ```
723    pub fn remove<'a, Q>(&'a mut self, key: &Q) -> Option<T>
724    where
725        Q: ?Sized + Comparable<T::Key<'a>>,
726    {
727        let (dormant_map, remove_index) = {
728            let (map, dormant_map) = DormantMutRef::new(self);
729            let remove_index = map.find_index(key)?;
730            (dormant_map, remove_index)
731        };
732
733        // SAFETY: `map` is not used after this point.
734        let awakened_map = unsafe { dormant_map.awaken() };
735        awakened_map.remove_by_index(remove_index)
736    }
737
738    /// Retrieves an entry by its `key`.
739    ///
740    /// Due to borrow checker limitations, this always accepts an owned key rather
741    /// than a borrowed form.
742    ///
743    /// # Examples
744    ///
745    /// ```
746    /// use iddqd::{IdOrdItem, IdOrdMap, id_ord_map, id_upcast};
747    ///
748    /// #[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
749    /// struct Item {
750    ///     id: String,
751    ///     value: u32,
752    /// }
753    ///
754    /// impl IdOrdItem for Item {
755    ///     type Key<'a> = &'a str;
756    ///
757    ///     fn key(&self) -> Self::Key<'_> {
758    ///         &self.id
759    ///     }
760    ///
761    ///     id_upcast!();
762    /// }
763    ///
764    /// let mut map = IdOrdMap::new();
765    ///
766    /// // Insert via vacant entry
767    /// match map.entry("foo") {
768    ///     id_ord_map::Entry::Vacant(entry) => {
769    ///         entry.insert(Item { id: "foo".to_string(), value: 42 });
770    ///     }
771    ///     id_ord_map::Entry::Occupied(_) => {}
772    /// }
773    ///
774    /// // Update via occupied entry
775    /// match map.entry("foo") {
776    ///     id_ord_map::Entry::Occupied(mut entry) => {
777    ///         entry.get_mut().value = 99;
778    ///     }
779    ///     id_ord_map::Entry::Vacant(_) => {}
780    /// }
781    ///
782    /// assert_eq!(map.get("foo").unwrap().value, 99);
783    /// ```
784    pub fn entry<'a>(&'a mut self, key: T::Key<'_>) -> Entry<'a, T> {
785        // Why does this always take an owned key? Well, it would seem like we
786        // should be able to pass in any Q that is equivalent. That results in
787        // *this* code compiling fine, but callers have trouble using it because
788        // the borrow checker believes the keys are borrowed for the full 'a
789        // rather than a shorter lifetime.
790        //
791        // By accepting owned keys, we can use the upcast functions to convert
792        // them to a shorter lifetime (so this function accepts T::Key<'_>
793        // rather than T::Key<'a>).
794        //
795        // Really, the solution here is to allow GATs to require covariant
796        // parameters. If that were allowed, the borrow checker should be able
797        // to figure out that keys don't need to be borrowed for the full 'a,
798        // just for some shorter lifetime.
799        let (map, dormant_map) = DormantMutRef::new(self);
800        let key = T::upcast_key(key);
801        {
802            // index is explicitly typed to show that it has a trivial Drop impl
803            // that doesn't capture anything from map.
804            let index: Option<usize> = map
805                .tables
806                .key_to_item
807                .find_index(&key, |index| map.items[index].key());
808            if let Some(index) = index {
809                drop(key);
810                return Entry::Occupied(
811                    // SAFETY: `map` is not used after this point.
812                    unsafe { OccupiedEntry::new(dormant_map, index) },
813                );
814            }
815        }
816        Entry::Vacant(
817            // SAFETY: `map` is not used after this point.
818            unsafe { VacantEntry::new(dormant_map) },
819        )
820    }
821
822    fn find<'a, Q>(&'a self, k: &Q) -> Option<&'a T>
823    where
824        Q: ?Sized + Comparable<T::Key<'a>>,
825    {
826        self.find_index(k).map(|ix| &self.items[ix])
827    }
828
829    fn linear_search_index<'a, Q>(&'a self, k: &Q) -> Option<usize>
830    where
831        Q: ?Sized + Ord + Equivalent<T::Key<'a>>,
832    {
833        self.items.iter().find_map(|(index, item)| {
834            (k.equivalent(&item.key())).then_some(*index)
835        })
836    }
837
838    fn find_index<'a, Q>(&'a self, k: &Q) -> Option<usize>
839    where
840        Q: ?Sized + Comparable<T::Key<'a>>,
841    {
842        self.tables.key_to_item.find_index(k, |index| self.items[index].key())
843    }
844
845    pub(super) fn get_by_index(&self, index: usize) -> Option<&T> {
846        self.items.get(index)
847    }
848
849    pub(super) fn get_by_index_mut<'a>(
850        &'a mut self,
851        index: usize,
852    ) -> Option<RefMut<'a, T>>
853    where
854        T::Key<'a>: Hash,
855    {
856        let (hash, dormant) = {
857            let item: &'a mut T = self.items.get_mut(index)?;
858            let (item, dormant) = DormantMutRef::new(item);
859            let hash = self.tables.make_hash(item);
860            (hash, dormant)
861        };
862
863        // SAFETY: item is no longer used after the above point.
864        let item = unsafe { dormant.awaken() };
865        Some(RefMut::new(hash, item))
866    }
867
868    pub(super) fn insert_unique_impl(
869        &mut self,
870        value: T,
871    ) -> Result<usize, DuplicateItem<T, &T>> {
872        let mut duplicates = BTreeSet::new();
873
874        // Check for duplicates *before* inserting the new item, because we
875        // don't want to partially insert the new item and then have to roll
876        // back.
877        let key = value.key();
878
879        if let Some(index) = self
880            .tables
881            .key_to_item
882            .find_index(&key, |index| self.items[index].key())
883        {
884            duplicates.insert(index);
885        }
886
887        if !duplicates.is_empty() {
888            drop(key);
889            return Err(DuplicateItem::__internal_new(
890                value,
891                duplicates.iter().map(|ix| &self.items[*ix]).collect(),
892            ));
893        }
894
895        let next_index = self.items.next_index();
896        self.tables
897            .key_to_item
898            .insert(next_index, &key, |index| self.items[index].key());
899        drop(key);
900        self.items.insert_at_next_index(value);
901
902        Ok(next_index)
903    }
904
905    pub(super) fn remove_by_index(&mut self, remove_index: usize) -> Option<T> {
906        let value = self.items.remove(remove_index)?;
907
908        // Remove the value from the table.
909        self.tables.key_to_item.remove(remove_index, value.key(), |index| {
910            if index == remove_index {
911                value.key()
912            } else {
913                self.items[index].key()
914            }
915        });
916
917        Some(value)
918    }
919
920    pub(super) fn replace_at_index(&mut self, index: usize, value: T) -> T {
921        // We check the key before removing it, to avoid leaving the map in an
922        // inconsistent state.
923        let old_key =
924            self.get_by_index(index).expect("index is known to be valid").key();
925        if T::upcast_key(old_key) != value.key() {
926            panic!(
927                "must insert a value with \
928                 the same key used to create the entry"
929            );
930        }
931
932        // Now that we know the key is the same, we can replace the value
933        // directly without needing to tweak any tables.
934        self.items.replace(index, value)
935    }
936}
937
938impl<'a, T: IdOrdItem> fmt::Debug for IdOrdMap<T>
939where
940    T: fmt::Debug,
941    T::Key<'a>: fmt::Debug,
942    T: 'a,
943{
944    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
945        let mut map = f.debug_map();
946
947        for item in self.iter() {
948            let key = item.key();
949
950            // SAFETY:
951            //
952            // * Lifetime extension: for a type T and two lifetime params 'a and
953            //   'b, T<'a> and T<'b> aren't guaranteed to have the same layout,
954            //   but (a) that is true today and (b) it would be shocking and
955            //   break half the Rust ecosystem if that were to change in the
956            //   future.
957            // * We only use key within the scope of this block before immediately
958            //   dropping it. In particular, map.entry calls key.fmt() without
959            //   holding a reference to it.
960            let key: T::Key<'a> =
961                unsafe { core::mem::transmute::<T::Key<'_>, T::Key<'a>>(key) };
962
963            map.entry(&key, &item);
964        }
965        map.finish()
966    }
967}
968
969impl<T: IdOrdItem + PartialEq> PartialEq for IdOrdMap<T> {
970    fn eq(&self, other: &Self) -> bool {
971        // Items are stored in sorted order, so we can just walk over both
972        // iterators.
973        if self.items.len() != other.items.len() {
974            return false;
975        }
976
977        self.iter().zip(other.iter()).all(|(item1, item2)| {
978            // Check that the items are equal.
979            item1 == item2
980        })
981    }
982}
983
984// The Eq bound on T ensures that the IdOrdMap forms an equivalence class.
985impl<T: IdOrdItem + Eq> Eq for IdOrdMap<T> {}
986
987/// The `Extend` implementation overwrites duplicates. In the future, there will
988/// also be an `extend_unique` method that will return an error.
989impl<T: IdOrdItem> Extend<T> for IdOrdMap<T> {
990    fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
991        for item in iter {
992            self.insert_overwrite(item);
993        }
994    }
995}
996
997impl<'a, T: IdOrdItem> IntoIterator for &'a IdOrdMap<T> {
998    type Item = &'a T;
999    type IntoIter = Iter<'a, T>;
1000
1001    #[inline]
1002    fn into_iter(self) -> Self::IntoIter {
1003        self.iter()
1004    }
1005}
1006
1007impl<'a, T: IdOrdItem> IntoIterator for &'a mut IdOrdMap<T>
1008where
1009    T::Key<'a>: Hash,
1010{
1011    type Item = RefMut<'a, T>;
1012    type IntoIter = IterMut<'a, T>;
1013
1014    #[inline]
1015    fn into_iter(self) -> Self::IntoIter {
1016        self.iter_mut()
1017    }
1018}
1019
1020impl<T: IdOrdItem> IntoIterator for IdOrdMap<T> {
1021    type Item = T;
1022    type IntoIter = IntoIter<T>;
1023
1024    #[inline]
1025    fn into_iter(self) -> Self::IntoIter {
1026        IntoIter::new(self.items, self.tables)
1027    }
1028}
1029
1030/// The `FromIterator` implementation for `IdOrdMap` overwrites duplicate
1031/// items.
1032///
1033/// To reject duplicates, use [`IdOrdMap::from_iter_unique`].
1034impl<T: IdOrdItem> FromIterator<T> for IdOrdMap<T> {
1035    fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
1036        let mut map = IdOrdMap::new();
1037        for value in iter {
1038            map.insert_overwrite(value);
1039        }
1040        map
1041    }
1042}