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}