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