hash_str/
hash.rs

1use crate::hash_str::HashStr;
2use std::collections::{HashMap,HashSet};
3use std::hash::{BuildHasherDefault,Hash,Hasher};
4
5pub(crate) fn make_hash(value:&str)->u64{
6	let mut hasher=ahash::AHasher::default();
7	hasher.write(value.as_bytes());
8	hasher.finish()
9}
10
11// Just feed the precomputed hash into the Hasher. Note that this will of course
12// be terrible unless the Hasher in question is expecting a precomputed hash.
13impl Hash for HashStr {
14	#[inline]
15    fn hash<H: Hasher>(&self, state: &mut H) {
16        state.write_u64(self.precomputed_hash());
17    }
18}
19
20/// A standard `HashMap` using `&HashStr` as the key type with a custom `Hasher`
21/// that just uses the precomputed hash for speed instead of calculating it.
22pub type HashStrMap<'a,V> = HashMap<&'a HashStr, V, BuildHasherDefault<IdentityHasher>>;
23
24/// A standard `HashSet` using `&HashStr` as the key type with a custom `Hasher`
25/// that just uses the precomputed hash for speed instead of calculating it.
26pub type HashStrSet<'a> = HashSet<&'a HashStr, BuildHasherDefault<IdentityHasher>>;
27
28/// The worst hasher in the world -- the identity hasher.
29#[doc(hidden)]
30#[derive(Default)]
31pub struct IdentityHasher {
32    hash: u64,
33}
34
35impl Hasher for IdentityHasher {
36	#[inline]
37    fn write_u64(&mut self, value: u64) {
38        self.hash = value;
39    }
40    #[inline]
41    fn write(&mut self, bytes: &[u8]) {
42        self.hash = u64::from_ne_bytes(bytes.try_into().unwrap());
43    }
44
45    #[inline]
46    fn finish(&self) -> u64 {
47        self.hash
48    }
49}
50
51#[test]
52fn test_hashing() {
53	let u1=&*HashStr::anonymous("the quick brown fox".to_owned());
54	let u2=&*HashStr::anonymous("jumped over the lazy dog".to_owned());
55
56	let mut hasher = IdentityHasher::default();
57	u1.hash(&mut hasher);
58	assert_eq!(hasher.finish(), u1.precomputed_hash());
59
60	let mut hasher = IdentityHasher::default();
61	u2.hash(&mut hasher);
62	assert_eq!(hasher.finish(), u2.precomputed_hash());
63
64	let mut hm = HashStrMap::<u32>::default();
65	hm.insert(u1, 17);
66	hm.insert(u2, 42);
67
68	assert_eq!(hm.get(u1), Some(&17));
69	assert_eq!(hm.get(u2), Some(&42));
70}