1use core::*;
32use crate::*;
33use crate::hash::*;
34
35
36struct KeyValue<K : Hash + PartialEq, V> {
37 hash : usize,
38 key : K,
39 value : V,
40}
41
42impl<K: Hash + PartialEq, V> KeyValue<K, V> {
43 pub fn is_empty(&self) -> bool { self.hash == 0 }
44}
45
46pub struct HashMap<K: Hash + PartialEq, V> {
47 table : Unique<KeyValue<K, V>>,
48 capacity: usize,
49 count : usize,
50}
51
52impl<K: Hash + PartialEq, V> HashMap<K, V> {
53 pub fn new() -> Self {
54 Self {
55 table : Unique::new(ptr::null_mut()),
56 count : 0,
57 capacity: 0,
58 }
59 }
60
61 pub fn count(&self) -> usize { self.count }
62
63 #[inline]
64 fn hash(k: &K) -> usize {
65 match k.hash() {
66 0 => 1,
67 h => h,
68 }
69 }
70
71 #[inline]
72 fn next(&self, index: isize) -> isize {
73 let mut ret = index - 1;
74 if ret < 0 { ret += self.capacity as isize }
75 ret
76 }
77
78 fn unchecked_set(&mut self, k: K, v: V) {
79 let hash = Self::hash(&k);
80 let mut index = (hash & (self.capacity - 1)) as isize;
81 let entries = unsafe { core::slice::from_raw_parts_mut(self.table.get_mut_ptr(), self.capacity) };
82
83 for _ in 0..self.capacity {
84 let mut e = &mut entries[index as usize];
85 if e.is_empty() {
86 e.key = k;
87 e.value = v;
88 e.hash = hash;
89 self.count += 1;
90 return;
91 }
92
93 if hash == e.hash && k == e.key {
94 e.value = v;
95 return;
96 }
97
98 index = self.next(index);
99 }
100 panic!("uncheckedSet shouldn't reach this point");
101 }
102
103 fn new_with_cap(cap: usize) -> Self {
104 Self {
105 table : Unique::new(unsafe { alloc_array_zeroed(cap) }),
106 count : 0,
107 capacity: cap,
108 }
109 }
110
111 fn grow(&mut self, new_cap: usize) {
112 let old_entries = unsafe { core::slice::from_raw_parts(self.table.get_ptr(), self.capacity) };
113 let mut new_hm = HashMap::<K, V>::new_with_cap(new_cap);
114 for o in old_entries {
115 if !o.is_empty() {
116 unsafe {
117 new_hm.unchecked_set(::core::ptr::read_unaligned(&o.key),
118 ::core::ptr::read_unaligned(&o.value));
119 }
120 }
121 }
122
123 unsafe { free_array_ptr(self.table.get_mut_ptr(), self.capacity) };
124 self.count = 0;
125 self.capacity = 0;
126
127 *self = new_hm;
128 }
129
130 pub fn set(&mut self, k: K, v: V) {
131 if 4 * self.count >= 3 * self.capacity {
132 self.grow(if self.capacity == 0 { 4 } else { self.capacity * 2 });
133 }
134 self.unchecked_set(k, v)
135 }
136
137 pub fn exist(&self, k: K) -> bool {
138 let hash = Self::hash(&k);
139 let mut index = (hash & (self.capacity - 1)) as isize;
140 let entries = unsafe { core::slice::from_raw_parts(self.table.get_ptr(), self.capacity) };
141
142 for _ in 0..self.capacity {
143 let e = &entries[index as usize];
144 if e.is_empty() {
145 return false;
146 }
147
148 if hash == e.hash && k == e.key {
149 return true;
150 }
151
152 index = self.next(index);
153 }
154 false
155 }
156
157 pub fn get(&self, k: K) -> Option<&V> {
158 let hash = Self::hash(&k);
159 let mut index = (hash & (self.capacity - 1)) as isize;
160 let entries = unsafe { core::slice::from_raw_parts(self.table.get_ptr(), self.capacity) };
161
162 for _ in 0..self.capacity {
163 let e = &entries[index as usize];
164 if e.is_empty() {
165 return None;
166 }
167
168 if hash == e.hash && k == e.key {
169 return Some(&e.value);
170 }
171
172 index = self.next(index);
173 }
174 None
175 }
176
177 pub fn remove(&mut self, k: K) {
178 let hash = Self::hash(&k);
179 let mut index = (hash & (self.capacity - 1)) as isize;
180 let entries = unsafe { core::slice::from_raw_parts_mut(self.table.get_mut_ptr(), self.capacity) };
181
182 for _ in 0..self.capacity {
183 let e = &entries[index as usize];
184 if e.is_empty() {
185 return;
186 }
187
188 if hash == e.hash && k == e.key {
189 self.count -= 1;
190 break;
191 }
192
193 index = self.next(index);
194 }
195
196 loop {
197 let empty_index = index;
198 let mut original_index;
199 loop {
200 index = self.next(index);
201 let s = &entries[index as usize];
202 if s.is_empty() {
203 entries[empty_index as usize].hash = 0;
204 unsafe { ::core::ptr::read_unaligned(&entries[empty_index as usize]) }; return;
206 }
207
208 original_index = (s.hash & (self.capacity - 1)) as isize;
209
210 if ! ((index <= original_index && original_index < empty_index)
211 || (original_index < empty_index && empty_index < index)
212 || (empty_index < index && index <= original_index)) {
213 break;
214 }
215 }
216
217 entries[empty_index as usize] = unsafe { ::core::ptr::read_unaligned(&entries[index as usize]) };
218 entries[index as usize].hash = 0;
219 }
220 }
221}
222
223impl<K : Hash + PartialEq, V> Drop for HashMap<K, V> {
224 fn drop(&mut self) {
225 if self.capacity > 0 {
226 let arr = unsafe { core::slice::from_raw_parts_mut(self.table.get_mut_ptr(), self.capacity) };
227 for kv in arr {
228 if !kv.is_empty() {
229 unsafe { ptr::drop_in_place(&kv.key as *const K as *mut K) };
230 unsafe { ptr::drop_in_place(&kv.value as *const V as *mut V) };
231 }
232 }
233 unsafe { free_array_ptr(self.table.get_mut_ptr(), self.capacity) }
234 }
235 }
236}
237
238impl Hash for i32 {
239 fn hash(&self) -> usize { *self as usize }
240}
241
242#[cfg(test)]
243mod test {
244 use super::*;
245 use crate::vec::*;
246
247 #[test]
248 fn test_insert() {
249 let mut hm = HashMap::<i32, i32>::new();
250 for i in 0..100 {
251 hm.set(i, i * 2);
252 }
253
254 for i in 0..100 {
255 let ret = hm.get(i);
256 assert!(ret.is_some());
257 match ret {
258 Some(o) => assert!(*o == i * 2),
259 None => assert!(false)
260 }
261 }
262 }
263
264 #[test]
265 fn test_remove() {
266 let mut hm = HashMap::<i32, i32>::new();
267 for i in 0..100 {
268 hm.set(i, i * 2);
269 }
270
271 for i in 45..55 {
272 hm.remove(i);
273 assert!(hm.exist(i) == false);
274 }
275
276 for i in 0..45 {
277 let ret = hm.get(i);
278 assert!(ret.is_some());
279 match ret {
280 Some(o) => assert!(*o == i * 2),
281 None => assert!(false)
282 }
283 }
284
285 for i in 55..100 {
286 let ret = hm.get(i);
287 assert!(ret.is_some());
288 match ret {
289 Some(o) => assert!(*o == i * 2),
290 None => assert!(false)
291 }
292 }
293
294 for i in 45..55 {
295 assert!(hm.exist(i) == false);
296 }
297
298 assert!(hm.count() == 90);
299 }
300
301 #[test]
302 fn test_vec_insert() {
303 let mut hm = HashMap::<i32, Vec<i32>>::new();
304 for i in 0..100 {
305 let mut v = Vec::new();
306 for j in 0..i * 2 {
307 v.push(j);
308 }
309 hm.set(i, v);
310 }
311
312 for i in 0..100 {
313 let ret = hm.get(i);
314 assert!(ret.is_some());
315 match ret {
316 Some(o) => {
317 for j in 0..i*2 {
318 assert!((*o)[j as usize] == j)
319 }
320 }
321 None => assert!(false)
322 }
323 }
324 }
325}