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