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