Skip to main content

imbl/hash/
map.rs

1// This Source Code Form is subject to the terms of the Mozilla Public
2// License, v. 2.0. If a copy of the MPL was not distributed with this
3// file, You can obtain one at http://mozilla.org/MPL/2.0/.
4
5//! An unordered map.
6//!
7//! An immutable hash map using [hash array mapped tries][1].
8//!
9//! Most operations on this map are O(log<sub>x</sub> n) for a
10//! suitably high *x* that it should be nearly O(1) for most maps.
11//! Because of this, it's a great choice for a generic map as long as
12//! you don't mind that keys will need to implement
13//! [`Hash`][std::hash::Hash] and [`Eq`][std::cmp::Eq].
14//!
15//! Map entries will have a predictable order based on the hasher
16//! being used. Unless otherwise specified, this will be the standard
17//! [`RandomState`][std::collections::hash_map::RandomState] hasher.
18//!
19//! [1]: https://en.wikipedia.org/wiki/Hash_array_mapped_trie
20//! [std::cmp::Eq]: https://doc.rust-lang.org/std/cmp/trait.Eq.html
21//! [std::hash::Hash]: https://doc.rust-lang.org/std/hash/trait.Hash.html
22//! [std::collections::hash_map::RandomState]: https://doc.rust-lang.org/std/collections/hash_map/struct.RandomState.html
23
24use std::borrow::Borrow;
25use std::collections;
26use std::collections::hash_map::RandomState;
27use std::fmt::{Debug, Error, Formatter};
28use std::hash::{BuildHasher, Hash};
29use std::iter::{FromIterator, FusedIterator, Sum};
30use std::mem;
31use std::ops::{Add, Index, IndexMut};
32
33use archery::{SharedPointer, SharedPointerKind};
34use equivalent::Equivalent;
35
36use crate::nodes::hamt::{
37    hash_key, Drain as NodeDrain, HashBits, HashValue, Iter as NodeIter, IterMut as NodeIterMut,
38    Node,
39};
40use crate::shared_ptr::DefaultSharedPtr;
41
42/// Construct a hash map from a sequence of key/value pairs.
43///
44/// # Examples
45///
46/// ```
47/// # #[macro_use] extern crate imbl;
48/// # use imbl::HashMap;
49/// # fn main() {
50/// assert_eq!(
51///   hashmap!{
52///     1 => 11,
53///     2 => 22,
54///     3 => 33
55///   },
56///   HashMap::from(vec![(1, 11), (2, 22), (3, 33)])
57/// );
58/// # }
59/// ```
60#[macro_export]
61macro_rules! hashmap {
62    () => { $crate::hashmap::HashMap::new() };
63
64    ( $( $key:expr => $value:expr ),* ) => {{
65        let mut map = $crate::hashmap::HashMap::new();
66        $({
67            map.insert($key, $value);
68        })*;
69        map
70    }};
71
72    ( $( $key:expr => $value:expr ,)* ) => {{
73        let mut map = $crate::hashmap::HashMap::new();
74        $({
75            map.insert($key, $value);
76        })*;
77        map
78    }};
79}
80
81/// Type alias for [`GenericHashMap`] that uses [`std::hash::RandomState`] as the default hasher and [`DefaultSharedPtr`] as the pointer type.
82///
83/// [GenericHashMap]: ./struct.GenericHashMap.html
84/// [`std::hash::RandomState`]: https://doc.rust-lang.org/stable/std/collections/hash_map/struct.RandomState.html
85/// [DefaultSharedPtr]: ../shared_ptr/type.DefaultSharedPtr.html
86pub type HashMap<K, V> = GenericHashMap<K, V, RandomState, DefaultSharedPtr>;
87
88/// An unordered map.
89///
90/// An immutable hash map using [hash array mapped tries] [1].
91///
92/// Most operations on this map are O(log<sub>x</sub> n) for a
93/// suitably high *x* that it should be nearly O(1) for most maps.
94/// Because of this, it's a great choice for a generic map as long as
95/// you don't mind that keys will need to implement
96/// [`Hash`][std::hash::Hash] and [`Eq`][std::cmp::Eq].
97///
98/// Map entries will have a predictable order based on the hasher
99/// being used. Unless otherwise specified, this will be the standard
100/// [`RandomState`][std::collections::hash_map::RandomState] hasher.
101///
102/// [1]: https://en.wikipedia.org/wiki/Hash_array_mapped_trie
103/// [std::cmp::Eq]: https://doc.rust-lang.org/std/cmp/trait.Eq.html
104/// [std::hash::Hash]: https://doc.rust-lang.org/std/hash/trait.Hash.html
105/// [std::collections::hash_map::RandomState]: https://doc.rust-lang.org/std/collections/hash_map/struct.RandomState.html
106pub struct GenericHashMap<K, V, S, P: SharedPointerKind> {
107    size: usize,
108    root: Option<SharedPointer<Node<(K, V), P>, P>>,
109    hasher: S,
110}
111
112impl<K, V> HashValue for (K, V)
113where
114    K: Eq,
115{
116    type Key = K;
117
118    fn extract_key(&self) -> &Self::Key {
119        &self.0
120    }
121
122    fn ptr_eq(&self, _other: &Self) -> bool {
123        false
124    }
125}
126
127impl<K, V, P> GenericHashMap<K, V, RandomState, P>
128where
129    K: Hash + Eq + Clone,
130    V: Clone,
131    P: SharedPointerKind,
132{
133    /// Construct a hash map with a single mapping.
134    ///
135    /// # Examples
136    ///
137    /// ```
138    /// # #[macro_use] extern crate imbl;
139    /// # use imbl::HashMap;
140    /// let map = HashMap::unit(123, "onetwothree");
141    /// assert_eq!(
142    ///   map.get(&123),
143    ///   Some(&"onetwothree")
144    /// );
145    /// ```
146    #[inline]
147    #[must_use]
148    pub fn unit(k: K, v: V) -> GenericHashMap<K, V, RandomState, P> {
149        GenericHashMap::new().update(k, v)
150    }
151}
152
153impl<K, V, S, P: SharedPointerKind> GenericHashMap<K, V, S, P> {
154    /// Construct an empty hash map.
155    #[inline]
156    #[must_use]
157    pub fn new() -> Self
158    where
159        S: Default,
160    {
161        Self::default()
162    }
163
164    /// Test whether a hash map is empty.
165    ///
166    /// Time: O(1)
167    ///
168    /// # Examples
169    ///
170    /// ```
171    /// # #[macro_use] extern crate imbl;
172    /// # use imbl::hashmap::HashMap;
173    /// assert!(
174    ///   !hashmap!{1 => 2}.is_empty()
175    /// );
176    /// assert!(
177    ///   HashMap::<i32, i32>::new().is_empty()
178    /// );
179    /// ```
180    #[inline]
181    #[must_use]
182    pub fn is_empty(&self) -> bool {
183        self.len() == 0
184    }
185
186    /// Get the size of a hash map.
187    ///
188    /// Time: O(1)
189    ///
190    /// # Examples
191    ///
192    /// ```
193    /// # #[macro_use] extern crate imbl;
194    /// # use imbl::hashmap::HashMap;
195    /// assert_eq!(3, hashmap!{
196    ///   1 => 11,
197    ///   2 => 22,
198    ///   3 => 33
199    /// }.len());
200    /// ```
201    #[inline]
202    #[must_use]
203    pub fn len(&self) -> usize {
204        self.size
205    }
206
207    /// Test whether two maps refer to the same content in memory.
208    ///
209    /// This is true if the two sides are references to the same map,
210    /// or if the two maps refer to the same root node.
211    ///
212    /// This would return true if you're comparing a map to itself, or
213    /// if you're comparing a map to a fresh clone of itself.
214    ///
215    /// Time: O(1)
216    pub fn ptr_eq(&self, other: &Self) -> bool {
217        match (&self.root, &other.root) {
218            (Some(a), Some(b)) => SharedPointer::ptr_eq(a, b),
219            (None, None) => true,
220            _ => false,
221        }
222    }
223
224    /// Construct an empty hash map using the provided hasher.
225    #[inline]
226    #[must_use]
227    pub fn with_hasher(hasher: S) -> Self {
228        GenericHashMap {
229            size: 0,
230            hasher,
231            root: None,
232        }
233    }
234
235    /// Get a reference to the map's [`BuildHasher`][BuildHasher].
236    ///
237    /// [BuildHasher]: https://doc.rust-lang.org/std/hash/trait.BuildHasher.html
238    #[must_use]
239    pub fn hasher(&self) -> &S {
240        &self.hasher
241    }
242
243    /// Construct an empty hash map using the same hasher as the
244    /// current hash map.
245    #[inline]
246    #[must_use]
247    pub fn new_from<K1, V1>(&self) -> GenericHashMap<K1, V1, S, P>
248    where
249        K1: Hash + Eq + Clone,
250        V1: Clone,
251        S: Clone,
252    {
253        GenericHashMap {
254            size: 0,
255            root: None,
256            hasher: self.hasher.clone(),
257        }
258    }
259
260    /// Get an iterator over the key/value pairs of a hash map.
261    ///
262    /// Please note that the order is consistent between maps using
263    /// the same hasher, but no other ordering guarantee is offered.
264    /// Items will not come out in insertion order or sort order.
265    /// They will, however, come out in the same order every time for
266    /// the same map.
267    #[inline]
268    #[must_use]
269    pub fn iter(&self) -> Iter<'_, K, V, P> {
270        Iter {
271            it: NodeIter::new(self.root.as_deref(), self.size),
272        }
273    }
274
275    /// Get an iterator over a hash map's keys.
276    ///
277    /// Please note that the order is consistent between maps using
278    /// the same hasher, but no other ordering guarantee is offered.
279    /// Items will not come out in insertion order or sort order.
280    /// They will, however, come out in the same order every time for
281    /// the same map.
282    #[inline]
283    #[must_use]
284    pub fn keys(&self) -> Keys<'_, K, V, P> {
285        Keys {
286            it: NodeIter::new(self.root.as_deref(), self.size),
287        }
288    }
289
290    /// Get an iterator over a hash map's values.
291    ///
292    /// Please note that the order is consistent between maps using
293    /// the same hasher, but no other ordering guarantee is offered.
294    /// Items will not come out in insertion order or sort order.
295    /// They will, however, come out in the same order every time for
296    /// the same map.
297    #[inline]
298    #[must_use]
299    pub fn values(&self) -> Values<'_, K, V, P> {
300        Values {
301            it: NodeIter::new(self.root.as_deref(), self.size),
302        }
303    }
304
305    /// Discard all elements from the map.
306    ///
307    /// This leaves you with an empty map, and all elements that
308    /// were previously inside it are dropped.
309    ///
310    /// Time: O(n)
311    ///
312    /// # Examples
313    ///
314    /// ```
315    /// # #[macro_use] extern crate imbl;
316    /// # use imbl::HashMap;
317    /// let mut map = hashmap![1=>1, 2=>2, 3=>3];
318    /// map.clear();
319    /// assert!(map.is_empty());
320    /// ```
321    pub fn clear(&mut self) {
322        self.root = None;
323        self.size = 0;
324    }
325
326    /// Print a summary of the HashMap structure showing per-level statistics.
327    /// This includes the number of nodes at each level and the distribution of child types.
328    #[cfg(test)]
329    pub fn print_structure_summary(&self) {
330        use crate::nodes::hamt::Entry as NodeEntry;
331        use std::collections::VecDeque;
332
333        println!("HashMap Structure Summary:");
334
335        #[derive(Default, Debug)]
336        struct LevelStats {
337            node_count: usize,
338            value_count: usize,
339            collision_count: usize,
340            collision_entry_sum: usize,
341            child_node_count: usize,
342            small_simd_node_count: usize,
343            large_simd_node_count: usize,
344            small_simd_entry_sum: usize,
345            large_simd_entry_sum: usize,
346            total_entries: usize,
347        }
348
349        if self.root.is_none() {
350            println!("  Empty HashMap (no root node)");
351            println!("  Total entries: 0");
352            return;
353        }
354
355        let mut level_stats: Vec<LevelStats> = Vec::new();
356        let mut queue: VecDeque<(usize, SharedPointer<Node<(K, V), P>, P>)> = VecDeque::new();
357        let mut max_depth = 0;
358
359        // Start with root node at level 0
360        if let Some(ref root) = self.root {
361            queue.push_back((0, root.clone()));
362        }
363
364        // BFS traversal to collect statistics
365        while let Some((level, node)) = queue.pop_front() {
366            // Ensure we have stats for this level
367            while level_stats.len() <= level {
368                level_stats.push(LevelStats::default());
369            }
370
371            let stats = &mut level_stats[level];
372            stats.node_count += 1;
373
374            // Analyze this node's entries
375            node.analyze_structure(|entry| {
376                stats.total_entries += 1;
377                match entry {
378                    NodeEntry::Value(_, _) => {
379                        stats.value_count += 1;
380                        max_depth = max_depth.max(level);
381                    }
382                    NodeEntry::Collision(_coll) => {
383                        stats.collision_count += 1;
384                        // stats.collision_entry_sum += coll.len();
385                        max_depth = max_depth.max(level);
386                    }
387                    NodeEntry::HamtNode(child_node) => {
388                        stats.child_node_count += 1;
389                        queue.push_back((level + 1, child_node.clone()));
390                    }
391                    NodeEntry::SmallSimdNode(small_node) => {
392                        stats.small_simd_node_count += 1;
393                        stats.small_simd_entry_sum += small_node.len();
394                        max_depth = max_depth.max(level + 1);
395                    }
396                    NodeEntry::LargeSimdNode(large_node) => {
397                        stats.large_simd_node_count += 1;
398                        stats.large_simd_entry_sum += large_node.len();
399                        max_depth = max_depth.max(level + 1);
400                    }
401                }
402            })
403        }
404
405        // Print the summary
406        println!(
407            "  Hash level size (bits): {}",
408            crate::config::HASH_LEVEL_SIZE
409        );
410        println!(
411            "  Branching factor: {}",
412            2_usize.pow(crate::config::HASH_LEVEL_SIZE as u32)
413        );
414        println!("  Total entries: {}", self.size);
415        println!("  Tree depth: {} levels", max_depth + 1);
416        println!();
417
418        for (level, stats) in level_stats.iter().enumerate() {
419            println!("  Level {}:", level);
420            println!("    Nodes: {}", stats.node_count);
421
422            if stats.total_entries > 0 {
423                let avg_entries = stats.total_entries as f64 / stats.node_count as f64;
424                println!("    Average entries per node: {:.2}", avg_entries);
425
426                println!("    Entry types:");
427                println!(
428                    "      Values: {} ({:.1}%)",
429                    stats.value_count,
430                    (stats.value_count as f64 / stats.total_entries as f64) * 100.0
431                );
432                println!(
433                    "      Collisions: {} (avg len: {:.1}) ({:.1}%)",
434                    stats.collision_count,
435                    if stats.collision_count > 0 {
436                        stats.collision_entry_sum as f64 / stats.collision_count as f64
437                    } else {
438                        0.0
439                    },
440                    (stats.collision_count as f64 / stats.total_entries as f64) * 100.0
441                );
442                println!(
443                    "      Child HAMT nodes: {} ({:.1}%)",
444                    stats.child_node_count,
445                    (stats.child_node_count as f64 / stats.total_entries as f64) * 100.0
446                );
447                if stats.small_simd_node_count > 0 {
448                    println!(
449                        "      Small SIMD leaf nodes: {} ({:.1}%) [total values: {}]",
450                        stats.small_simd_node_count,
451                        (stats.small_simd_node_count as f64 / stats.total_entries as f64) * 100.0,
452                        stats.small_simd_entry_sum
453                    );
454                    println!(
455                        "        → Avg values per small SIMD node: {:.1}",
456                        stats.small_simd_entry_sum as f64 / stats.small_simd_node_count as f64
457                    );
458                }
459                if stats.large_simd_node_count > 0 {
460                    println!(
461                        "      Large SIMD leaf nodes: {} ({:.1}%) [total values: {}]",
462                        stats.large_simd_node_count,
463                        (stats.large_simd_node_count as f64 / stats.total_entries as f64) * 100.0,
464                        stats.large_simd_entry_sum
465                    );
466                    println!(
467                        "        → Avg values per large SIMD node: {:.1}",
468                        stats.large_simd_entry_sum as f64 / stats.large_simd_node_count as f64
469                    );
470                }
471            }
472            println!();
473        }
474    }
475}
476
477impl<K, V, S, P> GenericHashMap<K, V, S, P>
478where
479    K: Hash + Eq,
480    S: BuildHasher + Clone,
481    P: SharedPointerKind,
482{
483    fn test_eq<S2: BuildHasher + Clone, P2: SharedPointerKind>(
484        &self,
485        other: &GenericHashMap<K, V, S2, P2>,
486    ) -> bool
487    where
488        V: PartialEq,
489    {
490        if self.len() != other.len() {
491            return false;
492        }
493        let mut seen = collections::HashSet::new();
494        for (key, value) in self.iter() {
495            if Some(value) != other.get(key) {
496                return false;
497            }
498            seen.insert(key);
499        }
500        for key in other.keys() {
501            if !seen.contains(&key) {
502                return false;
503            }
504        }
505        true
506    }
507
508    /// Get the value for a key from a hash map.
509    ///
510    /// Time: O(log n)
511    ///
512    /// # Examples
513    ///
514    /// ```
515    /// # #[macro_use] extern crate imbl;
516    /// # use imbl::hashmap::HashMap;
517    /// let map = hashmap!{123 => "lol"};
518    /// assert_eq!(
519    ///   map.get(&123),
520    ///   Some(&"lol")
521    /// );
522    /// ```
523    #[must_use]
524    pub fn get<Q>(&self, key: &Q) -> Option<&V>
525    where
526        Q: Hash + Equivalent<K> + ?Sized,
527    {
528        if let Some(root) = &self.root {
529            root.get(hash_key(&self.hasher, key), 0, key)
530                .map(|(_, v)| v)
531        } else {
532            None
533        }
534    }
535
536    /// Get the key/value pair for a key from a hash map.
537    ///
538    /// Time: O(log n)
539    ///
540    /// # Examples
541    ///
542    /// ```
543    /// # #[macro_use] extern crate imbl;
544    /// # use imbl::hashmap::HashMap;
545    /// let map = hashmap!{123 => "lol"};
546    /// assert_eq!(
547    ///   map.get_key_value(&123),
548    ///   Some((&123, &"lol"))
549    /// );
550    /// ```
551    #[must_use]
552    pub fn get_key_value<Q>(&self, key: &Q) -> Option<(&K, &V)>
553    where
554        Q: Hash + Equivalent<K> + ?Sized,
555    {
556        if let Some(root) = &self.root {
557            root.get(hash_key(&self.hasher, key), 0, key)
558                .map(|(k, v)| (k, v))
559        } else {
560            None
561        }
562    }
563
564    /// Test for the presence of a key in a hash map.
565    ///
566    /// Time: O(log n)
567    ///
568    /// # Examples
569    ///
570    /// ```
571    /// # #[macro_use] extern crate imbl;
572    /// # use imbl::hashmap::HashMap;
573    /// let map = hashmap!{123 => "lol"};
574    /// assert!(
575    ///   map.contains_key(&123)
576    /// );
577    /// assert!(
578    ///   !map.contains_key(&321)
579    /// );
580    /// ```
581    #[inline]
582    #[must_use]
583    pub fn contains_key<Q>(&self, k: &Q) -> bool
584    where
585        Q: Hash + Equivalent<K> + ?Sized,
586    {
587        self.get(k).is_some()
588    }
589
590    /// Test whether a map is a submap of another map, meaning that
591    /// all keys in our map must also be in the other map, with the
592    /// same values.
593    ///
594    /// Use the provided function to decide whether values are equal.
595    ///
596    /// Time: O(n log n)
597    #[must_use]
598    pub fn is_submap_by<B, RM, F, P2: SharedPointerKind>(&self, other: RM, mut cmp: F) -> bool
599    where
600        F: FnMut(&V, &B) -> bool,
601        RM: Borrow<GenericHashMap<K, B, S, P2>>,
602    {
603        self.iter()
604            .all(|(k, v)| other.borrow().get(k).map(|ov| cmp(v, ov)).unwrap_or(false))
605    }
606
607    /// Test whether a map is a proper submap of another map, meaning
608    /// that all keys in our map must also be in the other map, with
609    /// the same values. To be a proper submap, ours must also contain
610    /// fewer keys than the other map.
611    ///
612    /// Use the provided function to decide whether values are equal.
613    ///
614    /// Time: O(n log n)
615    #[must_use]
616    pub fn is_proper_submap_by<B, RM, F, P2: SharedPointerKind>(&self, other: RM, cmp: F) -> bool
617    where
618        F: FnMut(&V, &B) -> bool,
619        RM: Borrow<GenericHashMap<K, B, S, P2>>,
620    {
621        self.len() != other.borrow().len() && self.is_submap_by(other, cmp)
622    }
623
624    /// Test whether a map is a submap of another map, meaning that
625    /// all keys in our map must also be in the other map, with the
626    /// same values.
627    ///
628    /// Time: O(n log n)
629    ///
630    /// # Examples
631    ///
632    /// ```
633    /// # #[macro_use] extern crate imbl;
634    /// # use imbl::hashmap::HashMap;
635    /// let map1 = hashmap!{1 => 1, 2 => 2};
636    /// let map2 = hashmap!{1 => 1, 2 => 2, 3 => 3};
637    /// assert!(map1.is_submap(map2));
638    /// ```
639    #[inline]
640    #[must_use]
641    pub fn is_submap<RM>(&self, other: RM) -> bool
642    where
643        V: PartialEq,
644        RM: Borrow<Self>,
645    {
646        self.is_submap_by(other.borrow(), PartialEq::eq)
647    }
648
649    /// Test whether a map is a proper submap of another map, meaning
650    /// that all keys in our map must also be in the other map, with
651    /// the same values. To be a proper submap, ours must also contain
652    /// fewer keys than the other map.
653    ///
654    /// Time: O(n log n)
655    ///
656    /// # Examples
657    ///
658    /// ```
659    /// # #[macro_use] extern crate imbl;
660    /// # use imbl::hashmap::HashMap;
661    /// let map1 = hashmap!{1 => 1, 2 => 2};
662    /// let map2 = hashmap!{1 => 1, 2 => 2, 3 => 3};
663    /// assert!(map1.is_proper_submap(map2));
664    ///
665    /// let map3 = hashmap!{1 => 1, 2 => 2};
666    /// let map4 = hashmap!{1 => 1, 2 => 2};
667    /// assert!(!map3.is_proper_submap(map4));
668    /// ```
669    #[inline]
670    #[must_use]
671    pub fn is_proper_submap<RM>(&self, other: RM) -> bool
672    where
673        V: PartialEq,
674        RM: Borrow<Self>,
675    {
676        self.is_proper_submap_by(other.borrow(), PartialEq::eq)
677    }
678}
679
680impl<K, V, S, P> GenericHashMap<K, V, S, P>
681where
682    K: Hash + Eq + Clone,
683    V: Clone,
684    S: BuildHasher + Clone,
685    P: SharedPointerKind,
686{
687    /// Get a mutable iterator over the values of a hash map.
688    ///
689    /// Please note that the order is consistent between maps using
690    /// the same hasher, but no other ordering guarantee is offered.
691    /// Items will not come out in insertion order or sort order.
692    /// They will, however, come out in the same order every time for
693    /// the same map.
694    #[inline]
695    #[must_use]
696    pub fn iter_mut(&mut self) -> IterMut<'_, K, V, P> {
697        let root = self.root.as_mut().map(|r| SharedPointer::make_mut(r));
698        IterMut {
699            it: NodeIterMut::new(root, self.size),
700        }
701    }
702
703    /// Get a mutable reference to the value for a key from a hash
704    /// map.
705    ///
706    /// Time: O(log n)
707    ///
708    /// # Examples
709    ///
710    /// ```
711    /// # #[macro_use] extern crate imbl;
712    /// # use imbl::hashmap::HashMap;
713    /// let mut map = hashmap!{123 => "lol"};
714    /// if let Some(value) = map.get_mut(&123) {
715    ///     *value = "omg";
716    /// }
717    /// assert_eq!(
718    ///   map.get(&123),
719    ///   Some(&"omg")
720    /// );
721    /// ```
722    #[must_use]
723    pub fn get_mut<Q>(&mut self, key: &Q) -> Option<&mut V>
724    where
725        Q: Hash + Equivalent<K> + ?Sized,
726    {
727        self.get_key_value_mut(key).map(|(_, v)| v)
728    }
729
730    /// Get the key/value pair for a key from a hash map, returning a mutable reference to the value.
731    ///
732    /// Time: O(log n)
733    ///
734    /// # Examples
735    ///
736    /// ```
737    /// # #[macro_use] extern crate imbl;
738    /// # use imbl::hashmap::HashMap;
739    /// let mut map = hashmap!{123 => "lol"};
740    /// assert_eq!(
741    ///   map.get_key_value_mut(&123),
742    ///   Some((&123, &mut "lol"))
743    /// );
744    /// ```
745    #[must_use]
746    pub fn get_key_value_mut<Q>(&mut self, key: &Q) -> Option<(&K, &mut V)>
747    where
748        Q: Hash + Equivalent<K> + ?Sized,
749    {
750        let root = self.root.as_mut()?;
751        match SharedPointer::make_mut(root).get_mut(hash_key(&self.hasher, key), 0, key) {
752            None => None,
753            Some((key, value)) => Some((key, value)),
754        }
755    }
756
757    /// Insert a key/value mapping into a map.
758    ///
759    /// If the map already has a mapping for the given key, the
760    /// previous value is overwritten.
761    ///
762    /// Time: O(log n)
763    ///
764    /// # Examples
765    ///
766    /// ```
767    /// # #[macro_use] extern crate imbl;
768    /// # use imbl::hashmap::HashMap;
769    /// let mut map = hashmap!{};
770    /// map.insert(123, "123");
771    /// map.insert(456, "456");
772    /// assert_eq!(
773    ///   map,
774    ///   hashmap!{123 => "123", 456 => "456"}
775    /// );
776    /// ```
777    #[inline]
778    pub fn insert(&mut self, k: K, v: V) -> Option<V> {
779        let hash = hash_key(&self.hasher, &k);
780        let root = SharedPointer::make_mut(self.root.get_or_insert_with(SharedPointer::default));
781        let result = root.insert(hash, 0, (k, v));
782        if result.is_none() {
783            self.size += 1;
784        }
785        result.map(|(_, v)| v)
786    }
787
788    /// Remove a key/value pair from a map, if it exists, and return
789    /// the removed value.
790    ///
791    /// This is a copy-on-write operation, so that the parts of the
792    /// set's structure which are shared with other sets will be
793    /// safely copied before mutating.
794    ///
795    /// Time: O(log n)
796    ///
797    /// # Examples
798    ///
799    /// ```
800    /// # #[macro_use] extern crate imbl;
801    /// # use imbl::hashmap::HashMap;
802    /// let mut map = hashmap!{123 => "123", 456 => "456"};
803    /// assert_eq!(Some("123"), map.remove(&123));
804    /// assert_eq!(Some("456"), map.remove(&456));
805    /// assert_eq!(None, map.remove(&789));
806    /// assert!(map.is_empty());
807    /// ```
808    pub fn remove<Q>(&mut self, k: &Q) -> Option<V>
809    where
810        Q: Hash + Equivalent<K> + ?Sized,
811    {
812        self.remove_with_key(k).map(|(_, v)| v)
813    }
814
815    /// Remove a key/value pair from a map, if it exists, and return
816    /// the removed key and value.
817    ///
818    /// Time: O(log n)
819    ///
820    /// # Examples
821    ///
822    /// ```
823    /// # #[macro_use] extern crate imbl;
824    /// # use imbl::hashmap::HashMap;
825    /// let mut map = hashmap!{123 => "123", 456 => "456"};
826    /// assert_eq!(Some((123, "123")), map.remove_with_key(&123));
827    /// assert_eq!(Some((456, "456")), map.remove_with_key(&456));
828    /// assert_eq!(None, map.remove_with_key(&789));
829    /// assert!(map.is_empty());
830    /// ```
831    pub fn remove_with_key<Q>(&mut self, k: &Q) -> Option<(K, V)>
832    where
833        Q: Hash + Equivalent<K> + ?Sized,
834    {
835        let Some(root) = &mut self.root else {
836            return None;
837        };
838        let result = SharedPointer::make_mut(root).remove(hash_key(&self.hasher, k), 0, k);
839        if result.is_some() {
840            self.size -= 1;
841        }
842        result
843    }
844
845    /// Get the [`Entry`][Entry] for a key in the map for in-place manipulation.
846    ///
847    /// Time: O(log n)
848    ///
849    /// [Entry]: enum.Entry.html
850    #[must_use]
851    pub fn entry(&mut self, key: K) -> Entry<'_, K, V, S, P> {
852        let hash = hash_key(&self.hasher, &key);
853        if self
854            .root
855            .as_ref()
856            .and_then(|r| r.get(hash, 0, &key))
857            .is_some()
858        {
859            Entry::Occupied(OccupiedEntry {
860                map: self,
861                hash,
862                key,
863            })
864        } else {
865            Entry::Vacant(VacantEntry {
866                map: self,
867                hash,
868                key,
869            })
870        }
871    }
872
873    /// Construct a new hash map by inserting a key/value mapping into a map.
874    ///
875    /// If the map already has a mapping for the given key, the previous value
876    /// is overwritten.
877    ///
878    /// Time: O(log n)
879    ///
880    /// # Examples
881    ///
882    /// ```
883    /// # #[macro_use] extern crate imbl;
884    /// # use imbl::hashmap::HashMap;
885    /// let map = hashmap!{};
886    /// assert_eq!(
887    ///   map.update(123, "123"),
888    ///   hashmap!{123 => "123"}
889    /// );
890    /// ```
891    #[inline]
892    #[must_use]
893    pub fn update(&self, k: K, v: V) -> Self {
894        let mut out = self.clone();
895        out.insert(k, v);
896        out
897    }
898
899    /// Construct a new hash map by inserting a key/value mapping into
900    /// a map.
901    ///
902    /// If the map already has a mapping for the given key, we call
903    /// the provided function with the old value and the new value,
904    /// and insert the result as the new value.
905    ///
906    /// Time: O(log n)
907    #[must_use]
908    pub fn update_with<F>(&self, k: K, v: V, f: F) -> Self
909    where
910        F: FnOnce(V, V) -> V,
911    {
912        match self.extract_with_key(&k) {
913            None => self.update(k, v),
914            Some((_, v2, m)) => m.update(k, f(v2, v)),
915        }
916    }
917
918    /// Construct a new map by inserting a key/value mapping into a
919    /// map.
920    ///
921    /// If the map already has a mapping for the given key, we call
922    /// the provided function with the key, the old value and the new
923    /// value, and insert the result as the new value.
924    ///
925    /// Time: O(log n)
926    #[must_use]
927    pub fn update_with_key<F>(&self, k: K, v: V, f: F) -> Self
928    where
929        F: FnOnce(&K, V, V) -> V,
930    {
931        match self.extract_with_key(&k) {
932            None => self.update(k, v),
933            Some((_, v2, m)) => {
934                let out_v = f(&k, v2, v);
935                m.update(k, out_v)
936            }
937        }
938    }
939
940    /// Construct a new map by inserting a key/value mapping into a
941    /// map, returning the old value for the key as well as the new
942    /// map.
943    ///
944    /// If the map already has a mapping for the given key, we call
945    /// the provided function with the key, the old value and the new
946    /// value, and insert the result as the new value.
947    ///
948    /// Time: O(log n)
949    #[must_use]
950    pub fn update_lookup_with_key<F>(&self, k: K, v: V, f: F) -> (Option<V>, Self)
951    where
952        F: FnOnce(&K, &V, V) -> V,
953    {
954        match self.extract_with_key(&k) {
955            None => (None, self.update(k, v)),
956            Some((_, v2, m)) => {
957                let out_v = f(&k, &v2, v);
958                (Some(v2), m.update(k, out_v))
959            }
960        }
961    }
962
963    /// Update the value for a given key by calling a function with
964    /// the current value and overwriting it with the function's
965    /// return value.
966    ///
967    /// The function gets an [`Option<V>`][std::option::Option] and
968    /// returns the same, so that it can decide to delete a mapping
969    /// instead of updating the value, and decide what to do if the
970    /// key isn't in the map.
971    ///
972    /// Time: O(log n)
973    ///
974    /// [std::option::Option]: https://doc.rust-lang.org/std/option/enum.Option.html
975    #[must_use]
976    pub fn alter<F>(&self, f: F, k: K) -> Self
977    where
978        F: FnOnce(Option<V>) -> Option<V>,
979    {
980        let pop = self.extract_with_key(&k);
981        match (f(pop.as_ref().map(|(_, v, _)| v.clone())), pop) {
982            (None, None) => self.clone(),
983            (Some(v), None) => self.update(k, v),
984            (None, Some((_, _, m))) => m,
985            (Some(v), Some((_, _, m))) => m.update(k, v),
986        }
987    }
988
989    /// Construct a new map without the given key.
990    ///
991    /// Construct a map that's a copy of the current map, absent the
992    /// mapping for `key` if it's present.
993    ///
994    /// Time: O(log n)
995    #[must_use]
996    pub fn without<Q>(&self, k: &Q) -> Self
997    where
998        Q: Hash + Equivalent<K> + ?Sized,
999    {
1000        match self.extract_with_key(k) {
1001            None => self.clone(),
1002            Some((_, _, map)) => map,
1003        }
1004    }
1005
1006    /// Filter out values from a map which don't satisfy a predicate.
1007    ///
1008    /// This is slightly more efficient than filtering using an
1009    /// iterator, in that it doesn't need to rehash the retained
1010    /// values, but it still needs to reconstruct the entire tree
1011    /// structure of the map.
1012    ///
1013    /// Time: O(n log n)
1014    ///
1015    /// # Examples
1016    ///
1017    /// ```
1018    /// # #[macro_use] extern crate imbl;
1019    /// # use imbl::HashMap;
1020    /// let mut map = hashmap!{1 => 1, 2 => 2, 3 => 3};
1021    /// map.retain(|k, v| *k > 1);
1022    /// let expected = hashmap!{2 => 2, 3 => 3};
1023    /// assert_eq!(expected, map);
1024    /// ```
1025    pub fn retain<F>(&mut self, mut f: F)
1026    where
1027        F: FnMut(&K, &V) -> bool,
1028    {
1029        let Some(root) = &mut self.root else {
1030            return;
1031        };
1032        let old_root = root.clone();
1033        let root = SharedPointer::make_mut(root);
1034        for ((key, value), hash) in NodeIter::new(Some(&old_root), self.size) {
1035            if !f(key, value) && root.remove(hash, 0, key).is_some() {
1036                self.size -= 1;
1037            }
1038        }
1039    }
1040
1041    /// Remove a key/value pair from a map, if it exists, and return
1042    /// the removed value as well as the updated map.
1043    ///
1044    /// Time: O(log n)
1045    #[must_use]
1046    pub fn extract<Q>(&self, k: &Q) -> Option<(V, Self)>
1047    where
1048        Q: Hash + Equivalent<K> + ?Sized,
1049    {
1050        self.extract_with_key(k).map(|(_, v, m)| (v, m))
1051    }
1052
1053    /// Remove a key/value pair from a map, if it exists, and return
1054    /// the removed key and value as well as the updated list.
1055    ///
1056    /// Time: O(log n)
1057    #[must_use]
1058    pub fn extract_with_key<Q>(&self, k: &Q) -> Option<(K, V, Self)>
1059    where
1060        Q: Hash + Equivalent<K> + ?Sized,
1061    {
1062        let mut out = self.clone();
1063        out.remove_with_key(k).map(|(k, v)| (k, v, out))
1064    }
1065
1066    /// Construct the union of two maps, keeping the values in the
1067    /// current map when keys exist in both maps.
1068    ///
1069    /// Time: O(n log n)
1070    ///
1071    /// # Examples
1072    ///
1073    /// ```
1074    /// # #[macro_use] extern crate imbl;
1075    /// # use imbl::hashmap::HashMap;
1076    /// let map1 = hashmap!{1 => 1, 3 => 3};
1077    /// let map2 = hashmap!{2 => 2, 3 => 4};
1078    /// let expected = hashmap!{1 => 1, 2 => 2, 3 => 3};
1079    /// assert_eq!(expected, map1.union(map2));
1080    /// ```
1081    #[must_use]
1082    pub fn union(self, other: Self) -> Self {
1083        let (mut to_mutate, to_consume, use_to_consume) = if self.len() >= other.len() {
1084            (self, other, false)
1085        } else {
1086            (other, self, true)
1087        };
1088        for (k, v) in to_consume {
1089            match to_mutate.entry(k) {
1090                Entry::Occupied(mut e) if use_to_consume => {
1091                    e.insert(v);
1092                }
1093                Entry::Vacant(e) => {
1094                    e.insert(v);
1095                }
1096                _ => {}
1097            }
1098        }
1099        to_mutate
1100    }
1101
1102    /// Construct the union of two maps, using a function to decide
1103    /// what to do with the value when a key is in both maps.
1104    ///
1105    /// The function is called when a value exists in both maps, and
1106    /// receives the value from the current map as its first argument,
1107    /// and the value from the other map as the second. It should
1108    /// return the value to be inserted in the resulting map.
1109    ///
1110    /// Time: O(n log n)
1111    #[inline]
1112    #[must_use]
1113    pub fn union_with<F>(self, other: Self, mut f: F) -> Self
1114    where
1115        F: FnMut(V, V) -> V,
1116    {
1117        self.union_with_key(other, |_, v1, v2| f(v1, v2))
1118    }
1119
1120    /// Construct the union of two maps, using a function to decide
1121    /// what to do with the value when a key is in both maps.
1122    ///
1123    /// The function is called when a value exists in both maps, and
1124    /// receives a reference to the key as its first argument, the
1125    /// value from the current map as the second argument, and the
1126    /// value from the other map as the third argument. It should
1127    /// return the value to be inserted in the resulting map.
1128    ///
1129    /// Time: O(n log n)
1130    ///
1131    /// # Examples
1132    ///
1133    /// ```
1134    /// # #[macro_use] extern crate imbl;
1135    /// # use imbl::hashmap::HashMap;
1136    /// let map1 = hashmap!{1 => 1, 3 => 4};
1137    /// let map2 = hashmap!{2 => 2, 3 => 5};
1138    /// let expected = hashmap!{1 => 1, 2 => 2, 3 => 9};
1139    /// assert_eq!(expected, map1.union_with_key(
1140    ///     map2,
1141    ///     |key, left, right| left + right
1142    /// ));
1143    /// ```
1144    #[must_use]
1145    pub fn union_with_key<F>(self, other: Self, mut f: F) -> Self
1146    where
1147        F: FnMut(&K, V, V) -> V,
1148    {
1149        if self.len() >= other.len() {
1150            self.union_with_key_inner(other, f)
1151        } else {
1152            other.union_with_key_inner(self, |key, other_value, self_value| {
1153                f(key, self_value, other_value)
1154            })
1155        }
1156    }
1157
1158    fn union_with_key_inner<F>(mut self, other: Self, mut f: F) -> Self
1159    where
1160        F: FnMut(&K, V, V) -> V,
1161    {
1162        for (key, right_value) in other {
1163            match self.remove(&key) {
1164                None => {
1165                    self.insert(key, right_value);
1166                }
1167                Some(left_value) => {
1168                    let final_value = f(&key, left_value, right_value);
1169                    self.insert(key, final_value);
1170                }
1171            }
1172        }
1173        self
1174    }
1175
1176    /// Construct the union of a sequence of maps, selecting the value
1177    /// of the leftmost when a key appears in more than one map.
1178    ///
1179    /// Time: O(n log n)
1180    ///
1181    /// # Examples
1182    ///
1183    /// ```
1184    /// # #[macro_use] extern crate imbl;
1185    /// # use imbl::hashmap::HashMap;
1186    /// let map1 = hashmap!{1 => 1, 3 => 3};
1187    /// let map2 = hashmap!{2 => 2};
1188    /// let expected = hashmap!{1 => 1, 2 => 2, 3 => 3};
1189    /// assert_eq!(expected, HashMap::unions(vec![map1, map2]));
1190    /// ```
1191    #[must_use]
1192    pub fn unions<I>(i: I) -> Self
1193    where
1194        S: Default,
1195        I: IntoIterator<Item = Self>,
1196    {
1197        i.into_iter().fold(Self::default(), Self::union)
1198    }
1199
1200    /// Construct the union of a sequence of maps, using a function to
1201    /// decide what to do with the value when a key is in more than
1202    /// one map.
1203    ///
1204    /// The function is called when a value exists in multiple maps,
1205    /// and receives the value from the current map as its first
1206    /// argument, and the value from the next map as the second. It
1207    /// should return the value to be inserted in the resulting map.
1208    ///
1209    /// Time: O(n log n)
1210    #[must_use]
1211    pub fn unions_with<I, F>(i: I, f: F) -> Self
1212    where
1213        S: Default,
1214        I: IntoIterator<Item = Self>,
1215        F: Fn(V, V) -> V,
1216    {
1217        i.into_iter()
1218            .fold(Self::default(), |a, b| a.union_with(b, &f))
1219    }
1220
1221    /// Construct the union of a sequence of maps, using a function to
1222    /// decide what to do with the value when a key is in more than
1223    /// one map.
1224    ///
1225    /// The function is called when a value exists in multiple maps,
1226    /// and receives a reference to the key as its first argument, the
1227    /// value from the current map as the second argument, and the
1228    /// value from the next map as the third argument. It should
1229    /// return the value to be inserted in the resulting map.
1230    ///
1231    /// Time: O(n log n)
1232    #[must_use]
1233    pub fn unions_with_key<I, F>(i: I, f: F) -> Self
1234    where
1235        S: Default,
1236        I: IntoIterator<Item = Self>,
1237        F: Fn(&K, V, V) -> V,
1238    {
1239        i.into_iter()
1240            .fold(Self::default(), |a, b| a.union_with_key(b, &f))
1241    }
1242
1243    /// Construct the symmetric difference between two maps by discarding keys
1244    /// which occur in both maps.
1245    ///
1246    /// This is an alias for the
1247    /// [`symmetric_difference`][symmetric_difference] method.
1248    ///
1249    /// Time: O(n log n)
1250    ///
1251    /// # Examples
1252    ///
1253    /// ```
1254    /// # #[macro_use] extern crate imbl;
1255    /// # use imbl::hashmap::HashMap;
1256    /// let map1 = hashmap!{1 => 1, 3 => 4};
1257    /// let map2 = hashmap!{2 => 2, 3 => 5};
1258    /// let expected = hashmap!{1 => 1, 2 => 2};
1259    /// assert_eq!(expected, map1.difference(map2));
1260    /// ```
1261    ///
1262    /// [symmetric_difference]: #method.symmetric_difference
1263    #[deprecated(
1264        since = "2.0.1",
1265        note = "to avoid conflicting behaviors between std and imbl, the `difference` alias for `symmetric_difference` will be removed."
1266    )]
1267    #[inline]
1268    #[must_use]
1269    pub fn difference(self, other: Self) -> Self {
1270        self.symmetric_difference(other)
1271    }
1272
1273    /// Construct the symmetric difference between two maps by discarding keys
1274    /// which occur in both maps.
1275    ///
1276    /// Time: O(n log n)
1277    ///
1278    /// # Examples
1279    ///
1280    /// ```
1281    /// # #[macro_use] extern crate imbl;
1282    /// # use imbl::hashmap::HashMap;
1283    /// let map1 = hashmap!{1 => 1, 3 => 4};
1284    /// let map2 = hashmap!{2 => 2, 3 => 5};
1285    /// let expected = hashmap!{1 => 1, 2 => 2};
1286    /// assert_eq!(expected, map1.symmetric_difference(map2));
1287    /// ```
1288    #[inline]
1289    #[must_use]
1290    pub fn symmetric_difference(self, other: Self) -> Self {
1291        self.symmetric_difference_with_key(other, |_, _, _| None)
1292    }
1293
1294    /// Construct the symmetric difference between two maps by using a function
1295    /// to decide what to do if a key occurs in both.
1296    ///
1297    /// This is an alias for the
1298    /// [`symmetric_difference_with`][symmetric_difference_with] method.
1299    ///
1300    /// Time: O(n log n)
1301    ///
1302    /// [symmetric_difference_with]: #method.symmetric_difference_with
1303    #[deprecated(
1304        since = "2.0.1",
1305        note = "to avoid conflicting behaviors between std and imbl, the `difference_with` alias for `symmetric_difference_with` will be removed."
1306    )]
1307    #[inline]
1308    #[must_use]
1309    pub fn difference_with<F>(self, other: Self, f: F) -> Self
1310    where
1311        F: FnMut(V, V) -> Option<V>,
1312    {
1313        self.symmetric_difference_with(other, f)
1314    }
1315
1316    /// Construct the symmetric difference between two maps by using a function
1317    /// to decide what to do if a key occurs in both.
1318    ///
1319    /// Time: O(n log n)
1320    #[inline]
1321    #[must_use]
1322    pub fn symmetric_difference_with<F>(self, other: Self, mut f: F) -> Self
1323    where
1324        F: FnMut(V, V) -> Option<V>,
1325    {
1326        self.symmetric_difference_with_key(other, |_, a, b| f(a, b))
1327    }
1328
1329    /// Construct the symmetric difference between two maps by using a function
1330    /// to decide what to do if a key occurs in both. The function
1331    /// receives the key as well as both values.
1332    ///
1333    /// This is an alias for the
1334    /// [`symmetric_difference_with`_key][symmetric_difference_with_key]
1335    /// method.
1336    ///
1337    /// Time: O(n log n)
1338    ///
1339    /// # Examples
1340    ///
1341    /// ```
1342    /// # #[macro_use] extern crate imbl;
1343    /// # use imbl::hashmap::HashMap;
1344    /// let map1 = hashmap!{1 => 1, 3 => 4};
1345    /// let map2 = hashmap!{2 => 2, 3 => 5};
1346    /// let expected = hashmap!{1 => 1, 2 => 2, 3 => 9};
1347    /// assert_eq!(expected, map1.difference_with_key(
1348    ///     map2,
1349    ///     |key, left, right| Some(left + right)
1350    /// ));
1351    /// ```
1352    ///
1353    /// [symmetric_difference_with_key]: #method.symmetric_difference_with_key
1354    #[deprecated(
1355        since = "2.0.1",
1356        note = "to avoid conflicting behaviors between std and imbl, the `difference_with_key` alias for `symmetric_difference_with_key` will be removed."
1357    )]
1358    #[must_use]
1359    pub fn difference_with_key<F>(self, other: Self, f: F) -> Self
1360    where
1361        F: FnMut(&K, V, V) -> Option<V>,
1362    {
1363        self.symmetric_difference_with_key(other, f)
1364    }
1365
1366    /// Construct the symmetric difference between two maps by using a function
1367    /// to decide what to do if a key occurs in both. The function
1368    /// receives the key as well as both values.
1369    ///
1370    /// Time: O(n log n)
1371    ///
1372    /// # Examples
1373    ///
1374    /// ```
1375    /// # #[macro_use] extern crate imbl;
1376    /// # use imbl::hashmap::HashMap;
1377    /// let map1 = hashmap!{1 => 1, 3 => 4};
1378    /// let map2 = hashmap!{2 => 2, 3 => 5};
1379    /// let expected = hashmap!{1 => 1, 2 => 2, 3 => 9};
1380    /// assert_eq!(expected, map1.symmetric_difference_with_key(
1381    ///     map2,
1382    ///     |key, left, right| Some(left + right)
1383    /// ));
1384    /// ```
1385    #[must_use]
1386    pub fn symmetric_difference_with_key<F>(mut self, other: Self, mut f: F) -> Self
1387    where
1388        F: FnMut(&K, V, V) -> Option<V>,
1389    {
1390        let mut out = self.new_from();
1391        for (key, right_value) in other {
1392            match self.remove(&key) {
1393                None => {
1394                    out.insert(key, right_value);
1395                }
1396                Some(left_value) => {
1397                    if let Some(final_value) = f(&key, left_value, right_value) {
1398                        out.insert(key, final_value);
1399                    }
1400                }
1401            }
1402        }
1403        out.union(self)
1404    }
1405
1406    /// Construct the relative complement between two maps by discarding keys
1407    /// which occur in `other`.
1408    ///
1409    /// Time: O(m log n) where m is the size of the other map
1410    ///
1411    /// # Examples
1412    ///
1413    /// ```
1414    /// # #[macro_use] extern crate imbl;
1415    /// # use imbl::hashmap::HashMap;
1416    /// let map1 = hashmap!{1 => 1, 3 => 4};
1417    /// let map2 = hashmap!{2 => 2, 3 => 5};
1418    /// let expected = hashmap!{1 => 1};
1419    /// assert_eq!(expected, map1.relative_complement(map2));
1420    /// ```
1421    #[inline]
1422    #[must_use]
1423    pub fn relative_complement(mut self, other: Self) -> Self {
1424        for (key, _) in other {
1425            let _ = self.remove(&key);
1426        }
1427        self
1428    }
1429
1430    /// Construct the intersection of two maps, keeping the values
1431    /// from the current map.
1432    ///
1433    /// Time: O(n log n)
1434    ///
1435    /// # Examples
1436    ///
1437    /// ```
1438    /// # #[macro_use] extern crate imbl;
1439    /// # use imbl::hashmap::HashMap;
1440    /// let map1 = hashmap!{1 => 1, 2 => 2};
1441    /// let map2 = hashmap!{2 => 3, 3 => 4};
1442    /// let expected = hashmap!{2 => 2};
1443    /// assert_eq!(expected, map1.intersection(map2));
1444    /// ```
1445    #[inline]
1446    #[must_use]
1447    pub fn intersection(self, other: Self) -> Self {
1448        self.intersection_with_key(other, |_, v, _| v)
1449    }
1450
1451    /// Construct the intersection of two maps, calling a function
1452    /// with both values for each key and using the result as the
1453    /// value for the key.
1454    ///
1455    /// Time: O(n log n)
1456    #[inline]
1457    #[must_use]
1458    pub fn intersection_with<B, C, F>(
1459        self,
1460        other: GenericHashMap<K, B, S, P>,
1461        mut f: F,
1462    ) -> GenericHashMap<K, C, S, P>
1463    where
1464        B: Clone,
1465        C: Clone,
1466        F: FnMut(V, B) -> C,
1467    {
1468        self.intersection_with_key(other, |_, v1, v2| f(v1, v2))
1469    }
1470
1471    /// Construct the intersection of two maps, calling a function
1472    /// with the key and both values for each key and using the result
1473    /// as the value for the key.
1474    ///
1475    /// Time: O(n log n)
1476    ///
1477    /// # Examples
1478    ///
1479    /// ```
1480    /// # #[macro_use] extern crate imbl;
1481    /// # use imbl::hashmap::HashMap;
1482    /// let map1 = hashmap!{1 => 1, 2 => 2};
1483    /// let map2 = hashmap!{2 => 3, 3 => 4};
1484    /// let expected = hashmap!{2 => 5};
1485    /// assert_eq!(expected, map1.intersection_with_key(
1486    ///     map2,
1487    ///     |key, left, right| left + right
1488    /// ));
1489    /// ```
1490    #[must_use]
1491    pub fn intersection_with_key<B, C, F>(
1492        mut self,
1493        other: GenericHashMap<K, B, S, P>,
1494        mut f: F,
1495    ) -> GenericHashMap<K, C, S, P>
1496    where
1497        B: Clone,
1498        C: Clone,
1499        F: FnMut(&K, V, B) -> C,
1500    {
1501        let mut out = self.new_from();
1502        for (key, right_value) in other {
1503            match self.remove(&key) {
1504                None => (),
1505                Some(left_value) => {
1506                    let result = f(&key, left_value, right_value);
1507                    out.insert(key, result);
1508                }
1509            }
1510        }
1511        out
1512    }
1513}
1514
1515// Entries
1516
1517/// A handle for a key and its associated value.
1518///
1519/// ## Performance Note
1520///
1521/// When using an `Entry`, the key is only ever hashed once, when you
1522/// create the `Entry`. Operations on an `Entry` will never trigger a
1523/// rehash, where eg. a `contains_key(key)` followed by an
1524/// `insert(key, default_value)` (the equivalent of
1525/// `Entry::or_insert()`) would need to hash the key once for the
1526/// `contains_key` and again for the `insert`. The operations
1527/// generally perform similarly otherwise.
1528pub enum Entry<'a, K, V, S, P>
1529where
1530    K: Hash + Eq + Clone,
1531    V: Clone,
1532    S: BuildHasher + Clone,
1533    P: SharedPointerKind,
1534{
1535    /// An entry which exists in the map.
1536    Occupied(OccupiedEntry<'a, K, V, S, P>),
1537    /// An entry which doesn't exist in the map.
1538    Vacant(VacantEntry<'a, K, V, S, P>),
1539}
1540
1541impl<'a, K, V, S, P> Entry<'a, K, V, S, P>
1542where
1543    K: 'a + Hash + Eq + Clone,
1544    V: 'a + Clone,
1545    S: 'a + BuildHasher + Clone,
1546    P: SharedPointerKind,
1547{
1548    /// Insert the default value provided if there was no value
1549    /// already, and return a mutable reference to the value.
1550    pub fn or_insert(self, default: V) -> &'a mut V {
1551        self.or_insert_with(|| default)
1552    }
1553
1554    /// Insert the default value from the provided function if there
1555    /// was no value already, and return a mutable reference to the
1556    /// value.
1557    pub fn or_insert_with<F>(self, default: F) -> &'a mut V
1558    where
1559        F: FnOnce() -> V,
1560    {
1561        match self {
1562            Entry::Occupied(entry) => entry.into_mut(),
1563            Entry::Vacant(entry) => entry.insert(default()),
1564        }
1565    }
1566
1567    /// Insert a default value if there was no value already, and
1568    /// return a mutable reference to the value.
1569    pub fn or_default(self) -> &'a mut V
1570    where
1571        V: Default,
1572    {
1573        #[allow(clippy::unwrap_or_default)]
1574        self.or_insert_with(Default::default)
1575    }
1576
1577    /// Get the key for this entry.
1578    #[must_use]
1579    pub fn key(&self) -> &K {
1580        match self {
1581            Entry::Occupied(entry) => entry.key(),
1582            Entry::Vacant(entry) => entry.key(),
1583        }
1584    }
1585
1586    /// Call the provided function to modify the value if the value
1587    /// exists.
1588    pub fn and_modify<F>(mut self, f: F) -> Self
1589    where
1590        F: FnOnce(&mut V),
1591    {
1592        match &mut self {
1593            Entry::Occupied(ref mut entry) => f(entry.get_mut()),
1594            Entry::Vacant(_) => (),
1595        }
1596        self
1597    }
1598}
1599
1600/// An entry for a mapping that already exists in the map.
1601pub struct OccupiedEntry<'a, K, V, S, P>
1602where
1603    K: Hash + Eq + Clone,
1604    V: Clone,
1605    S: BuildHasher + Clone,
1606    P: SharedPointerKind,
1607{
1608    map: &'a mut GenericHashMap<K, V, S, P>,
1609    hash: HashBits,
1610    key: K,
1611}
1612
1613impl<'a, K, V, S, P> OccupiedEntry<'a, K, V, S, P>
1614where
1615    K: 'a + Hash + Eq + Clone,
1616    V: 'a + Clone,
1617    S: 'a + BuildHasher + Clone,
1618    P: SharedPointerKind,
1619{
1620    /// Get the key for this entry.
1621    #[must_use]
1622    pub fn key(&self) -> &K {
1623        &self.key
1624    }
1625
1626    /// Remove this entry from the map and return the removed mapping.
1627    pub fn remove_entry(self) -> (K, V) {
1628        // unwrap: occupied entries can only be created for non-empty maps
1629        let root = SharedPointer::make_mut(self.map.root.as_mut().unwrap());
1630        let result = root.remove(self.hash, 0, &self.key);
1631        self.map.size -= 1;
1632        result.unwrap()
1633    }
1634
1635    /// Get the current value.
1636    #[must_use]
1637    pub fn get(&self) -> &V {
1638        // unwrap: occupied entries can only be created for non-empty maps
1639        &self
1640            .map
1641            .root
1642            .as_ref()
1643            .unwrap()
1644            .get(self.hash, 0, &self.key)
1645            .unwrap()
1646            .1
1647    }
1648
1649    /// Get a mutable reference to the current value.
1650    #[must_use]
1651    pub fn get_mut(&mut self) -> &mut V {
1652        // unwrap: occupied entries can only be created for non-empty maps
1653        let root = SharedPointer::make_mut(self.map.root.as_mut().unwrap());
1654        &mut root.get_mut(self.hash, 0, &self.key).unwrap().1
1655    }
1656
1657    /// Convert this entry into a mutable reference.
1658    #[must_use]
1659    pub fn into_mut(self) -> &'a mut V {
1660        // unwrap: occupied entries can only be created for non-empty maps
1661        let root = SharedPointer::make_mut(self.map.root.as_mut().unwrap());
1662        &mut root.get_mut(self.hash, 0, &self.key).unwrap().1
1663    }
1664
1665    /// Overwrite the current value.
1666    pub fn insert(&mut self, value: V) -> V {
1667        mem::replace(self.get_mut(), value)
1668    }
1669
1670    /// Remove this entry from the map and return the removed value.
1671    pub fn remove(self) -> V {
1672        self.remove_entry().1
1673    }
1674}
1675
1676/// An entry for a mapping that does not already exist in the map.
1677pub struct VacantEntry<'a, K, V, S, P>
1678where
1679    K: Hash + Eq + Clone,
1680    V: Clone,
1681    S: BuildHasher + Clone,
1682    P: SharedPointerKind,
1683{
1684    map: &'a mut GenericHashMap<K, V, S, P>,
1685    hash: HashBits,
1686    key: K,
1687}
1688
1689impl<'a, K, V, S, P> VacantEntry<'a, K, V, S, P>
1690where
1691    K: 'a + Hash + Eq + Clone,
1692    V: 'a + Clone,
1693    S: 'a + BuildHasher + Clone,
1694    P: SharedPointerKind,
1695{
1696    /// Get the key for this entry.
1697    #[must_use]
1698    pub fn key(&self) -> &K {
1699        &self.key
1700    }
1701
1702    /// Convert this entry into its key.
1703    #[must_use]
1704    pub fn into_key(self) -> K {
1705        self.key
1706    }
1707
1708    /// Insert a value into this entry.
1709    pub fn insert(self, value: V) -> &'a mut V {
1710        let root =
1711            SharedPointer::make_mut(self.map.root.get_or_insert_with(SharedPointer::default));
1712        if root
1713            .insert(self.hash, 0, (self.key.clone(), value))
1714            .is_none()
1715        {
1716            self.map.size += 1;
1717        }
1718        // TODO it's unfortunate that we need to look up the key again
1719        // here to get the mut ref.
1720        &mut root.get_mut(self.hash, 0, &self.key).unwrap().1
1721    }
1722}
1723
1724// Core traits
1725
1726impl<K, V, S, P> Clone for GenericHashMap<K, V, S, P>
1727where
1728    K: Clone,
1729    V: Clone,
1730    S: Clone,
1731    P: SharedPointerKind,
1732{
1733    /// Clone a map.
1734    ///
1735    /// Time: O(1)
1736    #[inline]
1737    fn clone(&self) -> Self {
1738        GenericHashMap {
1739            root: self.root.clone(),
1740            size: self.size,
1741            hasher: self.hasher.clone(),
1742        }
1743    }
1744}
1745
1746impl<K, V, S1, S2, P1, P2> PartialEq<GenericHashMap<K, V, S2, P2>> for GenericHashMap<K, V, S1, P1>
1747where
1748    K: Hash + Eq,
1749    V: PartialEq,
1750    S1: BuildHasher + Clone,
1751    S2: BuildHasher + Clone,
1752    P1: SharedPointerKind,
1753    P2: SharedPointerKind,
1754{
1755    fn eq(&self, other: &GenericHashMap<K, V, S2, P2>) -> bool {
1756        self.test_eq(other)
1757    }
1758}
1759
1760impl<K, V, S, P> Eq for GenericHashMap<K, V, S, P>
1761where
1762    K: Hash + Eq,
1763    V: Eq,
1764    S: BuildHasher + Clone,
1765    P: SharedPointerKind,
1766{
1767}
1768
1769impl<K, V, S, P> Default for GenericHashMap<K, V, S, P>
1770where
1771    S: Default,
1772    P: SharedPointerKind,
1773{
1774    #[inline]
1775    fn default() -> Self {
1776        GenericHashMap {
1777            size: 0,
1778            root: None,
1779            hasher: Default::default(),
1780        }
1781    }
1782}
1783
1784impl<K, V, S, P> Add for GenericHashMap<K, V, S, P>
1785where
1786    K: Hash + Eq + Clone,
1787    V: Clone,
1788    S: BuildHasher + Clone,
1789    P: SharedPointerKind,
1790{
1791    type Output = GenericHashMap<K, V, S, P>;
1792
1793    fn add(self, other: Self) -> Self::Output {
1794        self.union(other)
1795    }
1796}
1797
1798impl<K, V, S, P> Add for &GenericHashMap<K, V, S, P>
1799where
1800    K: Hash + Eq + Clone,
1801    V: Clone,
1802    S: BuildHasher + Clone,
1803    P: SharedPointerKind,
1804{
1805    type Output = GenericHashMap<K, V, S, P>;
1806
1807    fn add(self, other: Self) -> Self::Output {
1808        self.clone().union(other.clone())
1809    }
1810}
1811
1812impl<K, V, S, P> Sum for GenericHashMap<K, V, S, P>
1813where
1814    K: Hash + Eq + Clone,
1815    V: Clone,
1816    S: BuildHasher + Default + Clone,
1817    P: SharedPointerKind,
1818{
1819    fn sum<I>(it: I) -> Self
1820    where
1821        I: Iterator<Item = Self>,
1822    {
1823        it.fold(Self::default(), |a, b| a + b)
1824    }
1825}
1826
1827impl<K, V, S, RK, RV, P> Extend<(RK, RV)> for GenericHashMap<K, V, S, P>
1828where
1829    K: Hash + Eq + Clone + From<RK>,
1830    V: Clone + From<RV>,
1831    S: BuildHasher + Clone,
1832    P: SharedPointerKind,
1833{
1834    fn extend<I>(&mut self, iter: I)
1835    where
1836        I: IntoIterator<Item = (RK, RV)>,
1837    {
1838        for (key, value) in iter {
1839            self.insert(From::from(key), From::from(value));
1840        }
1841    }
1842}
1843
1844impl<Q, K, V, S, P> Index<&Q> for GenericHashMap<K, V, S, P>
1845where
1846    Q: Hash + Equivalent<K> + ?Sized,
1847    K: Hash + Eq,
1848    S: BuildHasher + Clone,
1849    P: SharedPointerKind,
1850{
1851    type Output = V;
1852
1853    fn index(&self, key: &Q) -> &Self::Output {
1854        match self.get(key) {
1855            None => panic!("HashMap::index: invalid key"),
1856            Some(value) => value,
1857        }
1858    }
1859}
1860
1861impl<Q, K, V, S, P> IndexMut<&Q> for GenericHashMap<K, V, S, P>
1862where
1863    Q: Hash + Equivalent<K> + ?Sized,
1864    K: Hash + Eq + Clone,
1865    V: Clone,
1866    S: BuildHasher + Clone,
1867    P: SharedPointerKind,
1868{
1869    fn index_mut(&mut self, key: &Q) -> &mut Self::Output {
1870        match self.get_mut(key) {
1871            None => panic!("HashMap::index_mut: invalid key"),
1872            Some(value) => value,
1873        }
1874    }
1875}
1876
1877impl<K, V, S, P> Debug for GenericHashMap<K, V, S, P>
1878where
1879    K: Debug,
1880    V: Debug,
1881    P: SharedPointerKind,
1882{
1883    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {
1884        let mut d = f.debug_map();
1885        for (k, v) in self {
1886            d.entry(k, v);
1887        }
1888        d.finish()
1889    }
1890}
1891
1892// // Iterators
1893
1894/// An iterator over the elements of a map.
1895pub struct Iter<'a, K, V, P: SharedPointerKind> {
1896    it: NodeIter<'a, (K, V), P>,
1897}
1898
1899// We impl Clone instead of deriving it, because we want Clone even if K and V aren't.
1900impl<'a, K, V, P: SharedPointerKind> Clone for Iter<'a, K, V, P> {
1901    fn clone(&self) -> Self {
1902        Iter {
1903            it: self.it.clone(),
1904        }
1905    }
1906}
1907
1908impl<'a, K, V, P: SharedPointerKind> Iterator for Iter<'a, K, V, P> {
1909    type Item = (&'a K, &'a V);
1910
1911    fn next(&mut self) -> Option<Self::Item> {
1912        self.it.next().map(|((k, v), _)| (k, v))
1913    }
1914
1915    fn size_hint(&self) -> (usize, Option<usize>) {
1916        self.it.size_hint()
1917    }
1918}
1919
1920impl<'a, K, V, P: SharedPointerKind> ExactSizeIterator for Iter<'a, K, V, P> {}
1921
1922impl<'a, K, V, P: SharedPointerKind> FusedIterator for Iter<'a, K, V, P> {}
1923
1924/// A mutable iterator over the elements of a map.
1925pub struct IterMut<'a, K, V, P>
1926where
1927    K: Clone,
1928    V: Clone,
1929    P: SharedPointerKind,
1930{
1931    it: NodeIterMut<'a, (K, V), P>,
1932}
1933
1934impl<'a, K, V, P> Iterator for IterMut<'a, K, V, P>
1935where
1936    K: Clone,
1937    V: Clone,
1938    P: SharedPointerKind,
1939{
1940    type Item = (&'a K, &'a mut V);
1941
1942    fn next(&mut self) -> Option<Self::Item> {
1943        self.it.next().map(|((k, v), _)| (&*k, v))
1944    }
1945
1946    fn size_hint(&self) -> (usize, Option<usize>) {
1947        self.it.size_hint()
1948    }
1949}
1950
1951impl<'a, K, V, P> ExactSizeIterator for IterMut<'a, K, V, P>
1952where
1953    K: Clone,
1954    V: Clone,
1955    P: SharedPointerKind,
1956{
1957}
1958
1959impl<'a, K, V, P> FusedIterator for IterMut<'a, K, V, P>
1960where
1961    K: Clone,
1962    V: Clone,
1963    P: SharedPointerKind,
1964{
1965}
1966
1967/// A consuming iterator over the elements of a map.
1968pub struct ConsumingIter<A: HashValue, P: SharedPointerKind> {
1969    it: NodeDrain<A, P>,
1970}
1971
1972impl<A, P: SharedPointerKind> Iterator for ConsumingIter<A, P>
1973where
1974    A: HashValue + Clone,
1975{
1976    type Item = A;
1977
1978    fn next(&mut self) -> Option<Self::Item> {
1979        self.it.next().map(|(p, _)| p)
1980    }
1981
1982    fn size_hint(&self) -> (usize, Option<usize>) {
1983        self.it.size_hint()
1984    }
1985}
1986
1987impl<A, P> ExactSizeIterator for ConsumingIter<A, P>
1988where
1989    A: HashValue + Clone,
1990    P: SharedPointerKind,
1991{
1992}
1993
1994impl<A, P> FusedIterator for ConsumingIter<A, P>
1995where
1996    A: HashValue + Clone,
1997    P: SharedPointerKind,
1998{
1999}
2000
2001/// An iterator over the keys of a map.
2002pub struct Keys<'a, K, V, P: SharedPointerKind> {
2003    it: NodeIter<'a, (K, V), P>,
2004}
2005
2006impl<'a, K, V, P: SharedPointerKind> Iterator for Keys<'a, K, V, P> {
2007    type Item = &'a K;
2008
2009    fn next(&mut self) -> Option<Self::Item> {
2010        self.it.next().map(|((k, _), _)| k)
2011    }
2012
2013    fn size_hint(&self) -> (usize, Option<usize>) {
2014        self.it.size_hint()
2015    }
2016}
2017
2018impl<'a, K, V, P: SharedPointerKind> ExactSizeIterator for Keys<'a, K, V, P> {}
2019
2020impl<'a, K, V, P: SharedPointerKind> FusedIterator for Keys<'a, K, V, P> {}
2021
2022/// An iterator over the values of a map.
2023pub struct Values<'a, K, V, P: SharedPointerKind> {
2024    it: NodeIter<'a, (K, V), P>,
2025}
2026
2027impl<'a, K, V, P: SharedPointerKind> Iterator for Values<'a, K, V, P> {
2028    type Item = &'a V;
2029
2030    fn next(&mut self) -> Option<Self::Item> {
2031        self.it.next().map(|((_, v), _)| v)
2032    }
2033
2034    fn size_hint(&self) -> (usize, Option<usize>) {
2035        self.it.size_hint()
2036    }
2037}
2038
2039impl<'a, K, V, P: SharedPointerKind> ExactSizeIterator for Values<'a, K, V, P> {}
2040
2041impl<'a, K, V, P: SharedPointerKind> FusedIterator for Values<'a, K, V, P> {}
2042
2043impl<'a, K, V, S, P: SharedPointerKind> IntoIterator for &'a GenericHashMap<K, V, S, P> {
2044    type Item = (&'a K, &'a V);
2045    type IntoIter = Iter<'a, K, V, P>;
2046
2047    #[inline]
2048    fn into_iter(self) -> Self::IntoIter {
2049        self.iter()
2050    }
2051}
2052
2053impl<K, V, S, P> IntoIterator for GenericHashMap<K, V, S, P>
2054where
2055    K: Hash + Eq + Clone,
2056    V: Clone,
2057    S: BuildHasher + Clone,
2058    P: SharedPointerKind,
2059{
2060    type Item = (K, V);
2061    type IntoIter = ConsumingIter<(K, V), P>;
2062
2063    #[inline]
2064    fn into_iter(self) -> Self::IntoIter {
2065        ConsumingIter {
2066            it: NodeDrain::new(self.root, self.size),
2067        }
2068    }
2069}
2070
2071// Conversions
2072
2073impl<K, V, S, P> FromIterator<(K, V)> for GenericHashMap<K, V, S, P>
2074where
2075    K: Hash + Eq + Clone,
2076    V: Clone,
2077    S: BuildHasher + Default + Clone,
2078    P: SharedPointerKind,
2079{
2080    fn from_iter<T>(i: T) -> Self
2081    where
2082        T: IntoIterator<Item = (K, V)>,
2083    {
2084        let mut map = Self::default();
2085        for (k, v) in i {
2086            map.insert(k, v);
2087        }
2088        map
2089    }
2090}
2091
2092impl<K, V, S, P: SharedPointerKind> AsRef<GenericHashMap<K, V, S, P>>
2093    for GenericHashMap<K, V, S, P>
2094{
2095    #[inline]
2096    fn as_ref(&self) -> &Self {
2097        self
2098    }
2099}
2100
2101impl<K, V, OK, OV, SA, SB, P1, P2> From<&GenericHashMap<&K, &V, SA, P1>>
2102    for GenericHashMap<OK, OV, SB, P2>
2103where
2104    K: Hash + Equivalent<OK> + ToOwned<Owned = OK> + ?Sized,
2105    V: ToOwned<Owned = OV> + ?Sized,
2106    OK: Hash + Eq + Clone,
2107    OV: Borrow<V> + Clone,
2108    SA: BuildHasher + Clone,
2109    SB: BuildHasher + Default + Clone,
2110    P1: SharedPointerKind,
2111    P2: SharedPointerKind,
2112{
2113    fn from(m: &GenericHashMap<&K, &V, SA, P1>) -> Self {
2114        m.iter()
2115            .map(|(k, v)| ((*k).to_owned(), (*v).to_owned()))
2116            .collect()
2117    }
2118}
2119
2120impl<'a, K, V, S, P> From<&'a [(K, V)]> for GenericHashMap<K, V, S, P>
2121where
2122    K: Hash + Eq + Clone,
2123    V: Clone,
2124    S: BuildHasher + Default + Clone,
2125    P: SharedPointerKind,
2126{
2127    fn from(m: &'a [(K, V)]) -> Self {
2128        m.iter().cloned().collect()
2129    }
2130}
2131
2132impl<K, V, S, P> From<Vec<(K, V)>> for GenericHashMap<K, V, S, P>
2133where
2134    K: Hash + Eq + Clone,
2135    V: Clone,
2136    S: BuildHasher + Default + Clone,
2137    P: SharedPointerKind,
2138{
2139    fn from(m: Vec<(K, V)>) -> Self {
2140        m.into_iter().collect()
2141    }
2142}
2143
2144impl<'a, K, V, S, P> From<&'a Vec<(K, V)>> for GenericHashMap<K, V, S, P>
2145where
2146    K: Hash + Eq + Clone,
2147    V: Clone,
2148    S: BuildHasher + Default + Clone,
2149    P: SharedPointerKind,
2150{
2151    fn from(m: &'a Vec<(K, V)>) -> Self {
2152        m.iter().cloned().collect()
2153    }
2154}
2155
2156impl<K, V, S1, S2, P> From<collections::HashMap<K, V, S2>> for GenericHashMap<K, V, S1, P>
2157where
2158    K: Hash + Eq + Clone,
2159    V: Clone,
2160    S1: BuildHasher + Default + Clone,
2161    S2: BuildHasher,
2162    P: SharedPointerKind,
2163{
2164    fn from(m: collections::HashMap<K, V, S2>) -> Self {
2165        m.into_iter().collect()
2166    }
2167}
2168
2169impl<'a, K, V, S1, S2, P> From<&'a collections::HashMap<K, V, S2>> for GenericHashMap<K, V, S1, P>
2170where
2171    K: Hash + Eq + Clone,
2172    V: Clone,
2173    S1: BuildHasher + Default + Clone,
2174    S2: BuildHasher,
2175    P: SharedPointerKind,
2176{
2177    fn from(m: &'a collections::HashMap<K, V, S2>) -> Self {
2178        m.iter().map(|(k, v)| (k.clone(), v.clone())).collect()
2179    }
2180}
2181
2182impl<K, V, S, P> From<collections::BTreeMap<K, V>> for GenericHashMap<K, V, S, P>
2183where
2184    K: Hash + Eq + Clone,
2185    V: Clone,
2186    S: BuildHasher + Default + Clone,
2187    P: SharedPointerKind,
2188{
2189    fn from(m: collections::BTreeMap<K, V>) -> Self {
2190        m.into_iter().collect()
2191    }
2192}
2193
2194impl<'a, K, V, S, P> From<&'a collections::BTreeMap<K, V>> for GenericHashMap<K, V, S, P>
2195where
2196    K: Hash + Eq + Clone,
2197    V: Clone,
2198    S: BuildHasher + Default + Clone,
2199    P: SharedPointerKind,
2200{
2201    fn from(m: &'a collections::BTreeMap<K, V>) -> Self {
2202        m.iter().map(|(k, v)| (k.clone(), v.clone())).collect()
2203    }
2204}
2205
2206// impl<K: Ord + Hash + Eq, V, S> From<OrdMap<K, V>> for HashMap<K, V, S>
2207// where
2208//     S: BuildHasher + Default,
2209// {
2210//     fn from(m: OrdMap<K, V>) -> Self {
2211//         m.into_iter().collect()
2212//     }
2213// }
2214
2215// impl<'a, K: Ord + Hash + Eq, V, S> From<&'a OrdMap<K, V>> for HashMap<K, V, S>
2216// where
2217//     S: BuildHasher + Default,
2218// {
2219//     fn from(m: &'a OrdMap<K, V>) -> Self {
2220//         m.into_iter().collect()
2221//     }
2222// }
2223
2224// Proptest
2225#[cfg(any(test, feature = "proptest"))]
2226#[doc(hidden)]
2227pub mod proptest {
2228    #[deprecated(
2229        since = "14.3.0",
2230        note = "proptest strategies have moved to imbl::proptest"
2231    )]
2232    pub use crate::proptest::hash_map;
2233}
2234
2235// Tests
2236
2237#[cfg(test)]
2238mod test {
2239    use super::*;
2240    use crate::test::LolHasher;
2241    #[rustfmt::skip]
2242    use ::proptest::{collection, num::{i16, usize}, proptest};
2243    use static_assertions::{assert_impl_all, assert_not_impl_any};
2244    use std::hash::BuildHasherDefault;
2245
2246    assert_impl_all!(HashMap<i32, i32>: Send, Sync);
2247    assert_not_impl_any!(HashMap<i32, *const i32>: Send, Sync);
2248    assert_not_impl_any!(HashMap<*const i32, i32>: Send, Sync);
2249    assert_covariant!(HashMap<T, i32> in T);
2250    assert_covariant!(HashMap<i32, T> in T);
2251
2252    #[test]
2253    fn safe_mutation() {
2254        let v1: HashMap<usize, usize> = GenericHashMap::from_iter((0..131_072).map(|i| (i, i)));
2255        let mut v2 = v1.clone();
2256        v2.insert(131_000, 23);
2257        assert_eq!(Some(&23), v2.get(&131_000));
2258        assert_eq!(Some(&131_000), v1.get(&131_000));
2259    }
2260
2261    #[test]
2262    fn index_operator() {
2263        let mut map: HashMap<usize, usize> = hashmap![1 => 2, 3 => 4, 5 => 6];
2264        assert_eq!(4, map[&3]);
2265        map[&3] = 8;
2266        let target_map: HashMap<usize, usize> = hashmap![1 => 2, 3 => 8, 5 => 6];
2267        assert_eq!(target_map, map);
2268    }
2269
2270    #[test]
2271    fn proper_formatting() {
2272        let map: HashMap<usize, usize> = hashmap![1 => 2];
2273        assert_eq!("{1: 2}", format!("{:?}", map));
2274
2275        assert_eq!("{}", format!("{:?}", HashMap::<(), ()>::new()));
2276    }
2277
2278    #[test]
2279    fn remove_failing() {
2280        let pairs = [(1469, 0), (-67, 0)];
2281        let mut m: collections::HashMap<i16, i16, _> =
2282            collections::HashMap::with_hasher(BuildHasherDefault::<LolHasher>::default());
2283        for (k, v) in &pairs {
2284            m.insert(*k, *v);
2285        }
2286        let mut map: GenericHashMap<i16, i16, _, DefaultSharedPtr> =
2287            GenericHashMap::with_hasher(BuildHasherDefault::<LolHasher>::default());
2288        for (k, v) in &m {
2289            map = map.update(*k, *v);
2290        }
2291        for k in m.keys() {
2292            let l = map.len();
2293            assert_eq!(m.get(k).cloned(), map.get(k).cloned());
2294            map = map.without(k);
2295            assert_eq!(None, map.get(k));
2296            assert_eq!(l - 1, map.len());
2297        }
2298    }
2299
2300    #[test]
2301    fn match_string_keys_with_string_slices() {
2302        let tmp_map: HashMap<&str, &i32> = hashmap! { "foo" => &1, "bar" => &2, "baz" => &3 };
2303        let mut map: HashMap<String, i32> = From::from(&tmp_map);
2304        assert_eq!(Some(&1), map.get("foo"));
2305        map = map.without("foo");
2306        assert_eq!(Some(3), map.remove("baz"));
2307        map["bar"] = 8;
2308        assert_eq!(8, map["bar"]);
2309    }
2310
2311    #[test]
2312    fn macro_allows_trailing_comma() {
2313        let map1: HashMap<&str, i32> = hashmap! {"x" => 1, "y" => 2};
2314        let map2: HashMap<&str, i32> = hashmap! {
2315            "x" => 1,
2316            "y" => 2,
2317        };
2318        assert_eq!(map1, map2);
2319    }
2320
2321    #[test]
2322    fn remove_top_level_collisions() {
2323        let pairs = vec![9, 2569, 27145];
2324        let mut map: GenericHashMap<i16, i16, BuildHasherDefault<LolHasher>, DefaultSharedPtr> =
2325            Default::default();
2326        for k in pairs.clone() {
2327            map.insert(k, k);
2328        }
2329        assert_eq!(pairs.len(), map.len());
2330        let keys: Vec<_> = map.keys().cloned().collect();
2331        for k in keys {
2332            let l = map.len();
2333            assert_eq!(Some(&k), map.get(&k));
2334            map.remove(&k);
2335            assert_eq!(None, map.get(&k));
2336            assert_eq!(l - 1, map.len());
2337        }
2338    }
2339
2340    #[test]
2341    fn entry_api() {
2342        let mut map: HashMap<&str, i32> = hashmap! {"bar" => 5};
2343        map.entry("foo").and_modify(|v| *v += 5).or_insert(1);
2344        assert_eq!(1, map[&"foo"]);
2345        map.entry("foo").and_modify(|v| *v += 5).or_insert(1);
2346        assert_eq!(6, map[&"foo"]);
2347        map.entry("bar").and_modify(|v| *v += 5).or_insert(1);
2348        assert_eq!(10, map[&"bar"]);
2349        assert_eq!(
2350            10,
2351            match map.entry("bar") {
2352                Entry::Occupied(entry) => entry.remove(),
2353                _ => panic!(),
2354            }
2355        );
2356        assert!(!map.contains_key(&"bar"));
2357    }
2358
2359    #[test]
2360    fn refpool_crash() {
2361        let _map = HashMap::<u128, usize>::new();
2362    }
2363
2364    #[test]
2365    fn large_map() {
2366        let mut map = HashMap::<_, _>::new();
2367        let size = 32769;
2368        for i in 0..size {
2369            map.insert(i, i);
2370        }
2371        assert_eq!(size, map.len());
2372        for i in 0..size {
2373            assert_eq!(Some(&i), map.get(&i));
2374        }
2375    }
2376
2377    struct PanicOnClone;
2378
2379    impl Clone for PanicOnClone {
2380        fn clone(&self) -> Self {
2381            panic!("PanicOnClone::clone called")
2382        }
2383    }
2384
2385    #[test]
2386    fn into_iter_no_clone() {
2387        let mut map = HashMap::new();
2388        for i in 0..10_000 {
2389            map.insert(i, PanicOnClone);
2390        }
2391        let _ = map.into_iter().collect::<Vec<_>>();
2392    }
2393
2394    #[test]
2395    fn iter_mut_no_clone() {
2396        let mut map = HashMap::new();
2397        for i in 0..10_000 {
2398            map.insert(i, PanicOnClone);
2399        }
2400        let _ = map.iter_mut().collect::<Vec<_>>();
2401    }
2402
2403    #[test]
2404    fn iter_no_clone() {
2405        let mut map = HashMap::new();
2406        for i in 0..10_000 {
2407            map.insert(i, PanicOnClone);
2408        }
2409        let _ = map.iter().collect::<Vec<_>>();
2410    }
2411
2412    proptest! {
2413        #[test]
2414        fn update_and_length(ref m in collection::hash_map(i16::ANY, i16::ANY, 0..1000)) {
2415            let mut map: GenericHashMap<i16, i16, BuildHasherDefault<LolHasher>, DefaultSharedPtr> = Default::default();
2416            for (index, (k, v)) in m.iter().enumerate() {
2417                map = map.update(*k, *v);
2418                assert_eq!(Some(v), map.get(k));
2419                assert_eq!(index + 1, map.len());
2420            }
2421        }
2422
2423        #[test]
2424        fn from_iterator(ref m in collection::hash_map(i16::ANY, i16::ANY, 0..1000)) {
2425            let map: HashMap<i16, i16> =
2426                FromIterator::from_iter(m.iter().map(|(k, v)| (*k, *v)));
2427            assert_eq!(m.len(), map.len());
2428        }
2429
2430        #[test]
2431        fn iterate_over(ref m in collection::hash_map(i16::ANY, i16::ANY, 0..1000)) {
2432            let map: HashMap<i16, i16> = FromIterator::from_iter(m.iter().map(|(k, v)| (*k, *v)));
2433            assert_eq!(m.len(), map.iter().count());
2434        }
2435
2436        #[test]
2437        fn equality(ref m in collection::hash_map(i16::ANY, i16::ANY, 0..1000)) {
2438            let map1: HashMap<i16, i16> = FromIterator::from_iter(m.iter().map(|(k, v)| (*k, *v)));
2439            let map2: HashMap<i16, i16> = FromIterator::from_iter(m.iter().map(|(k, v)| (*k, *v)));
2440            assert_eq!(map1, map2);
2441        }
2442
2443        #[test]
2444        fn lookup(ref m in collection::hash_map(i16::ANY, i16::ANY, 0..1000)) {
2445            let map: HashMap<i16, i16> = FromIterator::from_iter(m.iter().map(|(k, v)| (*k, *v)));
2446            for (k, v) in m {
2447                assert_eq!(Some(*v), map.get(k).cloned(), "{k} not found in map {map:?}");
2448            }
2449        }
2450
2451        #[test]
2452        fn without(ref pairs in collection::vec((i16::ANY, i16::ANY), 0..100)) {
2453            let mut m: collections::HashMap<i16, i16, _> =
2454                collections::HashMap::with_hasher(BuildHasherDefault::<LolHasher>::default());
2455            for (k, v) in pairs {
2456                m.insert(*k, *v);
2457            }
2458            let mut map: GenericHashMap<i16, i16, _, DefaultSharedPtr> = GenericHashMap::with_hasher(BuildHasherDefault::<LolHasher>::default());
2459            for (k, v) in &m {
2460                map = map.update(*k, *v);
2461            }
2462            for k in m.keys() {
2463                let l = map.len();
2464                assert_eq!(m.get(k).cloned(), map.get(k).cloned());
2465                map = map.without(k);
2466                assert_eq!(None, map.get(k));
2467                assert_eq!(l - 1, map.len());
2468            }
2469        }
2470
2471        #[test]
2472        fn insert(ref m in collection::hash_map(i16::ANY, i16::ANY, 0..1000)) {
2473            let mut mut_map: GenericHashMap<i16, i16, BuildHasherDefault<LolHasher>, DefaultSharedPtr> = Default::default();
2474            let mut map: GenericHashMap<i16, i16, BuildHasherDefault<LolHasher>, DefaultSharedPtr> = Default::default();
2475            for (count, (k, v)) in m.iter().enumerate() {
2476                map = map.update(*k, *v);
2477                mut_map.insert(*k, *v);
2478                assert_eq!(count + 1, map.len());
2479                assert_eq!(count + 1, mut_map.len());
2480            }
2481            for (k, v) in m {
2482                assert_eq!(Some(v), map.get(k));
2483                assert_eq!(Some(v), mut_map.get(k));
2484            }
2485            assert_eq!(map, mut_map);
2486        }
2487
2488        #[test]
2489        fn remove(ref pairs in collection::vec((i16::ANY, i16::ANY), 0..100)) {
2490            let mut m: collections::HashMap<i16, i16, _> =
2491                collections::HashMap::with_hasher(BuildHasherDefault::<LolHasher>::default());
2492            for (k, v) in pairs {
2493                m.insert(*k, *v);
2494            }
2495            let mut map: GenericHashMap<i16, i16, _, DefaultSharedPtr> = GenericHashMap::with_hasher(BuildHasherDefault::<LolHasher>::default());
2496            for (k, v) in &m {
2497                map.insert(*k, *v);
2498            }
2499            for k in m.keys() {
2500                let l = map.len();
2501                assert_eq!(m.get(k).cloned(), map.get(k).cloned());
2502                map.remove(k);
2503                assert_eq!(None, map.get(k));
2504                assert_eq!(l - 1, map.len());
2505            }
2506        }
2507
2508        #[test]
2509        fn delete_and_reinsert(
2510            ref input in collection::hash_map(i16::ANY, i16::ANY, 1..1000),
2511            index_rand in usize::ANY
2512        ) {
2513            let index = *input.keys().nth(index_rand % input.len()).unwrap();
2514            let map1: HashMap<_, _> = HashMap::from_iter(input.clone());
2515            let (val, map2) = map1.extract(&index).unwrap();
2516            let map3 = map2.update(index, val);
2517            for key in map2.keys() {
2518                assert!(*key != index);
2519            }
2520            assert_eq!(map1.len(), map2.len() + 1);
2521            assert_eq!(map1, map3);
2522        }
2523
2524        #[test]
2525        fn proptest_works(ref m in proptest::hash_map(0..9999, ".*", 10..100)) {
2526            assert!(m.len() < 100);
2527            assert!(m.len() >= 10);
2528        }
2529
2530        #[test]
2531        fn exact_size_iterator(ref m in proptest::hash_map(i16::ANY, i16::ANY, 0..100)) {
2532            let mut should_be = m.len();
2533            let mut it = m.iter();
2534            loop {
2535                assert_eq!(should_be, it.len());
2536                match it.next() {
2537                    None => break,
2538                    Some(_) => should_be -= 1,
2539                }
2540            }
2541            assert_eq!(0, it.len());
2542        }
2543
2544        #[test]
2545        fn union(ref m1 in collection::hash_map(i16::ANY, i16::ANY, 0..100),
2546                 ref m2 in collection::hash_map(i16::ANY, i16::ANY, 0..100)) {
2547            let map1: HashMap<i16, i16> = FromIterator::from_iter(m1.iter().map(|(k, v)| (*k, *v)));
2548            let map2: HashMap<i16, i16> = FromIterator::from_iter(m2.iter().map(|(k, v)| (*k, *v)));
2549            let union_map = map1.union(map2);
2550
2551            for k in m1.keys() {
2552                assert!(union_map.contains_key(k));
2553            }
2554
2555            for k in m2.keys() {
2556                assert!(union_map.contains_key(k));
2557            }
2558
2559            for (k, v) in union_map.iter() {
2560                assert_eq!(v, m1.get(k).or_else(|| m2.get(k)).unwrap());
2561            }
2562        }
2563    }
2564
2565    #[test]
2566    fn test_structure_summary() {
2567        // Test with different sizes of HashMaps
2568        let sizes = vec![10, 100, 1_000, 10_000, 100_000];
2569
2570        for size in sizes {
2571            println!("\n=== Testing with {} entries ===", size);
2572
2573            let mut map = HashMap::new();
2574
2575            // Insert entries
2576            for i in 0..size {
2577                // dbg!(i);
2578                map.insert(i, i * 2);
2579            }
2580
2581            // Print structure summary
2582            map.print_structure_summary();
2583        }
2584    }
2585}