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
11impl Hash for HashStr {
14 #[inline]
15 fn hash<H: Hasher>(&self, state: &mut H) {
16 state.write_u64(self.precomputed_hash());
17 }
18}
19
20pub type HashStrMap<'a,V> = HashMap<&'a HashStr, V, BuildHasherDefault<IdentityHasher>>;
23
24pub type HashStrSet<'a> = HashSet<&'a HashStr, BuildHasherDefault<IdentityHasher>>;
27
28#[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}