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