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}