fallacy_hash/hash_map.rs
1//! A hash map implemented with quadratic probing.
2
3pub use std::collections::hash_map::{
4 Drain, Entry, IntoIter, IntoKeys, IntoValues, Iter, IterMut, Keys, Values, ValuesMut,
5};
6
7use crate::AllocError;
8use crate::FxBuildHasher;
9use std::borrow::Borrow;
10use std::collections::HashMap as StdHashMap;
11use std::fmt;
12use std::fmt::Debug;
13use std::hash::{BuildHasher, Hash};
14use std::ops::Index;
15
16/// A hash map implemented with quadratic probing.
17#[repr(transparent)]
18pub struct HashMap<K, V, S = FxBuildHasher>(StdHashMap<K, V, S>);
19
20impl<K, V> HashMap<K, V, FxBuildHasher> {
21 /// Creates an empty `HashMap`.
22 ///
23 /// The hash map is initially created with a capacity of 0, so it will not allocate until it
24 /// is first inserted into.
25 #[must_use]
26 #[inline]
27 pub fn new() -> HashMap<K, V, FxBuildHasher> {
28 HashMap::default()
29 }
30}
31
32impl<K, V, S> HashMap<K, V, S> {
33 #[inline]
34 pub fn from_std(hash_map: StdHashMap<K, V, S>) -> Self {
35 HashMap(hash_map)
36 }
37
38 #[inline]
39 pub fn into_std(self) -> StdHashMap<K, V, S> {
40 self.0
41 }
42
43 /// Creates an empty `HashMap` which will use the given hash builder to hash
44 /// keys.
45 ///
46 /// The created map has the default initial capacity.
47 ///
48 /// Warning: `hash_builder` is normally randomly generated, and
49 /// is designed to allow HashMaps to be resistant to attacks that
50 /// cause many collisions and very poor performance. Setting it
51 /// manually using this function can expose a DoS attack vector.
52 ///
53 /// The `hash_builder` passed should implement the [`BuildHasher`] trait for
54 /// the HashMap to be useful, see its documentation for details.
55 #[inline]
56 pub fn with_hasher(hash_builder: S) -> HashMap<K, V, S> {
57 HashMap(StdHashMap::with_hasher(hash_builder))
58 }
59
60 /// Returns the number of elements the map can hold without reallocating.
61 ///
62 /// This number is a lower bound; the `HashMap<K, V>` might be able to hold
63 /// more, but is guaranteed to be able to hold at least this many.
64 #[inline]
65 pub fn capacity(&self) -> usize {
66 self.0.capacity()
67 }
68
69 /// An iterator visiting all keys in arbitrary order.
70 /// The iterator element type is `&'a K`.
71 #[inline]
72 pub fn keys(&self) -> Keys<'_, K, V> {
73 self.0.keys()
74 }
75
76 /// Creates a consuming iterator visiting all the keys in arbitrary order.
77 /// The map cannot be used after calling this.
78 /// The iterator element type is `K`.
79 #[inline]
80 pub fn into_keys(self) -> IntoKeys<K, V> {
81 self.0.into_keys()
82 }
83
84 /// An iterator visiting all values in arbitrary order.
85 /// The iterator element type is `&'a V`.
86 #[inline]
87 pub fn values(&self) -> Values<'_, K, V> {
88 self.0.values()
89 }
90
91 /// An iterator visiting all values mutably in arbitrary order.
92 /// The iterator element type is `&'a mut V`.
93 #[inline]
94 pub fn values_mut(&mut self) -> ValuesMut<'_, K, V> {
95 self.0.values_mut()
96 }
97
98 /// Creates a consuming iterator visiting all the values in arbitrary order.
99 /// The map cannot be used after calling this.
100 /// The iterator element type is `V`.
101 #[inline]
102 pub fn into_values(self) -> IntoValues<K, V> {
103 self.0.into_values()
104 }
105
106 /// An iterator visiting all key-value pairs in arbitrary order.
107 /// The iterator element type is `(&'a K, &'a V)`.
108 #[inline]
109 pub fn iter(&self) -> Iter<'_, K, V> {
110 self.0.iter()
111 }
112
113 /// An iterator visiting all key-value pairs in arbitrary order,
114 /// with mutable references to the values.
115 /// The iterator element type is `(&'a K, &'a mut V)`.
116 #[inline]
117 pub fn iter_mut(&mut self) -> IterMut<'_, K, V> {
118 self.0.iter_mut()
119 }
120
121 /// Returns the number of elements in the map.
122 #[inline]
123 pub fn len(&self) -> usize {
124 self.0.len()
125 }
126
127 /// Returns `true` if the map contains no elements.
128 #[inline]
129 pub fn is_empty(&self) -> bool {
130 self.0.is_empty()
131 }
132
133 /// Clears the map, returning all key-value pairs as an iterator. Keeps the
134 /// allocated memory for reuse.
135 ///
136 /// If the returned iterator is dropped before being fully consumed, it
137 /// drops the remaining key-value pairs. The returned iterator keeps a
138 /// mutable borrow on the vector to optimize its implementation.
139 #[inline]
140 pub fn drain(&mut self) -> Drain<'_, K, V> {
141 self.0.drain()
142 }
143
144 /// Retains only the elements specified by the predicate.
145 ///
146 /// In other words, remove all pairs `(k, v)` for which `f(&k, &mut v)` returns `false`.
147 /// The elements are visited in unsorted (and unspecified) order.
148 #[inline]
149 pub fn retain<F>(&mut self, f: F)
150 where
151 F: FnMut(&K, &mut V) -> bool,
152 {
153 self.0.retain(f);
154 }
155
156 /// Clears the map, removing all key-value pairs. Keeps the allocated memory
157 /// for reuse.
158 #[inline]
159 pub fn clear(&mut self) {
160 self.0.clear();
161 }
162
163 /// Returns a reference to the map's [`BuildHasher`].
164 #[inline]
165 pub fn hasher(&self) -> &S {
166 self.0.hasher()
167 }
168}
169
170impl<K, V, S> HashMap<K, V, S>
171where
172 K: Eq + Hash,
173 S: BuildHasher,
174{
175 /// Creates an empty `HashMap` with the specified capacity.
176 ///
177 /// The hash map will be able to hold at least `capacity` elements without
178 /// reallocating. If `capacity` is 0, the hash map will not allocate.
179 #[inline]
180 pub fn try_with_capacity(capacity: usize) -> Result<HashMap<K, V, S>, AllocError>
181 where
182 S: Default,
183 {
184 let mut m = StdHashMap::with_hasher(Default::default());
185 m.try_reserve(capacity)?;
186 Ok(HashMap(m))
187 }
188
189 /// Creates an empty `HashMap` with the specified capacity, using `hash_builder`
190 /// to hash the keys.
191 ///
192 /// The hash map will be able to hold at least `capacity` elements without
193 /// reallocating. If `capacity` is 0, the hash map will not allocate.
194 ///
195 /// Warning: `hash_builder` is normally randomly generated, and
196 /// is designed to allow HashMaps to be resistant to attacks that
197 /// cause many collisions and very poor performance. Setting it
198 /// manually using this function can expose a DoS attack vector.
199 ///
200 /// The `hash_builder` passed should implement the [`BuildHasher`] trait for
201 /// the HashMap to be useful, see its documentation for details.
202 #[inline]
203 pub fn try_with_capacity_and_hasher(capacity: usize, hash_builder: S) -> Result<HashMap<K, V, S>, AllocError> {
204 let mut m = StdHashMap::with_hasher(hash_builder);
205 m.try_reserve(capacity)?;
206 Ok(HashMap(m))
207 }
208
209 /// Tries to reserve capacity for at least `additional` more elements to be inserted
210 /// in the given `HashMap<K, V>`. The collection may reserve more space to avoid
211 /// frequent reallocations.
212 ///
213 /// # Errors
214 ///
215 /// If the capacity overflows, or the allocator reports a failure, then an error
216 /// is returned.
217 #[inline]
218 pub fn try_reserve(&mut self, additional: usize) -> Result<(), AllocError> {
219 self.0.try_reserve(additional)?;
220 Ok(())
221 }
222
223 /// Gets the given key's corresponding entry in the map for in-place manipulation.
224 #[inline]
225 pub fn try_entry(&mut self, key: K) -> Result<Entry<'_, K, V>, AllocError> {
226 self.0.try_reserve(1)?;
227 Ok(self.0.entry(key))
228 }
229
230 /// Returns a reference to the value corresponding to the key.
231 ///
232 /// The key may be any borrowed form of the map's key type, but
233 /// [`Hash`] and [`Eq`] on the borrowed form *must* match those for
234 /// the key type.
235 #[inline]
236 pub fn get<Q: ?Sized>(&self, k: &Q) -> Option<&V>
237 where
238 K: Borrow<Q>,
239 Q: Hash + Eq,
240 {
241 self.0.get(k)
242 }
243
244 /// Returns the key-value pair corresponding to the supplied key.
245 ///
246 /// The supplied key may be any borrowed form of the map's key type, but
247 /// [`Hash`] and [`Eq`] on the borrowed form *must* match those for
248 /// the key type.
249 #[inline]
250 pub fn get_key_value<Q: ?Sized>(&self, k: &Q) -> Option<(&K, &V)>
251 where
252 K: Borrow<Q>,
253 Q: Hash + Eq,
254 {
255 self.0.get_key_value(k)
256 }
257
258 /// Returns `true` if the map contains a value for the specified key.
259 ///
260 /// The key may be any borrowed form of the map's key type, but
261 /// [`Hash`] and [`Eq`] on the borrowed form *must* match those for
262 /// the key type.
263 #[inline]
264 pub fn contains_key<Q: ?Sized>(&self, k: &Q) -> bool
265 where
266 K: Borrow<Q>,
267 Q: Hash + Eq,
268 {
269 self.0.contains_key(k)
270 }
271
272 /// Returns a mutable reference to the value corresponding to the key.
273 ///
274 /// The key may be any borrowed form of the map's key type, but
275 /// [`Hash`] and [`Eq`] on the borrowed form *must* match those for
276 /// the key type.
277 #[inline]
278 pub fn get_mut<Q: ?Sized>(&mut self, k: &Q) -> Option<&mut V>
279 where
280 K: Borrow<Q>,
281 Q: Hash + Eq,
282 {
283 self.0.get_mut(k)
284 }
285
286 /// Inserts a key-value pair into the map.
287 ///
288 /// If the map did not have this key present, [`None`] is returned.
289 ///
290 /// If the map did have this key present, the value is updated, and the old
291 /// value is returned. The key is not updated, though; this matters for
292 /// types that can be `==` without being identical.
293 #[inline]
294 pub fn try_insert(&mut self, k: K, v: V) -> Result<Option<V>, AllocError> {
295 self.0.try_reserve(1)?;
296 Ok(self.0.insert(k, v))
297 }
298
299 /// Removes a key from the map, returning the value at the key if the key
300 /// was previously in the map.
301 ///
302 /// The key may be any borrowed form of the map's key type, but
303 /// [`Hash`] and [`Eq`] on the borrowed form *must* match those for
304 /// the key type.
305 #[inline]
306 pub fn remove<Q: ?Sized>(&mut self, k: &Q) -> Option<V>
307 where
308 K: Borrow<Q>,
309 Q: Hash + Eq,
310 {
311 self.0.remove(k)
312 }
313
314 /// Removes a key from the map, returning the stored key and value if the
315 /// key was previously in the map.
316 ///
317 /// The key may be any borrowed form of the map's key type, but
318 /// [`Hash`] and [`Eq`] on the borrowed form *must* match those for
319 /// the key type.
320 #[inline]
321 pub fn remove_entry<Q: ?Sized>(&mut self, k: &Q) -> Option<(K, V)>
322 where
323 K: Borrow<Q>,
324 Q: Hash + Eq,
325 {
326 self.0.remove_entry(k)
327 }
328}
329
330impl<K, V, S> Default for HashMap<K, V, S>
331where
332 S: Default,
333{
334 #[inline]
335 fn default() -> Self {
336 HashMap::with_hasher(Default::default())
337 }
338}
339
340impl<K, V, S> PartialEq for HashMap<K, V, S>
341where
342 K: Eq + Hash,
343 V: PartialEq,
344 S: BuildHasher,
345{
346 #[inline]
347 fn eq(&self, other: &HashMap<K, V, S>) -> bool {
348 self.0.eq(&other.0)
349 }
350}
351
352impl<K, V, S> Eq for HashMap<K, V, S>
353where
354 K: Eq + Hash,
355 V: Eq,
356 S: BuildHasher,
357{
358}
359
360impl<K, V, S> Debug for HashMap<K, V, S>
361where
362 K: Debug,
363 V: Debug,
364{
365 #[inline]
366 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
367 Debug::fmt(&self.0, f)
368 }
369}
370
371impl<K, Q: ?Sized, V, S> Index<&Q> for HashMap<K, V, S>
372where
373 K: Eq + Hash + Borrow<Q>,
374 Q: Eq + Hash,
375 S: BuildHasher,
376{
377 type Output = V;
378
379 /// Returns a reference to the value corresponding to the supplied key.
380 ///
381 /// # Panics
382 ///
383 /// Panics if the key is not present in the `HashMap`.
384 #[inline]
385 fn index(&self, key: &Q) -> &V {
386 self.0.index(key)
387 }
388}
389
390impl<'a, K, V, S> IntoIterator for &'a HashMap<K, V, S> {
391 type Item = (&'a K, &'a V);
392 type IntoIter = Iter<'a, K, V>;
393
394 #[inline]
395 fn into_iter(self) -> Iter<'a, K, V> {
396 self.iter()
397 }
398}
399
400impl<'a, K, V, S> IntoIterator for &'a mut HashMap<K, V, S> {
401 type Item = (&'a K, &'a mut V);
402 type IntoIter = IterMut<'a, K, V>;
403
404 #[inline]
405 fn into_iter(self) -> IterMut<'a, K, V> {
406 self.iter_mut()
407 }
408}
409
410impl<K, V, S> IntoIterator for HashMap<K, V, S> {
411 type Item = (K, V);
412 type IntoIter = IntoIter<K, V>;
413
414 /// Creates a consuming iterator, that is, one that moves each key-value
415 /// pair out of the map in arbitrary order. The map cannot be used after
416 /// calling this.
417 #[inline]
418 fn into_iter(self) -> IntoIter<K, V> {
419 self.0.into_iter()
420 }
421}
422
423#[cfg(feature = "serde")]
424mod serde {
425 use crate::HashMap;
426 use serde::de::{MapAccess, Visitor};
427 use serde::{de::Error, Deserialize, Deserializer, Serialize, Serializer};
428 use std::fmt;
429 use std::hash::{BuildHasher, Hash};
430 use std::marker::PhantomData;
431
432 impl<K, V, H> Serialize for HashMap<K, V, H>
433 where
434 K: Eq + Hash + Serialize,
435 V: Serialize,
436 H: BuildHasher,
437 {
438 #[inline]
439 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
440 where
441 S: Serializer,
442 {
443 serializer.collect_map(self)
444 }
445 }
446
447 impl<'de, K, V, H> Deserialize<'de> for HashMap<K, V, H>
448 where
449 K: Eq + Hash + Deserialize<'de>,
450 V: Deserialize<'de>,
451 H: BuildHasher + Default + Deserialize<'de>,
452 {
453 #[inline]
454 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
455 where
456 D: Deserializer<'de>,
457 {
458 struct MapVisitor<K, V, H> {
459 _marker: PhantomData<HashMap<K, V, H>>,
460 }
461
462 impl<'de, K, V, H> Visitor<'de> for MapVisitor<K, V, H>
463 where
464 K: Eq + Hash + Deserialize<'de>,
465 V: Deserialize<'de>,
466 H: BuildHasher + Default + Deserialize<'de>,
467 {
468 type Value = HashMap<K, V, H>;
469
470 #[inline]
471 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
472 formatter.write_str("a map")
473 }
474
475 #[inline]
476 fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
477 where
478 A: MapAccess<'de>,
479 {
480 let cap = map.size_hint().unwrap_or(8).min(4096);
481 let mut values =
482 HashMap::try_with_capacity_and_hasher(cap, H::default()).map_err(A::Error::custom)?;
483
484 while let Some((key, value)) = map.next_entry()? {
485 values.try_insert(key, value).map_err(A::Error::custom)?;
486 }
487
488 Ok(values)
489 }
490 }
491
492 let visitor = MapVisitor { _marker: PhantomData };
493 deserializer.deserialize_map(visitor)
494 }
495 }
496}