Skip to main content

weak_table/
ptr_weak_key_hash_map.rs

1//! A hash map where the keys are held by weak pointers and compared by pointer.
2
3use crate::compat::*;
4
5use super::by_ptr::*;
6use super::traits::*;
7use super::weak_key_hash_map as base;
8
9pub use super::weak_key_hash_map::{
10    Drain, Entry, IntoIter, Iter, IterMut, Keys, Values, ValuesMut,
11};
12pub use super::PtrWeakKeyHashMap;
13
14impl<K: WeakElement, V> PtrWeakKeyHashMap<K, V, RandomState>
15where
16    K::Strong: Deref,
17{
18    /// Creates an empty `PtrWeakKeyHashMap`.
19    ///
20    /// *O*(1) time
21    pub fn new() -> Self {
22        PtrWeakKeyHashMap(base::WeakKeyHashMap::new())
23    }
24
25    /// Creates an empty `PtrWeakKeyHashMap` with the given capacity.
26    ///
27    /// *O*(*n*) time
28    pub fn with_capacity(capacity: usize) -> Self {
29        PtrWeakKeyHashMap(base::WeakKeyHashMap::with_capacity(capacity))
30    }
31}
32
33impl<K: WeakElement, V, S: BuildHasher> PtrWeakKeyHashMap<K, V, S>
34where
35    K::Strong: Deref,
36{
37    /// Creates an empty `PtrWeakKeyHashMap` with the given hasher.
38    ///
39    /// *O*(*n*) time
40    pub fn with_hasher(hash_builder: S) -> Self {
41        PtrWeakKeyHashMap(base::WeakKeyHashMap::with_hasher(hash_builder))
42    }
43
44    /// Creates an empty `PtrWeakKeyHashMap` with the given capacity and hasher.
45    ///
46    /// *O*(*n*) time
47    pub fn with_capacity_and_hasher(capacity: usize, hash_builder: S) -> Self {
48        PtrWeakKeyHashMap(base::WeakKeyHashMap::with_capacity_and_hasher(
49            capacity,
50            hash_builder,
51        ))
52    }
53
54    /// Returns a reference to the map's `BuildHasher`.
55    ///
56    /// *O*(1) time
57    pub fn hasher(&self) -> &S {
58        self.0.hasher()
59    }
60
61    /// Returns the number of elements the map can hold without reallocating.
62    ///
63    /// *O*(1) time
64    pub fn capacity(&self) -> usize {
65        self.0.capacity()
66    }
67
68    /// Removes all mappings whose keys have expired.
69    ///
70    /// *O*(*n*) time
71    pub fn remove_expired(&mut self) {
72        self.0.remove_expired();
73    }
74
75    /// Reserves room for additional elements.
76    ///
77    /// This method ensures that at least `additional_capacity` insertions
78    /// may be performed without reallocating.
79    ///
80    /// *O*(*n*) time
81    pub fn reserve(&mut self, additional_capacity: usize) {
82        self.0.reserve(additional_capacity);
83    }
84
85    /// Shrinks the capacity to the minimum allowed to hold the current number of elements.
86    ///
87    /// *O*(*n*) time
88    pub fn shrink_to_fit(&mut self) {
89        self.0.shrink_to_fit();
90    }
91
92    /// Returns an over-approximation of the number of elements.
93    ///
94    /// (This is an over-approximation because it includes expired elements.)
95    ///
96    /// (This is an over-approximation because it includes expired elements.)
97    ///    /// *O*(1) time
98    pub fn len(&self) -> usize {
99        self.0.len()
100    }
101
102    /// Is the map known to be empty?
103    ///
104    /// This could answer `false` for an empty map whose keys have
105    /// expired but have yet to be collected.
106    ///
107    /// *O*(1) time
108    pub fn is_empty(&self) -> bool {
109        self.len() == 0
110    }
111
112    /// The proportion of buckets that are used.
113    ///
114    /// This is an over-approximation because of expired keys.
115    ///
116    /// *O*(1) time
117    pub fn load_factor(&self) -> f32 {
118        self.0.load_factor()
119    }
120
121    /// Gets the requested entry.
122    ///
123    /// expected *O*(1) time; worst-case *O*(*p*) time
124    pub fn entry(&mut self, key: K::Strong) -> Entry<'_, ByPtr<K>, V> {
125        self.0.entry(key)
126    }
127
128    /// Removes all associations from the map.
129    ///
130    /// *O*(*n*) time
131    pub fn clear(&mut self) {
132        self.0.clear();
133    }
134
135    /// Returns a reference to the value corresponding to the key.
136    ///
137    /// Returns `None` if no matching key is found.
138    ///
139    /// expected *O*(1) time; worst-case *O*(*p*) time
140    pub fn get(&self, key: &K::Strong) -> Option<&V> {
141        self.0.get(&(key.deref() as *const _))
142    }
143
144    /// Returns true if the map contains the specified key.
145    ///
146    /// expected *O*(1) time; worst-case *O*(*p*) time
147    pub fn contains_key(&self, key: &K::Strong) -> bool {
148        self.0.contains_key(&(key.deref() as *const _))
149    }
150
151    /// Returns a mutable reference to the value corresponding to the key.
152    ///
153    /// Returns `None` if no matching key is found.
154    ///
155    /// expected *O*(1) time; worst-case *O*(*p*) time
156    pub fn get_mut(&mut self, key: &K::Strong) -> Option<&mut V> {
157        self.0.get_mut(&(key.deref() as *const _))
158    }
159
160    /// Unconditionally inserts the value, returning the old value if already present. Does not
161    /// replace the key.
162    ///
163    /// expected *O*(1) time; worst-case *O*(*p*) time
164    pub fn insert(&mut self, key: K::Strong, value: V) -> Option<V> {
165        self.0.insert(key, value)
166    }
167
168    /// Removes the entry with the given key, if it exists, and returns the value.
169    ///
170    /// expected *O*(1) time; worst-case *O*(*p*) time
171    pub fn remove(&mut self, key: &K::Strong) -> Option<V> {
172        self.0.remove(&(key.deref() as *const _))
173    }
174
175    /// Removes all mappings not satisfying the given predicate.
176    ///
177    /// Also removes any expired mappings.
178    ///
179    /// *O*(*n*) time
180    pub fn retain<F>(&mut self, f: F)
181    where
182        F: FnMut(K::Strong, &mut V) -> bool,
183    {
184        self.0.retain(f);
185    }
186
187    /// Is this map a submap of the other, using the given value comparison.
188    ///
189    /// In particular, all the keys of self must be in other and the values must compare true with
190    /// value_equal.
191    ///
192    /// expected *O*(*n*) time; worst-case *O*(*nq*) time (where *n* is
193    /// `self.capacity()` and *q* is the length of the probe sequences
194    /// in `other`)
195    pub fn submap_with<F, S1, V1>(
196        &self,
197        other: &PtrWeakKeyHashMap<K, V1, S1>,
198        value_equal: F,
199    ) -> bool
200    where
201        F: FnMut(&V, &V1) -> bool,
202        S1: BuildHasher,
203    {
204        self.0.is_submap_with(&other.0, value_equal)
205    }
206
207    /// Is self a submap of other?
208    ///
209    /// expected *O*(*n*) time; worst-case *O*(*nq*) time (where *n* is
210    /// `self.capacity()` and *q* is the length of the probe sequences
211    /// in `other`)
212    pub fn is_submap<V1, S1>(&self, other: &PtrWeakKeyHashMap<K, V1, S1>) -> bool
213    where
214        V: PartialEq<V1>,
215        S1: BuildHasher,
216    {
217        self.0.is_submap(&other.0)
218    }
219
220    /// Are the keys of self a subset of the keys of other?
221    ///
222    /// expected *O*(*n*) time; worst-case *O*(*nq*) time (where *n* is
223    /// `self.capacity()` and *q* is the length of the probe sequences
224    /// in `other`)
225    pub fn domain_is_subset<V1, S1>(&self, other: &PtrWeakKeyHashMap<K, V1, S1>) -> bool
226    where
227        S1: BuildHasher,
228    {
229        self.0.domain_is_subset(&other.0)
230    }
231}
232
233impl<K: WeakElement, V, S> PtrWeakKeyHashMap<K, V, S>
234where
235    K::Strong: Deref,
236{
237    /// Gets an iterator over the keys and values.
238    ///
239    /// *O*(1) time
240    pub fn iter(&self) -> Iter<'_, ByPtr<K>, V> {
241        self.0.iter()
242    }
243
244    /// Gets an iterator over the keys.
245    ///
246    /// *O*(1) time
247    pub fn keys(&self) -> Keys<'_, ByPtr<K>, V> {
248        self.0.keys()
249    }
250
251    /// Gets an iterator over the values.
252    ///
253    /// *O*(1) time
254    pub fn values(&self) -> Values<'_, ByPtr<K>, V> {
255        self.0.values()
256    }
257
258    /// Gets an iterator over the keys and mutable values.
259    ///
260    /// *O*(1) time
261    pub fn iter_mut(&mut self) -> IterMut<'_, ByPtr<K>, V> {
262        self.0.iter_mut()
263    }
264
265    /// Gets an iterator over the mutable values.
266    ///
267    /// *O*(1) time
268    pub fn values_mut(&mut self) -> ValuesMut<'_, ByPtr<K>, V> {
269        self.0.values_mut()
270    }
271
272    /// Gets a draining iterator, which removes all the values but retains the storage.
273    ///
274    /// *O*(1) time (and *O*(*n*) time to dispose of the result)
275    pub fn drain(&mut self) -> Drain<'_, ByPtr<K>, V> {
276        self.0.drain()
277    }
278}
279
280impl<K, V, V1, S, S1> PartialEq<PtrWeakKeyHashMap<K, V1, S1>> for PtrWeakKeyHashMap<K, V, S>
281where
282    K: WeakElement,
283    K::Strong: Deref,
284    V: PartialEq<V1>,
285    S: BuildHasher,
286    S1: BuildHasher,
287{
288    fn eq(&self, other: &PtrWeakKeyHashMap<K, V1, S1>) -> bool {
289        self.0 == other.0
290    }
291}
292
293impl<K: WeakElement, V: Eq, S: BuildHasher> Eq for PtrWeakKeyHashMap<K, V, S> where K::Strong: Deref {}
294
295impl<K: WeakElement, V, S: BuildHasher + Default> Default for PtrWeakKeyHashMap<K, V, S>
296where
297    K::Strong: Deref,
298{
299    fn default() -> Self {
300        PtrWeakKeyHashMap(base::WeakKeyHashMap::<ByPtr<K>, V, S>::default())
301    }
302}
303
304impl<'a, K, V, S> Index<&'a K::Strong> for PtrWeakKeyHashMap<K, V, S>
305where
306    K: WeakElement,
307    K::Strong: Deref,
308    S: BuildHasher,
309{
310    type Output = V;
311
312    fn index(&self, index: &'a K::Strong) -> &Self::Output {
313        self.0.index(&(index.deref() as *const _))
314    }
315}
316
317impl<'a, K, V, S> IndexMut<&'a K::Strong> for PtrWeakKeyHashMap<K, V, S>
318where
319    K: WeakElement,
320    K::Strong: Deref,
321    S: BuildHasher,
322{
323    fn index_mut(&mut self, index: &'a K::Strong) -> &mut Self::Output {
324        self.0.index_mut(&(index.deref() as *const _))
325    }
326}
327
328impl<K, V, S> FromIterator<(K::Strong, V)> for PtrWeakKeyHashMap<K, V, S>
329where
330    K: WeakElement,
331    K::Strong: Deref,
332    S: BuildHasher + Default,
333{
334    fn from_iter<T: IntoIterator<Item = (K::Strong, V)>>(iter: T) -> Self {
335        PtrWeakKeyHashMap(base::WeakKeyHashMap::<ByPtr<K>, V, S>::from_iter(iter))
336    }
337}
338
339impl<K, V, S> Extend<(K::Strong, V)> for PtrWeakKeyHashMap<K, V, S>
340where
341    K: WeakElement,
342    K::Strong: Deref,
343    S: BuildHasher,
344{
345    fn extend<T: IntoIterator<Item = (K::Strong, V)>>(&mut self, iter: T) {
346        self.0.extend(iter);
347    }
348}
349
350impl<'a, K, V, S> Extend<(&'a K::Strong, &'a V)> for PtrWeakKeyHashMap<K, V, S>
351where
352    K: 'a + WeakElement,
353    K::Strong: Clone + Deref,
354    V: 'a + Clone,
355    S: BuildHasher,
356{
357    fn extend<T: IntoIterator<Item = (&'a K::Strong, &'a V)>>(&mut self, iter: T) {
358        self.0.extend(iter);
359    }
360}
361
362impl<K, V: Debug, S> Debug for PtrWeakKeyHashMap<K, V, S>
363where
364    K: WeakElement,
365    K::Strong: Debug,
366{
367    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
368        self.0.fmt(f)
369    }
370}
371
372impl<K: WeakElement, V, S> IntoIterator for PtrWeakKeyHashMap<K, V, S> {
373    type Item = (K::Strong, V);
374    type IntoIter = IntoIter<ByPtr<K>, V>;
375
376    /// Creates an owning iterator from `self`.
377    ///
378    /// *O*(1) time (and *O*(*n*) time to dispose of the result)
379    fn into_iter(self) -> Self::IntoIter {
380        self.0.into_iter()
381    }
382}
383
384impl<'a, K: WeakElement, V, S> IntoIterator for &'a PtrWeakKeyHashMap<K, V, S> {
385    type Item = (K::Strong, &'a V);
386    type IntoIter = Iter<'a, ByPtr<K>, V>;
387
388    /// Creates a borrowing iterator from `self`.
389    ///
390    /// *O*(1) time
391    fn into_iter(self) -> Self::IntoIter {
392        (&self.0).into_iter()
393    }
394}
395
396impl<'a, K: WeakElement, V, S> IntoIterator for &'a mut PtrWeakKeyHashMap<K, V, S> {
397    type Item = (K::Strong, &'a mut V);
398    type IntoIter = IterMut<'a, ByPtr<K>, V>;
399
400    /// Creates a borrowing iterator from `self`.
401    ///
402    /// *O*(1) time
403    fn into_iter(self) -> Self::IntoIter {
404        (&mut self.0).into_iter()
405    }
406}
407
408#[cfg(test)]
409mod test {
410    #![allow(clippy::print_stderr)]
411
412    use super::{Entry, PtrWeakKeyHashMap};
413    use crate::compat::{
414        eprintln,
415        rc::{Rc, Weak},
416        Vec,
417    };
418
419    //    fn show_me(weakmap: &PtrWeakKeyHashMap<Weak<u32>, f32>) {
420    //        for (key, _) in weakmap {
421    //            eprint!(" {:2}", *key);
422    //        }
423    //        eprintln!();
424    //    }
425
426    // From https://github.com/tov/weak-table-rs/issues/1#issuecomment-461858060
427    #[test]
428    fn insert_and_check() {
429        let mut rcs: Vec<Rc<u32>> = Vec::new();
430
431        for i in 0..200 {
432            rcs.push(Rc::new(i));
433        }
434
435        let mut weakmap: PtrWeakKeyHashMap<Weak<u32>, f32> = PtrWeakKeyHashMap::new();
436
437        for item in rcs.iter().cloned() {
438            let f = *item as f32 + 0.1;
439            weakmap.insert(item, f);
440        }
441
442        let mut count = 0;
443
444        for item in &rcs {
445            assert!(weakmap.contains_key(item));
446
447            match weakmap.entry(Rc::clone(item)) {
448                Entry::Occupied(_) => count += 1,
449                Entry::Vacant(_) => eprintln!("PointerWeakKeyHashMap: missing: {}", *item),
450            }
451        }
452
453        assert_eq!(count, rcs.len());
454    }
455}