]>
git.proxmox.com Git - rustc.git/blob - vendor/ahash-0.7.6/src/lib.rs
1 //! AHash is a hashing algorithm is intended to be a high performance, (hardware specific), keyed hash function.
2 //! This can be seen as a DOS resistant alternative to `FxHash`, or a fast equivalent to `SipHash`.
3 //! It provides a high speed hash algorithm, but where the result is not predictable without knowing a Key.
4 //! This allows it to be used in a `HashMap` without allowing for the possibility that an malicious user can
5 //! induce a collision.
9 //! aHash uses the hardware AES instruction on x86 processors to provide a keyed hash function.
10 //! aHash is not a cryptographically secure hash.
14 //! use ahash::{AHasher, RandomState};
15 //! use std::collections::HashMap;
17 //! let mut map: HashMap<i32, i32, RandomState> = HashMap::default();
18 //! map.insert(12, 34);
20 //! For convinence wrappers called `AHashMap` and `AHashSet` are also provided.
21 //! These to the same thing with slightly less typing.
23 //! use ahash::AHashMap;
25 //! let mut map: AHashMap<i32, i32> = AHashMap::with_capacity(4);
26 //! map.insert(12, 34);
27 //! map.insert(56, 78);
29 #![deny(clippy::correctness, clippy::complexity, clippy::perf)]
30 #![allow(clippy::pedantic, clippy::cast_lossless, clippy::unreadable_literal)]
31 #![cfg_attr(all(not(test), not(feature = "std")), no_std)]
32 #![cfg_attr(feature = "specialize", feature(min_specialization))]
33 #![cfg_attr(feature = "stdsimd", feature(stdsimd))]
39 all(any(target_arch
= "x86", target_arch
= "x86_64"), target_feature
= "aes", not(miri
)),
40 all(any(target_arch
= "arm", target_arch
= "aarch64"), target_feature
= "crypto", not(miri
), feature
= "stdsimd")
45 mod hash_quality_test
;
47 #[cfg(feature = "std")]
49 #[cfg(feature = "std")]
56 all(any(target_arch
= "x86", target_arch
= "x86_64"), target_feature
= "aes", not(miri
)),
57 all(any(target_arch
= "arm", target_arch
= "aarch64"), target_feature
= "crypto", not(miri
), feature
= "stdsimd")
59 pub use crate::aes_hash
::AHasher
;
62 all(any(target_arch
= "x86", target_arch
= "x86_64"), target_feature
= "aes", not(miri
)),
63 all(any(target_arch
= "arm", target_arch
= "aarch64"), target_feature
= "crypto", not(miri
), feature
= "stdsimd")
65 pub use crate::fallback_hash
::AHasher
;
66 pub use crate::random_state
::RandomState
;
68 pub use crate::specialize
::CallHasher
;
70 #[cfg(feature = "std")]
71 pub use crate::hash_map
::AHashMap
;
72 #[cfg(feature = "std")]
73 pub use crate::hash_set
::AHashSet
;
74 use core
::hash
::BuildHasher
;
76 use core
::hash
::Hasher
;
78 /// Provides a default [Hasher] with fixed keys.
79 /// This is typically used in conjunction with [BuildHasherDefault] to create
80 /// [AHasher]s in order to hash the keys of the map.
82 /// Generally it is preferable to use [RandomState] instead, so that different
83 /// hashmaps will have different keys. However if fixed keys are desireable this
84 /// may be used instead.
88 /// use std::hash::BuildHasherDefault;
89 /// use ahash::{AHasher, RandomState};
90 /// use std::collections::HashMap;
92 /// let mut map: HashMap<i32, i32, BuildHasherDefault<AHasher>> = HashMap::default();
93 /// map.insert(12, 34);
96 /// [BuildHasherDefault]: std::hash::BuildHasherDefault
97 /// [Hasher]: std::hash::Hasher
98 /// [HashMap]: std::collections::HashMap
99 impl Default
for AHasher
{
100 /// Constructs a new [AHasher] with fixed keys.
101 /// If `std` is enabled these will be generated upon first invocation.
102 /// Otherwise if the `compile-time-rng`feature is enabled these will be generated at compile time.
103 /// If neither of these features are available, hardcoded constants will be used.
105 /// Because the values are fixed, different hashers will all hash elements the same way.
106 /// This could make hash values predictable, if DOS attacks are a concern. If this behaviour is
107 /// not required, it may be preferable to use [RandomState] instead.
112 /// use ahash::AHasher;
113 /// use std::hash::Hasher;
115 /// let mut hasher_1 = AHasher::default();
116 /// let mut hasher_2 = AHasher::default();
118 /// hasher_1.write_u32(1234);
119 /// hasher_2.write_u32(1234);
121 /// assert_eq!(hasher_1.finish(), hasher_2.finish());
124 fn default() -> AHasher
{
125 RandomState
::with_fixed_keys().build_hasher()
129 /// Used for specialization. (Sealed)
130 pub(crate) trait BuildHasherExt
: BuildHasher
{
132 fn hash_as_u64
<T
: Hash
+ ?Sized
>(&self, value
: &T
) -> u64;
135 fn hash_as_fixed_length
<T
: Hash
+ ?Sized
>(&self, value
: &T
) -> u64;
138 fn hash_as_str
<T
: Hash
+ ?Sized
>(&self, value
: &T
) -> u64;
141 impl<B
: BuildHasher
> BuildHasherExt
for B
{
143 #[cfg(feature = "specialize")]
144 default fn hash_as_u64
<T
: Hash
+ ?Sized
>(&self, value
: &T
) -> u64 {
145 let mut hasher
= self.build_hasher();
146 value
.hash(&mut hasher
);
150 #[cfg(not(feature = "specialize"))]
151 fn hash_as_u64
<T
: Hash
+ ?Sized
>(&self, value
: &T
) -> u64 {
152 let mut hasher
= self.build_hasher();
153 value
.hash(&mut hasher
);
157 #[cfg(feature = "specialize")]
158 default fn hash_as_fixed_length
<T
: Hash
+ ?Sized
>(&self, value
: &T
) -> u64 {
159 let mut hasher
= self.build_hasher();
160 value
.hash(&mut hasher
);
164 #[cfg(not(feature = "specialize"))]
165 fn hash_as_fixed_length
<T
: Hash
+ ?Sized
>(&self, value
: &T
) -> u64 {
166 let mut hasher
= self.build_hasher();
167 value
.hash(&mut hasher
);
171 #[cfg(feature = "specialize")]
172 default fn hash_as_str
<T
: Hash
+ ?Sized
>(&self, value
: &T
) -> u64 {
173 let mut hasher
= self.build_hasher();
174 value
.hash(&mut hasher
);
178 #[cfg(not(feature = "specialize"))]
179 fn hash_as_str
<T
: Hash
+ ?Sized
>(&self, value
: &T
) -> u64 {
180 let mut hasher
= self.build_hasher();
181 value
.hash(&mut hasher
);
188 // pub fn hash_test(input: &[u8]) -> u64 {
189 // let a = RandomState::with_seeds(11, 22, 33, 44);
190 // <[u8]>::get_hash(input, &a)
193 #[cfg(feature = "std")]
196 use crate::convert
::Convert
;
198 use std
::collections
::HashMap
;
202 fn test_default_builder() {
203 use core
::hash
::BuildHasherDefault
;
205 let mut map
= HashMap
::<u32, u64, BuildHasherDefault
<AHasher
>>::default();
211 let mut map
= HashMap
::<u32, u64, RandomState
>::default();
216 fn test_conversion() {
217 let input
: &[u8] = b
"dddddddd";
218 let bytes
: u64 = as_array
!(input
, 8).convert();
219 assert_eq
!(bytes
, 0x6464646464646464);
225 let mut hasher1
= AHasher
::new_with_keys(0, 0);
226 let mut hasher2
= AHasher
::new_with_keys(0, 0);
227 "foo".hash(&mut hasher1
);
228 "bar".hash(&mut hasher2
);
229 assert_ne
!(hasher1
.finish(), 0);
230 assert_ne
!(hasher2
.finish(), 0);
231 assert_ne
!(hasher1
.finish(), hasher2
.finish());
233 let mut hasher1
= AHasher
::new_with_keys(0, 0);
234 let mut hasher2
= AHasher
::new_with_keys(0, 0);
235 3_u64.hash(&mut hasher1
);
236 4_u64.hash(&mut hasher2
);
237 assert_ne
!(hasher1
.finish(), 0);
238 assert_ne
!(hasher2
.finish(), 0);
239 assert_ne
!(hasher1
.finish(), hasher2
.finish());
243 fn test_non_zero_specialized() {
244 let hasher_build
= RandomState
::with_seeds(0,0,0,0);
246 let h1
= str::get_hash("foo", &hasher_build
);
247 let h2
= str::get_hash("bar", &hasher_build
);
252 let h1
= u64::get_hash(&3_u64, &hasher_build
);
253 let h2
= u64::get_hash(&4_u64, &hasher_build
);
260 fn test_ahasher_construction() {
261 let _
= AHasher
::new_with_keys(1234, 5678);