alloy_primitives/map/
mod.rs

1//! Re-exports of map types and utilities.
2//!
3//! This module exports the following types:
4//! - [`HashMap`] and [`HashSet`] from the standard library or `hashbrown` crate. The
5//!   "map-hashbrown" feature can be used to force the use of `hashbrown`, and is required in
6//!   `no_std` environments.
7//! - [`IndexMap`] and [`IndexSet`] from the `indexmap` crate, if the "map-indexmap" feature is
8//!   enabled.
9//! - The previously-listed hash map types prefixed with `Fb`. These are type aliases with
10//!   [`FixedBytes<N>`][fb] as the key, and [`FbBuildHasher`] as the hasher builder. This hasher is
11//!   optimized for hashing fixed-size byte arrays, and wraps around the default hasher builder. It
12//!   performs best when the hasher is `fxhash`, which is enabled by default with the "map-fxhash"
13//!   feature.
14//! - The previously-listed hash map types prefixed with [`Selector`], [`Address`], and [`B256`].
15//!   These use [`FbBuildHasher`] with the respective fixed-size byte array as the key. See the
16//!   previous point for more information.
17//!
18//! Unless specified otherwise, the default hasher builder used by these types is
19//! [`DefaultHashBuilder`]. This hasher prioritizes speed over security. Users who require HashDoS
20//! resistance should enable the "rand" feature so that the hasher is initialized using a random
21//! seed.
22//!
23//! Note that using the types provided in this module may require using different APIs than the
24//! standard library as they might not be generic over the hasher state, such as using
25//! `HashMap::default()` instead of `HashMap::new()`.
26//!
27//! [fb]: crate::FixedBytes
28//! [`Selector`]: crate::Selector
29//! [`Address`]: crate::Address
30//! [`B256`]: crate::B256
31
32use cfg_if::cfg_if;
33
34mod fixed;
35pub use fixed::*;
36
37// The `HashMap` implementation.
38// Use `hashbrown` if requested with "map-hashbrown" or required by `no_std`.
39cfg_if! {
40    if #[cfg(any(feature = "map-hashbrown", not(feature = "std")))] {
41        use hashbrown as imp;
42    } else {
43        use hashbrown as _;
44        use std::collections as imp;
45    }
46}
47
48#[doc(no_inline)]
49pub use imp::{hash_map, hash_map::Entry, hash_set};
50
51/// A [`HashMap`](imp::HashMap) using the [default hasher](DefaultHasher).
52///
53/// See [`HashMap`](imp::HashMap) for more information.
54pub type HashMap<K, V, S = DefaultHashBuilder> = imp::HashMap<K, V, S>;
55/// A [`HashSet`](imp::HashSet) using the [default hasher](DefaultHasher).
56///
57/// See [`HashSet`](imp::HashSet) for more information.
58pub type HashSet<V, S = DefaultHashBuilder> = imp::HashSet<V, S>;
59
60// Faster hashers.
61cfg_if! {
62    if #[cfg(feature = "map-fxhash")] {
63        #[doc(no_inline)]
64        pub use rustc_hash::{self, FxHasher};
65
66        cfg_if! {
67            if #[cfg(all(feature = "std", feature = "rand"))] {
68                use rustc_hash::FxRandomState as FxBuildHasherInner;
69            } else {
70                use rustc_hash::FxBuildHasher as FxBuildHasherInner;
71            }
72        }
73
74        /// The [`FxHasher`] hasher builder.
75        ///
76        /// This is [`rustc_hash::FxBuildHasher`], unless both the "std" and "rand" features are
77        /// enabled, in which case it will be [`rustc_hash::FxRandomState`] for better security at
78        /// very little cost.
79        pub type FxBuildHasher = FxBuildHasherInner;
80    }
81}
82
83#[cfg(feature = "map-foldhash")]
84#[doc(no_inline)]
85pub use foldhash;
86
87// Default hasher.
88cfg_if! {
89    if #[cfg(feature = "map-foldhash")] {
90        type DefaultHashBuilderInner = foldhash::fast::RandomState;
91    } else if #[cfg(feature = "map-fxhash")] {
92        type DefaultHashBuilderInner = FxBuildHasher;
93    } else if #[cfg(any(feature = "map-hashbrown", not(feature = "std")))] {
94        type DefaultHashBuilderInner = hashbrown::DefaultHashBuilder;
95    } else {
96        type DefaultHashBuilderInner = std::collections::hash_map::RandomState;
97    }
98}
99/// The default [`BuildHasher`](core::hash::BuildHasher) used by [`HashMap`] and [`HashSet`].
100///
101/// See [the module documentation](self) for more information on the default hasher.
102pub type DefaultHashBuilder = DefaultHashBuilderInner;
103/// The default [`Hasher`](core::hash::Hasher) used by [`HashMap`] and [`HashSet`].
104///
105/// See [the module documentation](self) for more information on the default hasher.
106pub type DefaultHasher = <DefaultHashBuilder as core::hash::BuildHasher>::Hasher;
107
108// `indexmap` re-exports.
109cfg_if! {
110    if #[cfg(feature = "map-indexmap")] {
111        #[doc(no_inline)]
112        pub use indexmap::{self, map::Entry as IndexEntry};
113
114        /// [`IndexMap`](indexmap::IndexMap) using the [default hasher](DefaultHasher).
115        ///
116        /// See [`IndexMap`](indexmap::IndexMap) for more information.
117        pub type IndexMap<K, V, S = DefaultHashBuilder> = indexmap::IndexMap<K, V, S>;
118        /// [`IndexSet`](indexmap::IndexSet) using the [default hasher](DefaultHasher).
119        ///
120        /// See [`IndexSet`](indexmap::IndexSet) for more information.
121        pub type IndexSet<V, S = DefaultHashBuilder> = indexmap::IndexSet<V, S>;
122    }
123}
124
125/// This module contains the rayon parallel iterator types for hash maps (HashMap<K, V>).
126///
127/// You will rarely need to interact with it directly unless you have need to name one
128/// of the iterator types.
129#[cfg(feature = "rayon")]
130pub mod rayon {
131    use super::*;
132
133    cfg_if! {
134        if #[cfg(any(feature = "map-hashbrown", not(feature = "std")))] {
135            pub use hashbrown::hash_map::rayon::{
136                IntoParIter as IntoIter,
137                ParDrain as Drain,
138                ParIter as Iter,
139                ParIterMut as IterMut,
140                ParKeys as Keys,
141                ParValues as Values,
142                ParValuesMut as ValuesMut
143            };
144            use ::rayon as _;
145        } else {
146            pub use ::rayon::collections::hash_map::*;
147        }
148    }
149}
150
151#[cfg(test)]
152mod tests {
153    use super::*;
154
155    #[test]
156    fn default_hasher_builder_traits() {
157        let hash_builder = <DefaultHashBuilder as Default>::default();
158        let _hash_builder2 = <DefaultHashBuilder as Clone>::clone(&hash_builder);
159        let mut hasher =
160            <DefaultHashBuilder as core::hash::BuildHasher>::build_hasher(&hash_builder);
161
162        <DefaultHasher as core::hash::Hasher>::write_u8(&mut hasher, 0);
163        let _hasher2 = <DefaultHasher as Clone>::clone(&hasher);
164    }
165}