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