blob: bbff3b83e271c279342c32d0b8671b19269a7a95 [file] [log] [blame]
Joel Galenson2370d122020-10-12 16:02:26 -07001//! A hash set where the elements are held by weak pointers and compared by value.
2
David LeGare77e4bb92022-03-02 16:21:23 +00003use crate::compat::*;
Joel Galenson2370d122020-10-12 16:02:26 -07004
5use super::traits::*;
6use super::weak_key_hash_map as base;
7
8pub use super::WeakHashSet;
9
10impl <T: WeakKey> WeakHashSet<T, RandomState> {
11 /// Creates an empty `WeakHashSet`.
David LeGare77e4bb92022-03-02 16:21:23 +000012 ///
13 /// *O*(1) time
Joel Galenson2370d122020-10-12 16:02:26 -070014 pub fn new() -> Self {
15 WeakHashSet(base::WeakKeyHashMap::new())
16 }
17
18 /// Creates an empty `WeakHashSet` with the given capacity.
David LeGare77e4bb92022-03-02 16:21:23 +000019 ///
20 /// *O*(*n*) time
Joel Galenson2370d122020-10-12 16:02:26 -070021 pub fn with_capacity(capacity: usize) -> Self {
22 WeakHashSet(base::WeakKeyHashMap::with_capacity(capacity))
23 }
24}
25
26impl <T: WeakKey, S: BuildHasher> WeakHashSet<T, S> {
27 /// Creates an empty `WeakHashSet` with the given capacity and hasher.
David LeGare77e4bb92022-03-02 16:21:23 +000028 ///
29 /// *O*(*n*) time
Joel Galenson2370d122020-10-12 16:02:26 -070030 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.
David LeGare77e4bb92022-03-02 16:21:23 +000035 ///
36 /// *O*(*n*) time
Joel Galenson2370d122020-10-12 16:02:26 -070037 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`.
David LeGare77e4bb92022-03-02 16:21:23 +000042 ///
43 /// *O*(1) time
Joel Galenson2370d122020-10-12 16:02:26 -070044 pub fn hasher(&self) -> &S {
45 self.0.hasher()
46 }
47
48 /// Returns the number of elements the map can hold without reallocating.
David LeGare77e4bb92022-03-02 16:21:23 +000049 ///
50 /// *O*(1) time
Joel Galenson2370d122020-10-12 16:02:26 -070051 pub fn capacity(&self) -> usize {
52 self.0.capacity()
53 }
54
55 /// Removes all mappings whose keys have expired.
David LeGare77e4bb92022-03-02 16:21:23 +000056 ///
57 /// *O*(*n*) time
Joel Galenson2370d122020-10-12 16:02:26 -070058 pub fn remove_expired(&mut self) {
59 self.0.remove_expired()
60 }
61
62 /// Reserves room for additional elements.
David LeGare77e4bb92022-03-02 16:21:23 +000063 ///
64 /// *O*(*n*) time
Joel Galenson2370d122020-10-12 16:02:26 -070065 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.
David LeGare77e4bb92022-03-02 16:21:23 +000070 ///
71 /// *O*(*n*) time
Joel Galenson2370d122020-10-12 16:02:26 -070072 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.
David LeGare77e4bb92022-03-02 16:21:23 +000077 ///
78 /// *O*(1) time
Joel Galenson2370d122020-10-12 16:02:26 -070079 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.
David LeGare77e4bb92022-03-02 16:21:23 +000087 ///
88 /// *O*(1) time
Joel Galenson2370d122020-10-12 16:02:26 -070089 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.
David LeGare77e4bb92022-03-02 16:21:23 +000096 ///
97 /// *O*(1) time
Joel Galenson2370d122020-10-12 16:02:26 -070098 pub fn load_factor(&self) -> f32 {
99 self.0.load_factor()
100 }
101
102 /// Removes all associations from the map.
David LeGare77e4bb92022-03-02 16:21:23 +0000103 ///
104 /// *O*(*n*) time
Joel Galenson2370d122020-10-12 16:02:26 -0700105 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.
David LeGare77e4bb92022-03-02 16:21:23 +0000112 ///
113 /// expected *O*(1) time; worst-case *O*(*p*) time
Joel Galenson2370d122020-10-12 16:02:26 -0700114 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 /// ```
David LeGare77e4bb92022-03-02 16:21:23 +0000139 ///
140 /// expected *O*(1) time; worst-case *O*(*p*) time
Joel Galenson2370d122020-10-12 16:02:26 -0700141 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.
David LeGare77e4bb92022-03-02 16:21:23 +0000150 ///
151 /// expected *O*(1) time; worst-case *O*(*p*) time
Joel Galenson2370d122020-10-12 16:02:26 -0700152 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.
David LeGare77e4bb92022-03-02 16:21:23 +0000157 ///
158 /// expected *O*(1) time; worst-case *O*(*p*) time
Joel Galenson2370d122020-10-12 16:02:26 -0700159 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.
David LeGare77e4bb92022-03-02 16:21:23 +0000169 ///
170 /// *O*(*n*) time
Joel Galenson2370d122020-10-12 16:02:26 -0700171 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?
David LeGare77e4bb92022-03-02 16:21:23 +0000178 ///
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`)
Joel Galenson2370d122020-10-12 16:02:26 -0700182 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.
190pub struct Iter<'a, T: 'a>(base::Keys<'a, T, ()>);
191
192impl<'a, T: WeakElement> Iterator for Iter<'a, T> {
193 type Item = T::Strong;
194
195 fn next(&mut self) -> Option<Self::Item> {
196 self.0.next()
197 }
198
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.
205pub struct IntoIter<T>(base::IntoIter<T, ()>);
206
207impl<T: WeakElement> Iterator for IntoIter<T> {
208 type Item = T::Strong;
209
210 fn next(&mut self) -> Option<Self::Item> {
211 self.0.next().map(|pair| pair.0)
212 }
213
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.
220pub struct Drain<'a, T: 'a>(base::Drain<'a, T, ()>);
221
222impl<'a, T: WeakElement> Iterator for Drain<'a, T> {
223 type Item = T::Strong;
224
225 fn next(&mut self) -> Option<Self::Item> {
226 self.0.next().map(|pair| pair.0)
227 }
228
229 fn size_hint(&self) -> (usize, Option<usize>) {
230 self.0.size_hint()
231 }
232}
233
234impl<T: WeakKey, S> WeakHashSet<T, S> {
235 /// Gets an iterator over the keys and values.
David LeGare77e4bb92022-03-02 16:21:23 +0000236 ///
237 /// *O*(1) time
Joel Galenson2370d122020-10-12 16:02:26 -0700238 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.
David LeGare77e4bb92022-03-02 16:21:23 +0000243 ///
244 /// *O*(1) time (and *O*(*n*) time to dispose of the result)
Joel Galenson2370d122020-10-12 16:02:26 -0700245 pub fn drain(&mut self) -> Drain<T> {
246 Drain(self.0.drain())
247 }
248}
249
250impl<T, S, S1> PartialEq<WeakHashSet<T, S1>> for WeakHashSet<T, S>
251 where T: WeakKey,
252 S: BuildHasher,
253 S1: BuildHasher
254{
255 fn eq(&self, other: &WeakHashSet<T, S1>) -> bool {
256 self.0 == other.0
257 }
258}
259
260impl<T: WeakKey, S: BuildHasher> Eq for WeakHashSet<T, S>
261 where T::Key: Eq
262{ }
263
264impl<T: WeakKey, S: BuildHasher + Default> Default for WeakHashSet<T, S> {
265 fn default() -> Self {
266 WeakHashSet(base::WeakKeyHashMap::<T, (), S>::default())
267 }
268}
269
270impl<T, S> FromIterator<T::Strong> for WeakHashSet<T, S>
271 where T: WeakKey,
272 S: BuildHasher + Default
273{
274 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
280impl<T: WeakKey, S: BuildHasher> Extend<T::Strong> for WeakHashSet<T, S> {
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
286impl<T: WeakKey, S> Debug for WeakHashSet<T, S>
287 where T::Strong: Debug
288{
289 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
290 self.0.fmt(f)
291 }
292}
293
294impl<T: WeakKey, S> IntoIterator for WeakHashSet<T, S> {
295 type Item = T::Strong;
296 type IntoIter = IntoIter<T>;
297
David LeGare77e4bb92022-03-02 16:21:23 +0000298 /// Creates an owning iterator from `self`.
299 ///
300 /// *O*(1) time (and *O*(*n*) time to dispose of the result)
Joel Galenson2370d122020-10-12 16:02:26 -0700301 fn into_iter(self) -> Self::IntoIter {
302 IntoIter(self.0.into_iter())
303 }
304}
305
306impl<'a, T: WeakKey, S> IntoIterator for &'a WeakHashSet<T, S> {
307 type Item = T::Strong;
308 type IntoIter = Iter<'a, T>;
309
David LeGare77e4bb92022-03-02 16:21:23 +0000310 /// Creates a borrowing iterator from `self`.
311 ///
312 /// *O*(1) time
Joel Galenson2370d122020-10-12 16:02:26 -0700313 fn into_iter(self) -> Self::IntoIter {
314 Iter(self.0.keys())
315 }
316}