scopegraphs_prust_lib/
hashmap.rs1use std::{
2 collections::hash_map::DefaultHasher,
3 fmt::Debug,
4 hash::{Hash, Hasher},
5 marker::PhantomData,
6};
7
8use crate::trie::Trie;
9
10#[derive(Clone)]
11pub struct HashMap<K, V = ()> {
12 trie: Trie<bool, KeyValue<K, V>>,
13 phantom: PhantomData<K>,
14}
15
16pub type HashSet<K> = HashMap<K, ()>;
17
18#[derive(Clone, Debug)]
19struct KeyValue<K, V> {
20 key: K,
21 value: Option<V>,
22}
23
24impl<K: PartialEq, V> PartialEq for KeyValue<K, V> {
25 fn eq(&self, other: &Self) -> bool {
26 self.key == other.key
27 }
28}
29
30impl<K, V> Default for HashMap<K, V> {
31 fn default() -> Self {
32 Self::new()
33 }
34}
35
36impl<K, V> HashMap<K, V> {
37 pub fn new() -> HashMap<K, V> {
38 HashMap {
39 trie: Trie::empty_store(),
40 phantom: PhantomData,
41 }
42 }
43}
44
45impl<K: Hash + PartialEq> HashMap<K> {
46 pub fn insert(&self, value: K) -> Self {
47 self.put(value, ())
48 }
49 pub fn search(&self, value: &K) -> bool {
50 self.get(value).is_some()
51 }
52}
53
54impl<K: Hash + PartialEq, V> HashMap<K, V> {
55 pub fn put(&self, key: K, value: V) -> Self {
56 Self {
57 trie: self.trie.insert_store(
58 Self::get_bits(&key),
59 KeyValue {
60 key,
61 value: Some(value),
62 },
63 ),
64 phantom: PhantomData,
65 }
66 }
67
68 pub fn get(&self, k: &K) -> Option<&V> {
69 let store = self.trie.get_store(Self::get_bits(k))?;
70 let store_cloned: Vec<_> = (*store).to_vec();
71 store_cloned
72 .iter()
73 .find(|KeyValue { key, .. }| k == key)
74 .and_then(|kv| kv.value.as_ref())
75 }
76
77 pub fn delete(&self, key: K) -> Option<Self> {
78 self.trie
79 .delete_store(Self::get_bits(&key), &KeyValue { key, value: None })
80 .map(|trie| HashMap {
81 trie,
82 phantom: PhantomData,
83 })
84 }
85
86 fn get_bits(key: &K) -> Vec<bool> {
87 let mut s = DefaultHasher::new();
88 key.hash(&mut s);
89 let hash = s.finish();
90 (0..64).map(|i| hash & (1u64 << i) > 0).collect()
91 }
92}
93
94#[cfg(test)]
95mod tests {
96 use super::*;
97
98 #[test]
99 fn insert_and_retrieve_values_set() {
100 let m1 = HashMap::new();
101 let m2 = m1.insert(1238).insert(-1).insert(1238);
102 assert!(m2.search(&1238));
103 assert!(!m1.search(&-1));
104 assert!(!m2.delete(1238).unwrap().search(&1238))
105 }
106
107 #[test]
108 fn insert_and_retrieve_values() {
109 let m1 = HashMap::new();
110 let m2 = m1.put(1238, 1).put(-1, 10);
111 assert_eq!(m2.get(&1238), Some(&1));
112 assert_eq!(m1.get(&-1), None);
113 }
114
115 #[test]
116 fn handle_hash_collisions() {
117 #[derive(PartialEq, Clone)]
118 struct K {
119 x: i8,
120 }
121
122 impl Hash for K {
123 fn hash<H: Hasher>(&self, _: &mut H) {}
124 }
125
126 let m = HashMap::new().put(K { x: 1 }, 1).put(K { x: -1 }, 10);
127 assert_eq!(m.get(&K { x: 1 }), Some(&1));
128 assert_eq!(m.get(&K { x: -1 }), Some(&10));
129 }
130
131 #[test]
132 fn delete_entries() {
133 #[derive(PartialEq, Clone)]
134 struct K {
135 x: i8,
136 }
137
138 impl Hash for K {
139 fn hash<H: Hasher>(&self, _: &mut H) {}
140 }
141
142 let m = HashMap::new()
143 .put(K { x: 1 }, 1)
144 .put(K { x: -1 }, 10)
145 .delete(K { x: 1 });
146 assert!(m.is_some());
147 let m2 = m.unwrap();
148 assert_eq!(m2.get(&K { x: 1 }), None);
149 assert_eq!(m2.get(&K { x: -1 }), Some(&10));
150 }
151}