1 //! A hash set where the elements are held by weak pointers and compared by value. 2 3 use crate::compat::*; 4 5 use super::traits::*; 6 use super::weak_key_hash_map as base; 7 8 pub use super::WeakHashSet; 9 10 impl <T: WeakKey> WeakHashSet<T, RandomState> { 11 /// Creates an empty `WeakHashSet`. 12 /// 13 /// *O*(1) time new() -> Self14 pub fn new() -> Self { 15 WeakHashSet(base::WeakKeyHashMap::new()) 16 } 17 18 /// Creates an empty `WeakHashSet` with the given capacity. 19 /// 20 /// *O*(*n*) time with_capacity(capacity: usize) -> Self21 pub fn with_capacity(capacity: usize) -> Self { 22 WeakHashSet(base::WeakKeyHashMap::with_capacity(capacity)) 23 } 24 } 25 26 impl <T: WeakKey, S: BuildHasher> WeakHashSet<T, S> { 27 /// Creates an empty `WeakHashSet` with the given capacity and hasher. 28 /// 29 /// *O*(*n*) time with_hasher(hash_builder: S) -> Self30 pub fn with_hasher(hash_builder: S) -> Self { 31 WeakHashSet(base::WeakKeyHashMap::with_hasher(hash_builder)) 32 } 33 34 /// Creates an empty `WeakHashSet` with the given capacity and hasher. 35 /// 36 /// *O*(*n*) time with_capacity_and_hasher(capacity: usize, hash_builder: S) -> Self37 pub fn with_capacity_and_hasher(capacity: usize, hash_builder: S) -> Self { 38 WeakHashSet(base::WeakKeyHashMap::with_capacity_and_hasher(capacity, hash_builder)) 39 } 40 41 /// Returns a reference to the map's `BuildHasher`. 42 /// 43 /// *O*(1) time hasher(&self) -> &S44 pub fn hasher(&self) -> &S { 45 self.0.hasher() 46 } 47 48 /// Returns the number of elements the map can hold without reallocating. 49 /// 50 /// *O*(1) time capacity(&self) -> usize51 pub fn capacity(&self) -> usize { 52 self.0.capacity() 53 } 54 55 /// Removes all mappings whose keys have expired. 56 /// 57 /// *O*(*n*) time remove_expired(&mut self)58 pub fn remove_expired(&mut self) { 59 self.0.remove_expired() 60 } 61 62 /// Reserves room for additional elements. 63 /// 64 /// *O*(*n*) time reserve(&mut self, additional_capacity: usize)65 pub fn reserve(&mut self, additional_capacity: usize) { 66 self.0.reserve(additional_capacity) 67 } 68 69 /// Shrinks the capacity to the minimum allowed to hold the current number of elements. 70 /// 71 /// *O*(*n*) time shrink_to_fit(&mut self)72 pub fn shrink_to_fit(&mut self) { 73 self.0.shrink_to_fit() 74 } 75 76 /// Returns an over-approximation of the number of elements. 77 /// 78 /// *O*(1) time len(&self) -> usize79 pub fn len(&self) -> usize { 80 self.0.len() 81 } 82 83 /// Is the set empty? 84 /// 85 /// Note that this may return false even if all keys in the set have 86 /// expired, if they haven't been collected yet. 87 /// 88 /// *O*(1) time is_empty(&self) -> bool89 pub fn is_empty(&self) -> bool { 90 self.0.is_empty() 91 } 92 93 /// The proportion of buckets that are used. 94 /// 95 /// This is an over-approximation because of expired elements. 96 /// 97 /// *O*(1) time load_factor(&self) -> f3298 pub fn load_factor(&self) -> f32 { 99 self.0.load_factor() 100 } 101 102 /// Removes all associations from the map. 103 /// 104 /// *O*(*n*) time clear(&mut self)105 pub fn clear(&mut self) { 106 self.0.clear() 107 } 108 109 // Non-ptr WeakHashSet should probably have `get` method. 110 111 /// Returns true if the map contains the specified key. 112 /// 113 /// expected *O*(1) time; worst-case *O*(*p*) time contains<Q>(&self, key: &Q) -> bool where Q: ?Sized + Eq + Hash, T::Key: Borrow<Q>114 pub fn contains<Q>(&self, key: &Q) -> bool 115 where Q: ?Sized + Eq + Hash, 116 T::Key: Borrow<Q> 117 { 118 self.0.contains_key(key) 119 } 120 121 /// Gets a strong reference to the given key, if found. 122 /// 123 /// # Examples 124 /// 125 /// ``` 126 /// use weak_table::WeakHashSet; 127 /// use std::rc::{Rc, Weak}; 128 /// use std::ops::Deref; 129 /// 130 /// let mut set: WeakHashSet<Weak<String>> = WeakHashSet::new(); 131 /// 132 /// let a = Rc::new("a".to_owned()); 133 /// set.insert(a.clone()); 134 /// 135 /// let also_a = set.get("a").unwrap(); 136 /// 137 /// assert!(Rc::ptr_eq( &a, &also_a )); 138 /// ``` 139 /// 140 /// expected *O*(1) time; worst-case *O*(*p*) time get<Q>(&self, key: &Q) -> Option<T::Strong> where Q: ?Sized + Eq + Hash, T::Key: Borrow<Q>141 pub fn get<Q>(&self, key: &Q) -> Option<T::Strong> 142 where Q: ?Sized + Eq + Hash, 143 T::Key: Borrow<Q> 144 { 145 self.0.get_key(key) 146 } 147 148 /// Unconditionally inserts the value, returning the old value if already present. Does not 149 /// replace the key. 150 /// 151 /// expected *O*(1) time; worst-case *O*(*p*) time insert(&mut self, key: T::Strong) -> bool152 pub fn insert(&mut self, key: T::Strong) -> bool { 153 self.0.insert(key, ()).is_some() 154 } 155 156 /// Removes the entry with the given key, if it exists, and returns the value. 157 /// 158 /// expected *O*(1) time; worst-case *O*(*p*) time remove<Q>(&mut self, key: &Q) -> bool where Q: ?Sized + Eq + Hash, T::Key: Borrow<Q>159 pub fn remove<Q>(&mut self, key: &Q) -> bool 160 where Q: ?Sized + Eq + Hash, 161 T::Key: Borrow<Q> 162 { 163 self.0.remove(key).is_some() 164 } 165 166 /// Removes all mappings not satisfying the given predicate. 167 /// 168 /// Also removes any expired mappings. 169 /// 170 /// *O*(*n*) time retain<F>(&mut self, mut f: F) where F: FnMut(T::Strong) -> bool171 pub fn retain<F>(&mut self, mut f: F) 172 where F: FnMut(T::Strong) -> bool 173 { 174 self.0.retain(|k, _| f(k)) 175 } 176 177 /// Is self a subset of other? 178 /// 179 /// expected *O*(*n*) time; worst-case *O*(*nq*) time (where *n* is 180 /// `self.capacity()` and *q* is the length of the probe sequences 181 /// in `other`) is_subset<S1>(&self, other: &WeakHashSet<T, S1>) -> bool where S1: BuildHasher182 pub fn is_subset<S1>(&self, other: &WeakHashSet<T, S1>) -> bool 183 where S1: BuildHasher 184 { 185 self.0.domain_is_subset(&other.0) 186 } 187 } 188 189 /// An iterator over the elements of a set. 190 pub struct Iter<'a, T: 'a>(base::Keys<'a, T, ()>); 191 192 impl<'a, T: WeakElement> Iterator for Iter<'a, T> { 193 type Item = T::Strong; 194 next(&mut self) -> Option<Self::Item>195 fn next(&mut self) -> Option<Self::Item> { 196 self.0.next() 197 } 198 size_hint(&self) -> (usize, Option<usize>)199 fn size_hint(&self) -> (usize, Option<usize>) { 200 self.0.size_hint() 201 } 202 } 203 204 /// An iterator over the elements of a set. 205 pub struct IntoIter<T>(base::IntoIter<T, ()>); 206 207 impl<T: WeakElement> Iterator for IntoIter<T> { 208 type Item = T::Strong; 209 next(&mut self) -> Option<Self::Item>210 fn next(&mut self) -> Option<Self::Item> { 211 self.0.next().map(|pair| pair.0) 212 } 213 size_hint(&self) -> (usize, Option<usize>)214 fn size_hint(&self) -> (usize, Option<usize>) { 215 self.0.size_hint() 216 } 217 } 218 219 /// A draining iterator over the elements of a set. 220 pub struct Drain<'a, T: 'a>(base::Drain<'a, T, ()>); 221 222 impl<'a, T: WeakElement> Iterator for Drain<'a, T> { 223 type Item = T::Strong; 224 next(&mut self) -> Option<Self::Item>225 fn next(&mut self) -> Option<Self::Item> { 226 self.0.next().map(|pair| pair.0) 227 } 228 size_hint(&self) -> (usize, Option<usize>)229 fn size_hint(&self) -> (usize, Option<usize>) { 230 self.0.size_hint() 231 } 232 } 233 234 impl<T: WeakKey, S> WeakHashSet<T, S> { 235 /// Gets an iterator over the keys and values. 236 /// 237 /// *O*(1) time iter(&self) -> Iter<T>238 pub fn iter(&self) -> Iter<T> { 239 Iter(self.0.keys()) 240 } 241 242 /// Gets a draining iterator, which removes all the values but retains the storage. 243 /// 244 /// *O*(1) time (and *O*(*n*) time to dispose of the result) drain(&mut self) -> Drain<T>245 pub fn drain(&mut self) -> Drain<T> { 246 Drain(self.0.drain()) 247 } 248 } 249 250 impl<T, S, S1> PartialEq<WeakHashSet<T, S1>> for WeakHashSet<T, S> 251 where T: WeakKey, 252 S: BuildHasher, 253 S1: BuildHasher 254 { eq(&self, other: &WeakHashSet<T, S1>) -> bool255 fn eq(&self, other: &WeakHashSet<T, S1>) -> bool { 256 self.0 == other.0 257 } 258 } 259 260 impl<T: WeakKey, S: BuildHasher> Eq for WeakHashSet<T, S> 261 where T::Key: Eq 262 { } 263 264 impl<T: WeakKey, S: BuildHasher + Default> Default for WeakHashSet<T, S> { default() -> Self265 fn default() -> Self { 266 WeakHashSet(base::WeakKeyHashMap::<T, (), S>::default()) 267 } 268 } 269 270 impl<T, S> FromIterator<T::Strong> for WeakHashSet<T, S> 271 where T: WeakKey, 272 S: BuildHasher + Default 273 { from_iter<I: IntoIterator<Item=T::Strong>>(iter: I) -> Self274 fn from_iter<I: IntoIterator<Item=T::Strong>>(iter: I) -> Self { 275 WeakHashSet(base::WeakKeyHashMap::<T, (), S>::from_iter( 276 iter.into_iter().map(|k| (k, ())))) 277 } 278 } 279 280 impl<T: WeakKey, S: BuildHasher> Extend<T::Strong> for WeakHashSet<T, S> { extend<I: IntoIterator<Item=T::Strong>>(&mut self, iter: I)281 fn extend<I: IntoIterator<Item=T::Strong>>(&mut self, iter: I) { 282 self.0.extend(iter.into_iter().map(|k| (k, ()))) 283 } 284 } 285 286 impl<T: WeakKey, S> Debug for WeakHashSet<T, S> 287 where T::Strong: Debug 288 { fmt(&self, f: &mut fmt::Formatter) -> fmt::Result289 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 290 self.0.fmt(f) 291 } 292 } 293 294 impl<T: WeakKey, S> IntoIterator for WeakHashSet<T, S> { 295 type Item = T::Strong; 296 type IntoIter = IntoIter<T>; 297 298 /// Creates an owning iterator from `self`. 299 /// 300 /// *O*(1) time (and *O*(*n*) time to dispose of the result) into_iter(self) -> Self::IntoIter301 fn into_iter(self) -> Self::IntoIter { 302 IntoIter(self.0.into_iter()) 303 } 304 } 305 306 impl<'a, T: WeakKey, S> IntoIterator for &'a WeakHashSet<T, S> { 307 type Item = T::Strong; 308 type IntoIter = Iter<'a, T>; 309 310 /// Creates a borrowing iterator from `self`. 311 /// 312 /// *O*(1) time into_iter(self) -> Self::IntoIter313 fn into_iter(self) -> Self::IntoIter { 314 Iter(self.0.keys()) 315 } 316 } 317