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