alloy_primitives/map/
hasher.rs

1use cfg_if::cfg_if;
2use core::hash::{BuildHasher, Hash, Hasher};
3
4// Faster hashers.
5cfg_if! {
6    if #[cfg(feature = "map-fxhash")] {
7        #[doc(no_inline)]
8        pub use rustc_hash::{self, FxHasher};
9
10        /// The [`FxHasher`] hasher builder.
11        ///
12        /// This is [`rustc_hash::FxBuildHasher`], unless both the "std" and "rand" features are
13        /// enabled, in which case it will be [`rustc_hash::FxRandomState`] for better security at
14        /// very little cost.
15        pub type FxBuildHasher = FxBuildHasherInner;
16    }
17}
18
19// Used by `FbHasher`.
20cfg_if! {
21    if #[cfg(all(feature = "std", feature = "rand"))] {
22        pub(super) use rustc_hash::FxRandomState as FxBuildHasherInner;
23    } else {
24        pub(super) use rustc_hash::FxBuildHasher as FxBuildHasherInner;
25    }
26}
27
28#[cfg(feature = "map-foldhash")]
29#[doc(no_inline)]
30pub use foldhash;
31
32#[cfg(feature = "map-rapidhash")]
33#[doc(no_inline)]
34pub use rapidhash;
35
36// Default hasher.
37cfg_if! {
38    if #[cfg(feature = "map-foldhash")] {
39        type DefaultHashBuilderInner = foldhash::fast::RandomState;
40    } else if #[cfg(feature = "map-rapidhash")] {
41        type DefaultHashBuilderInner = rapidhash::fast::RandomState;
42    } else if #[cfg(feature = "map-fxhash")] {
43        type DefaultHashBuilderInner = FxBuildHasher;
44    } else if #[cfg(any(feature = "map-hashbrown", not(feature = "std")))] {
45        type DefaultHashBuilderInner = hashbrown::DefaultHashBuilder;
46    } else {
47        type DefaultHashBuilderInner = std::collections::hash_map::RandomState;
48    }
49}
50
51/// The default [`BuildHasher`] used by [`HashMap`](super::HashMap) and [`HashSet`](super::HashSet).
52///
53/// See [the module documentation](super) for more information on the default hasher.
54#[derive(Clone, Default)]
55#[allow(missing_copy_implementations, missing_debug_implementations)]
56pub struct DefaultHashBuilder {
57    inner: DefaultHashBuilderInner,
58}
59
60impl BuildHasher for DefaultHashBuilder {
61    type Hasher = DefaultHasher;
62
63    #[inline]
64    fn build_hasher(&self) -> Self::Hasher {
65        DefaultHasher { inner: self.inner.build_hasher() }
66    }
67
68    #[inline]
69    fn hash_one<T: Hash>(&self, x: T) -> u64
70    where
71        Self: Sized,
72        Self::Hasher: Hasher,
73    {
74        self.inner.hash_one(x)
75    }
76}
77
78/// The default [`Hasher`] used by [`HashMap`](super::HashMap) and [`HashSet`](super::HashSet).
79///
80/// See [the module documentation](super) for more information on the default hasher.
81#[derive(Clone)]
82#[allow(missing_debug_implementations)]
83pub struct DefaultHasher {
84    inner: <DefaultHashBuilderInner as BuildHasher>::Hasher,
85}
86
87macro_rules! forward_writes {
88    ($( $write:ident ( $ty:ty ) , )*) => {$(
89        #[inline(always)]
90        fn $write(&mut self, arg: $ty) {
91            self.inner.$write(arg);
92        }
93    )*}
94}
95
96impl Hasher for DefaultHasher {
97    forward_writes! {
98        write(&[u8]),
99        write_u8(u8),
100        write_u16(u16),
101        write_u32(u32),
102        write_u64(u64),
103        write_u128(u128),
104        write_usize(usize),
105        write_i8(i8),
106        write_i16(i16),
107        write_i32(i32),
108        write_i64(i64),
109        write_i128(i128),
110        write_isize(isize),
111    }
112
113    // feature(hasher_prefixfree_extras)
114    #[cfg(feature = "nightly")]
115    forward_writes! {
116        write_length_prefix(usize),
117        write_str(&str),
118    }
119
120    #[inline(always)]
121    fn finish(&self) -> u64 {
122        self.inner.finish()
123    }
124}