1 //! A hash map where the keys and values are both held by weak pointers, and keys are compared by 2 //! pointer. 3 4 use crate::compat::*; 5 6 use super::by_ptr::*; 7 use super::traits::*; 8 use super::weak_weak_hash_map as base; 9 10 pub use super::PtrWeakWeakHashMap; 11 pub use super::weak_weak_hash_map::{Entry, Iter, Keys, Values, Drain, IntoIter}; 12 13 impl <K: WeakElement, V: WeakElement> PtrWeakWeakHashMap<K, V, RandomState> 14 where K::Strong: Deref 15 { 16 /// Creates an empty `PtrWeakWeakHashMap`. 17 /// 18 /// *O*(1) time new() -> Self19 pub fn new() -> Self { 20 PtrWeakWeakHashMap(base::WeakWeakHashMap::new()) 21 } 22 23 /// Creates an empty `PtrWeakWeakHashMap` with the given capacity. 24 /// 25 /// *O*(*n*) time with_capacity(capacity: usize) -> Self26 pub fn with_capacity(capacity: usize) -> Self { 27 PtrWeakWeakHashMap(base::WeakWeakHashMap::with_capacity(capacity)) 28 } 29 } 30 31 impl <K: WeakElement, V: WeakElement, S: BuildHasher> PtrWeakWeakHashMap<K, V, S> 32 where K::Strong: Deref 33 { 34 /// Creates an empty `PtrWeakWeakHashMap` with the given capacity and hasher. 35 /// 36 /// *O*(*n*) time with_hasher(hash_builder: S) -> Self37 pub fn with_hasher(hash_builder: S) -> Self { 38 PtrWeakWeakHashMap(base::WeakWeakHashMap::with_hasher(hash_builder)) 39 } 40 41 /// Creates an empty `PtrWeakWeakHashMap` with the given capacity and hasher. 42 /// 43 /// *O*(*n*) time with_capacity_and_hasher(capacity: usize, hash_builder: S) -> Self44 pub fn with_capacity_and_hasher(capacity: usize, hash_builder: S) -> Self { 45 PtrWeakWeakHashMap(base::WeakWeakHashMap::with_capacity_and_hasher(capacity, hash_builder)) 46 } 47 48 /// Returns a reference to the map's `BuildHasher`. 49 /// 50 /// *O*(1) time hasher(&self) -> &S51 pub fn hasher(&self) -> &S { 52 self.0.hasher() 53 } 54 55 /// Returns the number of elements the map can hold without reallocating. 56 /// 57 /// *O*(1) time capacity(&self) -> usize58 pub fn capacity(&self) -> usize { 59 self.0.capacity() 60 } 61 62 /// Removes all mappings whose keys have expired. 63 /// 64 /// *O*(*n*) time remove_expired(&mut self)65 pub fn remove_expired(&mut self) { 66 self.0.remove_expired() 67 } 68 69 /// Reserves room for additional elements. 70 /// 71 /// *O*(*n*) time reserve(&mut self, additional_capacity: usize)72 pub fn reserve(&mut self, additional_capacity: usize) { 73 self.0.reserve(additional_capacity) 74 } 75 76 /// Shrinks the capacity to the minimum allowed to hold the current number of elements. 77 /// 78 /// *O*(*n*) time shrink_to_fit(&mut self)79 pub fn shrink_to_fit(&mut self) { 80 self.0.shrink_to_fit() 81 } 82 83 /// Returns an over-approximation of the number of elements. 84 /// 85 /// *O*(1) time len(&self) -> usize86 pub fn len(&self) -> usize { 87 self.0.len() 88 } 89 90 /// Is the map empty? 91 /// 92 /// Note that this may return false even if all keys in the map have 93 /// expired, if they haven't been collected yet. 94 /// 95 /// *O*(1) time is_empty(&self) -> bool96 pub fn is_empty(&self) -> bool { 97 self.0.is_empty() 98 } 99 100 /// The proportion of buckets that are used. 101 /// 102 /// This is an over-approximation because of expired keys. 103 /// 104 /// *O*(1) time load_factor(&self) -> f32105 pub fn load_factor(&self) -> f32 { 106 self.0.load_factor() 107 } 108 109 /// Gets the requested entry. 110 /// 111 /// expected *O*(1) time; worst-case *O*(*p*) time entry(&mut self, key: K::Strong) -> Entry<ByPtr<K>, V>112 pub fn entry(&mut self, key: K::Strong) -> Entry<ByPtr<K>, V> { 113 self.0.entry(key) 114 } 115 116 /// Removes all associations from the map. 117 /// 118 /// *O*(*n*) time clear(&mut self)119 pub fn clear(&mut self) { 120 self.0.clear() 121 } 122 123 /// Returns a reference to the value corresponding to the key. 124 /// 125 /// expected *O*(1) time; worst-case *O*(*p*) time get(&self, key: &K::Strong) -> Option<V::Strong>126 pub fn get(&self, key: &K::Strong) -> Option<V::Strong> { 127 self.0.get(&(key.deref() as *const _)) 128 } 129 130 /// Returns true if the map contains the specified key. 131 /// 132 /// expected *O*(1) time; worst-case *O*(*p*) time contains_key(&self, key: &K::Strong) -> bool133 pub fn contains_key(&self, key: &K::Strong) -> bool { 134 self.0.contains_key(&(key.deref() as *const _)) 135 } 136 137 /// Unconditionally inserts the value, returning the old value if already present. Does not 138 /// replace the key. 139 /// 140 /// expected *O*(1) time; worst-case *O*(*p*) time insert(&mut self, key: K::Strong, value: V::Strong) -> Option<V::Strong>141 pub fn insert(&mut self, key: K::Strong, value: V::Strong) -> Option<V::Strong> { 142 self.0.insert(key, value) 143 } 144 145 /// Removes the entry with the given key, if it exists, and returns the value. 146 /// 147 /// expected *O*(1) time; worst-case *O*(*p*) time remove(&mut self, key: &K::Strong) -> Option<V::Strong>148 pub fn remove(&mut self, key: &K::Strong) -> Option<V::Strong> { 149 self.0.remove(&(key.deref() as *const _)) 150 } 151 152 /// Removes all mappings not satisfying the given predicate. 153 /// 154 /// Also removes any expired mappings. 155 /// 156 /// *O*(*n*) time retain<F>(&mut self, f: F) where F: FnMut(K::Strong, V::Strong) -> bool157 pub fn retain<F>(&mut self, f: F) 158 where F: FnMut(K::Strong, V::Strong) -> bool 159 { 160 self.0.retain(f) 161 } 162 163 /// Is this map a submap of the other, using the given value comparison. 164 /// 165 /// In particular, all the keys of self must be in other and the values must compare true with 166 /// value_equal. 167 /// 168 /// expected *O*(*n*) time; worst-case *O*(*nq*) time (where *n* is 169 /// `self.capacity()` and *q* is the length of the probe sequences 170 /// in `other`) submap_with<F, S1, V1>(&self, other: &PtrWeakWeakHashMap<K, V1, S1>, value_equal: F) -> bool where F: FnMut(V::Strong, V1::Strong) -> bool, V1: WeakElement, S1: BuildHasher171 pub fn submap_with<F, S1, V1>(&self, other: &PtrWeakWeakHashMap<K, V1, S1>, value_equal: F) -> bool 172 where F: FnMut(V::Strong, V1::Strong) -> bool, 173 V1: WeakElement, 174 S1: BuildHasher 175 { 176 self.0.is_submap_with(&other.0, value_equal) 177 } 178 179 /// Is self a submap of other? 180 /// 181 /// expected *O*(*n*) time; worst-case *O*(*nq*) time (where *n* is 182 /// `self.capacity()` and *q* is the length of the probe sequences 183 /// in `other`) is_submap<V1, S1>(&self, other: &PtrWeakWeakHashMap<K, V1, S1>) -> bool where V1: WeakElement, V::Strong: PartialEq<V1::Strong>, S1: BuildHasher184 pub fn is_submap<V1, S1>(&self, other: &PtrWeakWeakHashMap<K, V1, S1>) -> bool 185 where V1: WeakElement, 186 V::Strong: PartialEq<V1::Strong>, 187 S1: BuildHasher 188 { 189 self.0.is_submap(&other.0) 190 } 191 192 /// Are the keys of self a subset of the keys of other? 193 /// 194 /// expected *O*(*n*) time; worst-case *O*(*nq*) time (where *n* is 195 /// `self.capacity()` and *q* is the length of the probe sequences 196 /// in `other`) domain_is_subset<V1, S1>(&self, other: &PtrWeakWeakHashMap<K, V1, S1>) -> bool where V1: WeakElement, S1: BuildHasher197 pub fn domain_is_subset<V1, S1>(&self, other: &PtrWeakWeakHashMap<K, V1, S1>) -> bool 198 where V1: WeakElement, 199 S1: BuildHasher 200 { 201 self.0.domain_is_subset(&other.0) 202 } 203 } 204 205 impl<K: WeakElement, V: WeakElement, S> PtrWeakWeakHashMap<K, V, S> 206 where K::Strong: Deref 207 { 208 /// Gets an iterator over the keys and values. 209 /// 210 /// *O*(1) time iter(&self) -> Iter<ByPtr<K>, V>211 pub fn iter(&self) -> Iter<ByPtr<K>, V> { 212 self.0.iter() 213 } 214 215 /// Gets an iterator over the keys. 216 /// 217 /// *O*(1) time keys(&self) -> Keys<ByPtr<K>, V>218 pub fn keys(&self) -> Keys<ByPtr<K>, V> { 219 self.0.keys() 220 } 221 222 /// Gets an iterator over the values. 223 /// 224 /// *O*(1) time values(&self) -> Values<ByPtr<K>, V>225 pub fn values(&self) -> Values<ByPtr<K>, V> { 226 self.0.values() 227 } 228 229 /// Gets a draining iterator, which removes all the values but retains the storage. 230 /// 231 /// *O*(1) time (and *O*(*n*) time to dispose of the result) drain(&mut self) -> Drain<ByPtr<K>, V>232 pub fn drain(&mut self) -> Drain<ByPtr<K>, V> { 233 self.0.drain() 234 } 235 } 236 237 impl<K, V, V1, S, S1> PartialEq<PtrWeakWeakHashMap<K, V1, S1>> 238 for PtrWeakWeakHashMap<K, V, S> 239 where K: WeakElement, 240 K::Strong: Deref, 241 V: WeakElement, 242 V1: WeakElement, 243 V::Strong: PartialEq<V1::Strong>, 244 S: BuildHasher, 245 S1: BuildHasher 246 { eq(&self, other: &PtrWeakWeakHashMap<K, V1, S1>) -> bool247 fn eq(&self, other: &PtrWeakWeakHashMap<K, V1, S1>) -> bool { 248 self.0 == other.0 249 } 250 } 251 252 impl<K: WeakElement, V: WeakElement, S: BuildHasher> Eq for PtrWeakWeakHashMap<K, V, S> 253 where K::Strong: Deref, 254 V::Strong: Eq 255 { } 256 257 impl<K: WeakElement, V: WeakElement, S: BuildHasher + Default> Default for PtrWeakWeakHashMap<K, V, S> 258 where K::Strong: Deref 259 { default() -> Self260 fn default() -> Self { 261 PtrWeakWeakHashMap(base::WeakWeakHashMap::<ByPtr<K>, V, S>::default()) 262 } 263 } 264 265 impl<K, V, S> FromIterator<(K::Strong, V::Strong)> for PtrWeakWeakHashMap<K, V, S> 266 where K: WeakElement, 267 K::Strong: Deref, 268 V: WeakElement, 269 S: BuildHasher + Default 270 { from_iter<T: IntoIterator<Item=(K::Strong, V::Strong)>>(iter: T) -> Self271 fn from_iter<T: IntoIterator<Item=(K::Strong, V::Strong)>>(iter: T) -> Self { 272 PtrWeakWeakHashMap(base::WeakWeakHashMap::<ByPtr<K>, V, S>::from_iter(iter)) 273 } 274 } 275 276 impl<K, V, S> Extend<(K::Strong, V::Strong)> for PtrWeakWeakHashMap<K, V, S> 277 where K: WeakElement, 278 K::Strong: Deref, 279 V: WeakElement, 280 S: BuildHasher 281 { extend<T: IntoIterator<Item=(K::Strong, V::Strong)>>(&mut self, iter: T)282 fn extend<T: IntoIterator<Item=(K::Strong, V::Strong)>>(&mut self, iter: T) { 283 self.0.extend(iter) 284 } 285 } 286 287 impl<K, V, S> Debug for PtrWeakWeakHashMap<K, V, S> 288 where K: WeakElement, 289 K::Strong: Debug, 290 V: WeakElement, 291 V::Strong: Debug 292 { fmt(&self, f: &mut fmt::Formatter) -> fmt::Result293 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 294 self.0.fmt(f) 295 } 296 } 297 298 impl<K: WeakElement, V: WeakElement, S> IntoIterator for PtrWeakWeakHashMap<K, V, S> { 299 type Item = (K::Strong, V::Strong); 300 type IntoIter = IntoIter<ByPtr<K>, V>; 301 302 /// Creates an owning iterator from `self`. 303 /// 304 /// *O*(1) time (and *O*(*n*) time to dispose of the result) into_iter(self) -> Self::IntoIter305 fn into_iter(self) -> Self::IntoIter { 306 self.0.into_iter() 307 } 308 } 309 310 impl<'a, K: WeakElement, V: WeakElement, S> IntoIterator for &'a PtrWeakWeakHashMap<K, V, S> { 311 type Item = (K::Strong, V::Strong); 312 type IntoIter = Iter<'a, ByPtr<K>, V>; 313 314 /// Creates a borrowing iterator from `self`. 315 /// 316 /// *O*(1) time into_iter(self) -> Self::IntoIter317 fn into_iter(self) -> Self::IntoIter { 318 (&self.0).into_iter() 319 } 320 } 321 322 #[cfg(test)] 323 mod test { 324 use crate::compat::{ 325 eprintln, 326 rc::{Rc, Weak}, 327 Vec, 328 }; 329 use super::{Entry, PtrWeakWeakHashMap}; 330 331 // fn show_me(weakmap: &PtrWeakWeakHashMap<Weak<u32>, Weak<f32>>) { 332 // for (key, _) in weakmap { 333 // eprint!(" {:2}", *key); 334 // } 335 // eprintln!(); 336 // } 337 338 // From https://github.com/tov/weak-table-rs/issues/1#issuecomment-461858060 339 #[test] insert_and_check()340 fn insert_and_check() { 341 let mut rcs: Vec<(Rc<u32>, Rc<f32>)> = Vec::new(); 342 343 for i in 0 .. 200 { 344 rcs.push((Rc::new(i), Rc::new(i as f32 + 0.1))); 345 } 346 347 let mut weakmap: PtrWeakWeakHashMap<Weak<u32>, Weak<f32>> = PtrWeakWeakHashMap::new(); 348 349 for (key, value) in rcs.iter().cloned() { 350 weakmap.insert(key, value); 351 // show_me(&weakmap); 352 } 353 354 let mut count = 0; 355 356 for (key, value) in &rcs { 357 assert!(weakmap.contains_key(key)); 358 359 match weakmap.entry(Rc::clone(key)) { 360 Entry::Occupied(occ) => { 361 assert_eq!( occ.get(), value ); 362 count += 1; 363 } 364 Entry::Vacant(_) => { 365 eprintln!("PointerWeakWeakHashMap: missing: {}", *key); 366 } 367 } 368 } 369 370 assert_eq!( count, rcs.len() ); 371 } 372 } 373 374 375