Skip to main content

scc/
hash_set.rs

1//! [`HashSet`] is an asynchronous/concurrent hash set.
2
3#![deny(unsafe_code)]
4
5use std::collections::hash_map::RandomState;
6use std::fmt::{self, Debug};
7use std::hash::{BuildHasher, Hash};
8use std::mem::swap;
9use std::ops::{Deref, RangeInclusive};
10
11use super::hash_map;
12use super::hash_table::{HashTable, num_entries_from_hint};
13use super::{Equivalent, HashMap};
14
15/// Scalable asynchronous/concurrent hash set.
16///
17/// [`HashSet`] is an asynchronous/concurrent hash set based on [`HashMap`].
18pub struct HashSet<K, H = RandomState>
19where
20    H: BuildHasher,
21{
22    map: HashMap<K, (), H>,
23}
24
25/// [`OccupiedEntry`] is a view into an occupied entry in a [`HashSet`].
26pub struct OccupiedEntry<'h, K, H = RandomState>
27where
28    H: BuildHasher,
29{
30    occupied: hash_map::OccupiedEntry<'h, K, (), H>,
31}
32
33/// [`ConsumableEntry`] is a view into an occupied entry in a [`HashSet`] when iterating over
34/// entries in it.
35pub struct ConsumableEntry<'w, K> {
36    consumable: hash_map::ConsumableEntry<'w, K, ()>,
37}
38
39/// [`Reserve`] keeps the capacity of the associated [`HashSet`] higher than a certain level.
40///
41/// The [`HashSet`] does not shrink the capacity below the reserved capacity.
42pub type Reserve<'h, K, H = RandomState> = super::hash_map::Reserve<'h, K, (), H>;
43
44impl<K, H> HashSet<K, H>
45where
46    H: BuildHasher,
47{
48    /// Creates an empty [`HashSet`] with the given [`BuildHasher`].
49    ///
50    /// # Examples
51    ///
52    /// ```
53    /// use scc::HashSet;
54    /// use std::collections::hash_map::RandomState;
55    ///
56    /// let hashset: HashSet<u64, RandomState> = HashSet::with_hasher(RandomState::new());
57    /// ```
58    #[cfg(not(feature = "loom"))]
59    #[inline]
60    pub const fn with_hasher(build_hasher: H) -> Self {
61        Self {
62            map: HashMap::with_hasher(build_hasher),
63        }
64    }
65
66    /// Creates an empty [`HashSet`] with the given [`BuildHasher`].
67    #[cfg(feature = "loom")]
68    #[inline]
69    pub fn with_hasher(build_hasher: H) -> Self {
70        Self {
71            map: HashMap::with_hasher(build_hasher),
72        }
73    }
74
75    /// Creates an empty [`HashSet`] with the specified capacity and [`BuildHasher`].
76    ///
77    /// The actual capacity is equal to or greater than `capacity` unless it is greater than
78    /// `1 << (usize::BITS - 1)`.
79    ///
80    /// # Examples
81    ///
82    /// ```
83    /// use scc::HashSet;
84    /// use std::collections::hash_map::RandomState;
85    ///
86    /// let hashset: HashSet<u64, RandomState> =
87    ///     HashSet::with_capacity_and_hasher(800, RandomState::new());
88    ///
89    /// let result = hashset.capacity();
90    /// assert_eq!(result, 1024);
91    /// ```
92    #[inline]
93    pub fn with_capacity_and_hasher(capacity: usize, build_hasher: H) -> Self {
94        Self {
95            map: HashMap::with_capacity_and_hasher(capacity, build_hasher),
96        }
97    }
98}
99
100impl<K, H> HashSet<K, H>
101where
102    K: Eq + Hash,
103    H: BuildHasher,
104{
105    /// Temporarily increases the minimum capacity of the [`HashSet`].
106    ///
107    /// A [`Reserve`] is returned if the [`HashSet`] could increase the minimum capacity while the
108    /// increased capacity is not exclusively owned by the returned [`Reserve`], allowing others to
109    /// benefit from it. The memory for the additional space may not be immediately allocated if
110    /// the [`HashSet`] is empty or currently being resized, however once the memory is reserved
111    /// eventually, the capacity will not shrink below the additional capacity until the returned
112    /// [`Reserve`] is dropped.
113    ///
114    /// # Errors
115    ///
116    /// Returns `None` if a too large number is given.
117    ///
118    /// # Examples
119    ///
120    /// ```
121    /// use scc::HashSet;
122    ///
123    /// let hashset: HashSet<usize> = HashSet::with_capacity(800);
124    /// assert_eq!(hashset.capacity(), 1024);
125    ///
126    /// let reserved = hashset.reserve(10000);
127    /// assert!(reserved.is_some());
128    /// assert_eq!(hashset.capacity(), 16384);
129    ///
130    /// assert!(hashset.reserve(usize::MAX).is_none());
131    /// assert_eq!(hashset.capacity(), 16384);
132    ///
133    /// for i in 0..16 {
134    ///     assert!(hashset.insert_sync(i).is_ok());
135    /// }
136    /// drop(reserved);
137    ///
138    /// assert_eq!(hashset.capacity(), 1024);
139    /// ```
140    #[inline]
141    pub fn reserve(&self, capacity: usize) -> Option<Reserve<'_, K, H>> {
142        self.map.reserve(capacity)
143    }
144
145    /// Begins iterating over entries by getting the first occupied entry.
146    ///
147    /// The returned [`OccupiedEntry`] in combination with [`OccupiedEntry::next_async`] can act as
148    /// a mutable iterator over entries.
149    ///
150    /// # Examples
151    ///
152    /// ```
153    /// use scc::HashSet;
154    ///
155    /// let hashset: HashSet<u32> = HashSet::default();
156    ///
157    /// let future_entry = hashset.begin_async();
158    /// ```
159    #[inline]
160    pub async fn begin_async(&self) -> Option<OccupiedEntry<'_, K, H>> {
161        self.any_async(|_| true).await
162    }
163
164    /// Begins iterating over entries by getting the first occupied entry.
165    ///
166    /// The returned [`OccupiedEntry`] in combination with [`OccupiedEntry::next_sync`] can act as a
167    /// mutable iterator over entries.
168    ///
169    /// # Examples
170    ///
171    /// ```
172    /// use scc::HashSet;
173    ///
174    /// let hashset: HashSet<u64> = HashSet::default();
175    ///
176    /// assert!(hashset.insert_sync(1).is_ok());
177    ///
178    /// let mut first_entry = hashset.begin_sync().unwrap();
179    /// assert_eq!(*first_entry.get(), 1);
180    ///
181    /// assert!(first_entry.next_sync().is_none());
182    /// assert!(hashset.read_sync(&1, |_| true).unwrap());
183    /// ```
184    #[inline]
185    pub fn begin_sync(&self) -> Option<OccupiedEntry<'_, K, H>> {
186        self.any_sync(|_| true)
187    }
188
189    /// Finds any entry satisfying the supplied predicate for in-place manipulation.
190    ///
191    /// # Examples
192    ///
193    /// ```
194    /// use scc::HashSet;
195    ///
196    /// let hashset: HashSet<u32> = HashSet::default();
197    ///
198    /// let future_entry = hashset.any_async(|k| *k == 2);
199    /// ```
200    #[inline]
201    pub async fn any_async<P: FnMut(&K) -> bool>(
202        &self,
203        mut pred: P,
204    ) -> Option<OccupiedEntry<'_, K, H>> {
205        self.map
206            .any_async(|k, ()| pred(k))
207            .await
208            .map(|occupied| OccupiedEntry { occupied })
209    }
210
211    /// Finds any entry satisfying the supplied predicate for in-place manipulation.
212    ///
213    /// # Examples
214    ///
215    /// ```
216    /// use scc::HashSet;
217    ///
218    /// let hashset: HashSet<u32> = HashSet::default();
219    ///
220    /// assert!(hashset.insert_sync(1).is_ok());
221    /// assert!(hashset.insert_sync(2).is_ok());
222    ///
223    /// let mut entry = hashset.any_sync(|k| *k == 2).unwrap();
224    /// assert_eq!(*entry.get(), 2);
225    /// ```
226    #[inline]
227    pub fn any_sync<P: FnMut(&K) -> bool>(&self, mut pred: P) -> Option<OccupiedEntry<'_, K, H>> {
228        self.map
229            .any_sync(|k, ()| pred(k))
230            .map(|occupied| OccupiedEntry { occupied })
231    }
232
233    /// Inserts a key into the [`HashSet`].
234    ///
235    /// # Errors
236    ///
237    /// Returns an error along with the supplied key if the key exists.
238    ///
239    /// # Examples
240    ///
241    /// ```
242    /// use scc::HashSet;
243    ///
244    /// let hashset: HashSet<u64> = HashSet::default();
245    /// let future_insert = hashset.insert_async(11);
246    /// ```
247    #[inline]
248    pub async fn insert_async(&self, key: K) -> Result<(), K> {
249        self.map.insert_async(key, ()).await.map_err(|(k, ())| k)
250    }
251
252    /// Inserts a key into the [`HashSet`].
253    ///
254    /// # Errors
255    ///
256    /// Returns an error along with the supplied key if the key exists.
257    ///
258    /// # Examples
259    ///
260    /// ```
261    /// use scc::HashSet;
262    ///
263    /// let hashset: HashSet<u64> = HashSet::default();
264    ///
265    /// assert!(hashset.insert_sync(1).is_ok());
266    /// assert_eq!(hashset.insert_sync(1).unwrap_err(), 1);
267    /// ```
268    #[inline]
269    pub fn insert_sync(&self, key: K) -> Result<(), K> {
270        if let Err((k, ())) = self.map.insert_sync(key, ()) {
271            return Err(k);
272        }
273        Ok(())
274    }
275
276    /// Adds a key to the set, replacing the existing key, if any, that is equal to the given one.
277    ///
278    /// Returns the replaced key, if any.
279    ///
280    /// # Examples
281    ///
282    /// ```
283    /// use std::cmp::{Eq, PartialEq};
284    /// use std::hash::{Hash, Hasher};
285    ///
286    /// use scc::HashSet;
287    ///
288    /// #[derive(Debug)]
289    /// struct MaybeEqual(u64, u64);
290    ///
291    /// impl Eq for MaybeEqual {}
292    ///
293    /// impl Hash for MaybeEqual {
294    ///     fn hash<H: Hasher>(&self, state: &mut H) {
295    ///         // Do not read `self.1`.
296    ///         self.0.hash(state);
297    ///     }
298    /// }
299    ///
300    /// impl PartialEq for MaybeEqual {
301    ///     fn eq(&self, other: &Self) -> bool {
302    ///         // Do not compare `self.1`.
303    ///         self.0 == other.0
304    ///     }
305    /// }
306    ///
307    /// let hashset: HashSet<MaybeEqual> = HashSet::default();
308    ///
309    /// assert!(hashset.replace_sync(MaybeEqual(11, 7)).is_none());
310    /// assert_eq!(hashset.replace_sync(MaybeEqual(11, 11)), Some(MaybeEqual(11, 7)));
311    /// ```
312    #[inline]
313    pub async fn replace_async(&self, mut key: K) -> Option<K> {
314        let hash = self.map.hash(&key);
315        let mut locked_bucket = self.map.writer_async(hash).await;
316        let mut entry_ptr = locked_bucket.search(&key, hash);
317        if entry_ptr.is_valid() {
318            let k = locked_bucket.entry_mut(&mut entry_ptr).0;
319            swap(k, &mut key);
320            Some(key)
321        } else {
322            locked_bucket.insert(hash, (key, ()));
323            None
324        }
325    }
326
327    /// Adds a key to the set, replacing the existing key, if any, that is equal to the given one.
328    ///
329    /// Returns the replaced key, if any.
330    ///
331    /// # Examples
332    ///
333    /// ```
334    /// use std::cmp::{Eq, PartialEq};
335    /// use std::hash::{Hash, Hasher};
336    ///
337    /// use scc::HashSet;
338    ///
339    /// #[derive(Debug)]
340    /// struct MaybeEqual(u64, u64);
341    ///
342    /// impl Eq for MaybeEqual {}
343    ///
344    /// impl Hash for MaybeEqual {
345    ///     fn hash<H: Hasher>(&self, state: &mut H) {
346    ///         // Do not read `self.1`.
347    ///         self.0.hash(state);
348    ///     }
349    /// }
350    ///
351    /// impl PartialEq for MaybeEqual {
352    ///     fn eq(&self, other: &Self) -> bool {
353    ///         // Do not compare `self.1`.
354    ///         self.0 == other.0
355    ///     }
356    /// }
357    ///
358    /// let hashset: HashSet<MaybeEqual> = HashSet::default();
359    ///
360    /// async {
361    ///     assert!(hashset.replace_async(MaybeEqual(11, 7)).await.is_none());
362    ///     assert_eq!(hashset.replace_async(MaybeEqual(11, 11)).await, Some(MaybeEqual(11, 7)));
363    /// };
364    /// ```
365    #[inline]
366    pub fn replace_sync(&self, mut key: K) -> Option<K> {
367        let hash = self.map.hash(&key);
368        let mut locked_bucket = self.map.writer_sync(hash);
369        let mut entry_ptr = locked_bucket.search(&key, hash);
370        if entry_ptr.is_valid() {
371            let k = locked_bucket.entry_mut(&mut entry_ptr).0;
372            swap(k, &mut key);
373            Some(key)
374        } else {
375            locked_bucket.insert(hash, (key, ()));
376            None
377        }
378    }
379
380    /// Removes a key if the key exists.
381    ///
382    /// Returns `None` if the key does not exist.
383    ///
384    /// # Examples
385    ///
386    /// ```
387    /// use scc::HashSet;
388    ///
389    /// let hashset: HashSet<u64> = HashSet::default();
390    /// let future_insert = hashset.insert_async(11);
391    /// let future_remove = hashset.remove_async(&11);
392    /// ```
393    #[inline]
394    pub async fn remove_async<Q>(&self, key: &Q) -> Option<K>
395    where
396        Q: Equivalent<K> + Hash + ?Sized,
397    {
398        self.map
399            .remove_if_async(key, |()| true)
400            .await
401            .map(|(k, ())| k)
402    }
403
404    /// Removes a key if the key exists.
405    ///
406    /// Returns `None` if the key does not exist.
407    ///
408    /// # Examples
409    ///
410    /// ```
411    /// use scc::HashSet;
412    ///
413    /// let hashset: HashSet<u64> = HashSet::default();
414    ///
415    /// assert!(hashset.remove_sync(&1).is_none());
416    /// assert!(hashset.insert_sync(1).is_ok());
417    /// assert_eq!(hashset.remove_sync(&1).unwrap(), 1);
418    /// ```
419    #[inline]
420    pub fn remove_sync<Q>(&self, key: &Q) -> Option<K>
421    where
422        Q: Equivalent<K> + Hash + ?Sized,
423    {
424        self.map.remove_sync(key).map(|(k, ())| k)
425    }
426
427    /// Removes a key if the key exists and the given condition is met.
428    ///
429    /// Returns `None` if the key does not exist or the condition was not met.
430    ///
431    /// # Examples
432    ///
433    /// ```
434    /// use scc::HashSet;
435    ///
436    /// let hashset: HashSet<u64> = HashSet::default();
437    /// let future_insert = hashset.insert_async(11);
438    /// let future_remove = hashset.remove_if_async(&11, || true);
439    /// ```
440    #[inline]
441    pub async fn remove_if_async<Q, F: FnOnce() -> bool>(&self, key: &Q, condition: F) -> Option<K>
442    where
443        Q: Equivalent<K> + Hash + ?Sized,
444    {
445        self.map
446            .remove_if_async(key, |()| condition())
447            .await
448            .map(|(k, ())| k)
449    }
450
451    /// Removes a key if the key exists and the given condition is met.
452    ///
453    /// Returns `None` if the key does not exist or the condition was not met.
454    ///
455    /// # Examples
456    ///
457    /// ```
458    /// use scc::HashSet;
459    ///
460    /// let hashset: HashSet<u64> = HashSet::default();
461    ///
462    /// assert!(hashset.insert_sync(1).is_ok());
463    /// assert!(hashset.remove_if_sync(&1, || false).is_none());
464    /// assert_eq!(hashset.remove_if_sync(&1, || true).unwrap(), 1);
465    /// ```
466    #[inline]
467    pub fn remove_if_sync<Q, F: FnOnce() -> bool>(&self, key: &Q, condition: F) -> Option<K>
468    where
469        Q: Equivalent<K> + Hash + ?Sized,
470    {
471        self.map
472            .remove_if_sync(key, |()| condition())
473            .map(|(k, ())| k)
474    }
475
476    /// Reads a key.
477    ///
478    /// Returns `None` if the key does not exist.
479    ///
480    /// # Examples
481    ///
482    /// ```
483    /// use scc::HashSet;
484    ///
485    /// let hashset: HashSet<u64> = HashSet::default();
486    /// let future_insert = hashset.insert_async(11);
487    /// let future_read = hashset.read_async(&11, |k| *k);
488    /// ```
489    #[inline]
490    pub async fn read_async<Q, R, F: FnOnce(&K) -> R>(&self, key: &Q, reader: F) -> Option<R>
491    where
492        Q: Equivalent<K> + Hash + ?Sized,
493    {
494        self.map.read_async(key, |k, ()| reader(k)).await
495    }
496
497    /// Reads a key.
498    ///
499    /// Returns `None` if the key does not exist.
500    ///
501    /// # Examples
502    ///
503    /// ```
504    /// use scc::HashSet;
505    ///
506    /// let hashset: HashSet<u64> = HashSet::default();
507    ///
508    /// assert!(hashset.read_sync(&1, |_| true).is_none());
509    /// assert!(hashset.insert_sync(1).is_ok());
510    /// assert!(hashset.read_sync(&1, |_| true).unwrap());
511    /// ```
512    #[inline]
513    pub fn read_sync<Q, R, F: FnOnce(&K) -> R>(&self, key: &Q, reader: F) -> Option<R>
514    where
515        Q: Equivalent<K> + Hash + ?Sized,
516    {
517        self.map.read_sync(key, |k, ()| reader(k))
518    }
519
520    /// Returns `true` if the [`HashSet`] contains the specified key.
521    ///
522    /// # Examples
523    ///
524    /// ```
525    /// use scc::HashSet;
526    ///
527    /// let hashset: HashSet<u64> = HashSet::default();
528    ///
529    /// let future_contains = hashset.contains_async(&1);
530    /// ```
531    #[inline]
532    pub async fn contains_async<Q>(&self, key: &Q) -> bool
533    where
534        Q: Equivalent<K> + Hash + ?Sized,
535    {
536        self.map.contains_async(key).await
537    }
538
539    /// Returns `true` if the [`HashSet`] contains the specified key.
540    ///
541    /// # Examples
542    ///
543    /// ```
544    /// use scc::HashSet;
545    ///
546    /// let hashset: HashSet<u64> = HashSet::default();
547    ///
548    /// assert!(!hashset.contains_sync(&1));
549    /// assert!(hashset.insert_sync(1).is_ok());
550    /// assert!(hashset.contains_sync(&1));
551    /// ```
552    #[inline]
553    pub fn contains_sync<Q>(&self, key: &Q) -> bool
554    where
555        Q: Equivalent<K> + Hash + ?Sized,
556    {
557        self.read_sync(key, |_| ()).is_some()
558    }
559
560    /// Iterates over entries asynchronously for reading.
561    ///
562    /// Stops iterating when the closure returns `false`, and this method also returns `false`.
563    ///
564    /// # Examples
565    ///
566    /// ```
567    /// use scc::HashSet;
568    ///
569    /// let hashset: HashSet<u64> = HashSet::default();
570    ///
571    /// assert!(hashset.insert_sync(1).is_ok());
572    ///
573    /// async {
574    ///     let result = hashset.iter_async(|k| {
575    ///         true
576    ///     }).await;
577    ///     assert!(result);
578    /// };
579    /// ```
580    #[inline]
581    pub async fn iter_async<F: FnMut(&K) -> bool>(&self, mut f: F) -> bool {
582        self.map.iter_async(|k, ()| f(k)).await
583    }
584
585    /// Iterates over entries synchronously for reading.
586    ///
587    /// Stops iterating when the closure returns `false`, and this method also returns `false`.
588    ///
589    /// # Examples
590    ///
591    /// ```
592    /// use scc::HashSet;
593    ///
594    /// let hashset: HashSet<u64> = HashSet::default();
595    ///
596    /// assert!(hashset.insert_sync(1).is_ok());
597    /// assert!(hashset.insert_sync(2).is_ok());
598    ///
599    /// let mut acc = 0;
600    /// let result = hashset.iter_sync(|k| {
601    ///     acc += *k;
602    ///     true
603    /// });
604    ///
605    /// assert!(result);
606    /// assert_eq!(acc, 3);
607    /// ```
608    #[inline]
609    pub fn iter_sync<F: FnMut(&K) -> bool>(&self, mut f: F) -> bool {
610        self.map.iter_sync(|k, ()| f(k))
611    }
612
613    /// Iterates over entries asynchronously for modification.
614    ///
615    /// This method stops iterating when the closure returns `false`, and also returns `false` in
616    /// that case.
617    ///
618    /// # Examples
619    ///
620    /// ```
621    /// use scc::HashSet;
622    ///
623    /// let hashset: HashSet<u64> = HashSet::default();
624    ///
625    /// assert!(hashset.insert_sync(1).is_ok());
626    /// assert!(hashset.insert_sync(2).is_ok());
627    ///
628    /// async {
629    ///     let result = hashset.iter_mut_async(|e| {
630    ///         if *e == 1 {
631    ///             e.consume();
632    ///             return false;
633    ///         }
634    ///         true
635    ///     }).await;
636    ///
637    ///     assert!(!result);
638    ///     assert_eq!(hashset.len(), 1);
639    /// };
640    /// ```
641    #[inline]
642    pub async fn iter_mut_async<F: FnMut(ConsumableEntry<'_, K>) -> bool>(&self, mut f: F) -> bool {
643        self.map
644            .iter_mut_async(|consumable| f(ConsumableEntry { consumable }))
645            .await
646    }
647
648    /// Iterates over entries synchronously for modification.
649    ///
650    /// This method stops iterating when the closure returns `false`, and also returns `false` in
651    /// that case.
652    ///
653    /// # Examples
654    ///
655    /// ```
656    /// use scc::HashSet;
657    ///
658    /// let hashset: HashSet<u64> = HashSet::default();
659    ///
660    /// assert!(hashset.insert_sync(1).is_ok());
661    /// assert!(hashset.insert_sync(2).is_ok());
662    /// assert!(hashset.insert_sync(3).is_ok());
663    ///
664    /// let result = hashset.iter_mut_sync(|e| {
665    ///     if *e == 1 {
666    ///         e.consume();
667    ///         return false;
668    ///     }
669    ///     true
670    /// });
671    ///
672    /// assert!(!result);
673    /// assert!(!hashset.contains_sync(&1));
674    /// assert_eq!(hashset.len(), 2);
675    /// ```
676    #[inline]
677    pub fn iter_mut_sync<F: FnMut(ConsumableEntry<'_, K>) -> bool>(&self, mut f: F) -> bool {
678        self.map
679            .iter_mut_sync(|consumable| f(ConsumableEntry { consumable }))
680    }
681
682    /// Retains keys that satisfy the given predicate.
683    ///
684    /// # Examples
685    ///
686    /// ```
687    /// use scc::HashSet;
688    ///
689    /// let hashset: HashSet<u64> = HashSet::default();
690    ///
691    /// let future_insert = hashset.insert_async(1);
692    /// let future_retain = hashset.retain_async(|k| *k == 1);
693    /// ```
694    #[inline]
695    pub async fn retain_async<F: FnMut(&K) -> bool>(&self, mut filter: F) {
696        self.map.retain_async(|k, ()| filter(k)).await;
697    }
698
699    /// Retains keys that satisfy the given predicate.
700    ///
701    /// # Examples
702    ///
703    /// ```
704    /// use scc::HashSet;
705    ///
706    /// let hashset: HashSet<u64> = HashSet::default();
707    ///
708    /// assert!(hashset.insert_sync(1).is_ok());
709    /// assert!(hashset.insert_sync(2).is_ok());
710    /// assert!(hashset.insert_sync(3).is_ok());
711    ///
712    /// hashset.retain_sync(|k| *k == 1);
713    ///
714    /// assert!(hashset.contains_sync(&1));
715    /// assert!(!hashset.contains_sync(&2));
716    /// assert!(!hashset.contains_sync(&3));
717    /// ```
718    #[inline]
719    pub fn retain_sync<F: FnMut(&K) -> bool>(&self, mut pred: F) {
720        self.iter_mut_sync(|e| {
721            if !pred(&*e) {
722                drop(e.consume());
723            }
724            true
725        });
726    }
727
728    /// Clears the [`HashSet`] by removing all keys.
729    ///
730    /// # Examples
731    ///
732    /// ```
733    /// use scc::HashSet;
734    ///
735    /// let hashset: HashSet<u64> = HashSet::default();
736    ///
737    /// let future_insert = hashset.insert_async(1);
738    /// let future_clear = hashset.clear_async();
739    /// ```
740    #[inline]
741    pub async fn clear_async(&self) {
742        self.map.clear_async().await;
743    }
744
745    /// Clears the [`HashSet`] by removing all keys.
746    ///
747    /// # Examples
748    ///
749    /// ```
750    /// use scc::HashSet;
751    ///
752    /// let hashset: HashSet<u64> = HashSet::default();
753    ///
754    /// assert!(hashset.insert_sync(1).is_ok());
755    /// hashset.clear_sync();
756    ///
757    /// assert!(!hashset.contains_sync(&1));
758    /// ```
759    #[inline]
760    pub fn clear_sync(&self) {
761        self.map.clear_sync();
762    }
763
764    /// Returns the number of entries in the [`HashSet`].
765    ///
766    /// It reads the entire metadata area of the bucket array to calculate the number of valid
767    /// entries, making its time complexity `O(N)`. Furthermore, it may overcount entries if an old
768    /// bucket array has yet to be dropped.
769    ///
770    /// # Examples
771    ///
772    /// ```
773    /// use scc::HashSet;
774    ///
775    /// let hashset: HashSet<u64> = HashSet::default();
776    ///
777    /// assert!(hashset.insert_sync(1).is_ok());
778    /// assert_eq!(hashset.len(), 1);
779    /// ```
780    #[inline]
781    pub fn len(&self) -> usize {
782        self.map.len()
783    }
784
785    /// Returns `true` if the [`HashSet`] is empty.
786    ///
787    /// # Examples
788    ///
789    /// ```
790    /// use scc::HashSet;
791    ///
792    /// let hashset: HashSet<u64> = HashSet::default();
793    ///
794    /// assert!(hashset.is_empty());
795    /// assert!(hashset.insert_sync(1).is_ok());
796    /// assert!(!hashset.is_empty());
797    /// ```
798    #[inline]
799    pub fn is_empty(&self) -> bool {
800        self.map.is_empty()
801    }
802
803    /// Returns the capacity of the [`HashSet`].
804    ///
805    /// # Examples
806    ///
807    /// ```
808    /// use scc::HashSet;
809    ///
810    /// let hashset_default: HashSet<u64> = HashSet::default();
811    /// assert_eq!(hashset_default.capacity(), 0);
812    ///
813    /// assert!(hashset_default.insert_sync(1).is_ok());
814    /// assert_eq!(hashset_default.capacity(), 64);
815    ///
816    /// let hashset: HashSet<u64> = HashSet::with_capacity(800);
817    /// assert_eq!(hashset.capacity(), 1024);
818    /// ```
819    #[inline]
820    pub fn capacity(&self) -> usize {
821        self.map.capacity()
822    }
823
824    /// Returns the current capacity range of the [`HashSet`].
825    ///
826    /// # Examples
827    ///
828    /// ```
829    /// use scc::HashSet;
830    ///
831    /// let hashset: HashSet<u64> = HashSet::default();
832    ///
833    /// assert_eq!(hashset.capacity_range(), 0..=(1_usize << (usize::BITS - 2)));
834    ///
835    /// let reserved = hashset.reserve(1000);
836    /// assert_eq!(hashset.capacity_range(), 1000..=(1_usize << (usize::BITS - 2)));
837    /// ```
838    #[inline]
839    pub fn capacity_range(&self) -> RangeInclusive<usize> {
840        self.map.capacity_range()
841    }
842
843    /// Returns the index of the bucket that may contain the key.
844    ///
845    /// The method returns the index of the bucket associated with the key. The number of buckets
846    /// can be calculated by dividing the capacity by `32`.
847    ///
848    /// # Examples
849    ///
850    /// ```
851    /// use scc::HashSet;
852    ///
853    /// let hashset: HashSet<u64> = HashSet::with_capacity(1024);
854    ///
855    /// let bucket_index = hashset.bucket_index(&11);
856    /// assert!(bucket_index < hashset.capacity() / 32);
857    /// ```
858    #[inline]
859    pub fn bucket_index<Q>(&self, key: &Q) -> usize
860    where
861        Q: Equivalent<K> + Hash + ?Sized,
862    {
863        self.map.bucket_index(key)
864    }
865}
866
867impl<K, H> Clone for HashSet<K, H>
868where
869    K: Clone + Eq + Hash,
870    H: BuildHasher + Clone,
871{
872    #[inline]
873    fn clone(&self) -> Self {
874        Self {
875            map: self.map.clone(),
876        }
877    }
878}
879
880impl<K, H> Debug for HashSet<K, H>
881where
882    K: Debug + Eq + Hash,
883    H: BuildHasher,
884{
885    #[inline]
886    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
887        let mut d = f.debug_set();
888        self.iter_sync(|k| {
889            d.entry(k);
890            true
891        });
892        d.finish()
893    }
894}
895
896impl<K: Eq + Hash> HashSet<K, RandomState> {
897    /// Creates an empty default [`HashSet`].
898    ///
899    /// # Examples
900    ///
901    /// ```
902    /// use scc::HashSet;
903    ///
904    /// let hashset: HashSet<u64> = HashSet::new();
905    ///
906    /// let result = hashset.capacity();
907    /// assert_eq!(result, 0);
908    /// ```
909    #[inline]
910    #[must_use]
911    pub fn new() -> Self {
912        Self::default()
913    }
914
915    /// Creates an empty [`HashSet`] with the specified capacity.
916    ///
917    /// The actual capacity is equal to or greater than `capacity` unless it is greater than
918    /// `1 << (usize::BITS - 1)`.
919    ///
920    /// # Examples
921    ///
922    /// ```
923    /// use scc::HashSet;
924    ///
925    /// let hashset: HashSet<u64> = HashSet::with_capacity(800);
926    ///
927    /// let result = hashset.capacity();
928    /// assert_eq!(result, 1024);
929    /// ```
930    #[inline]
931    #[must_use]
932    pub fn with_capacity(capacity: usize) -> Self {
933        Self {
934            map: HashMap::with_capacity(capacity),
935        }
936    }
937}
938
939impl<K, H> Default for HashSet<K, H>
940where
941    H: BuildHasher + Default,
942{
943    /// Creates an empty default [`HashSet`].
944    ///
945    /// The default capacity is `0`.
946    ///
947    /// # Examples
948    ///
949    /// ```
950    /// use scc::HashSet;
951    ///
952    /// let hashset: HashSet<u64> = HashSet::default();
953    ///
954    /// let result = hashset.capacity();
955    /// assert_eq!(result, 0);
956    /// ```
957    #[inline]
958    fn default() -> Self {
959        Self {
960            map: HashMap::default(),
961        }
962    }
963}
964
965impl<K, H> FromIterator<K> for HashSet<K, H>
966where
967    K: Eq + Hash,
968    H: BuildHasher + Default,
969{
970    #[inline]
971    fn from_iter<T: IntoIterator<Item = K>>(iter: T) -> Self {
972        let into_iter = iter.into_iter();
973        let hashset = Self::with_capacity_and_hasher(
974            num_entries_from_hint(into_iter.size_hint()),
975            H::default(),
976        );
977        into_iter.for_each(|k| {
978            let _result = hashset.insert_sync(k);
979        });
980        hashset
981    }
982}
983
984impl<K, H> PartialEq for HashSet<K, H>
985where
986    K: Eq + Hash,
987    H: BuildHasher,
988{
989    /// Compares two [`HashSet`] instances.
990    ///
991    /// ### Locking behavior
992    ///
993    /// Shared locks on buckets are acquired when comparing two instances of [`HashSet`], therefore
994    /// it may lead to a deadlock if the instances are being modified by another thread.
995    #[inline]
996    fn eq(&self, other: &Self) -> bool {
997        if self.iter_sync(|k| other.contains_sync(k)) {
998            return other.iter_sync(|k| self.contains_sync(k));
999        }
1000        false
1001    }
1002}
1003
1004impl<'h, K, H> OccupiedEntry<'h, K, H>
1005where
1006    K: Eq + Hash,
1007    H: BuildHasher,
1008{
1009    /// Takes ownership of the value from the [`HashSet`].
1010    ///
1011    /// # Examples
1012    ///
1013    /// ```
1014    /// use scc::HashSet;
1015    ///
1016    /// let hashset: HashSet<u32> = HashSet::default();
1017    /// hashset.insert_sync(42);
1018    ///
1019    /// assert_eq!(hashset.begin_sync().unwrap().remove_entry(), 42);
1020    /// ```
1021    #[inline]
1022    #[must_use]
1023    pub fn remove_entry(self) -> K {
1024        self.occupied.remove_entry().0
1025    }
1026
1027    /// Gets a reference to the value in the entry.
1028    ///
1029    /// # Examples
1030    ///
1031    /// ```
1032    /// use scc::HashSet;
1033    ///
1034    /// let mut hashset: HashSet<u32> = HashSet::default();
1035    /// hashset.insert_sync(42);
1036    ///
1037    /// assert_eq!(hashset.begin_sync().unwrap().get(), &42);
1038    /// ```
1039    #[inline]
1040    #[must_use]
1041    pub fn get(&self) -> &K {
1042        self.occupied.key()
1043    }
1044
1045    /// Removes the entry and gets the next closest occupied entry.
1046    ///
1047    /// [`HashSet::begin_async`] and this method together allow the [`OccupiedEntry`] to
1048    /// effectively act as a mutable iterator over entries. This method never acquires more than one
1049    /// lock, even when it searches other buckets for the next closest occupied entry.
1050    ///
1051    /// # Examples
1052    ///
1053    /// ```
1054    /// use scc::HashSet;
1055    ///
1056    /// let hashset: HashSet<u32> = HashSet::default();
1057    ///
1058    /// assert!(hashset.insert_sync(1).is_ok());
1059    /// assert!(hashset.insert_sync(2).is_ok());
1060    ///
1061    /// let second_entry_future = hashset.begin_sync().unwrap().remove_and_async();
1062    /// ```
1063    #[inline]
1064    pub async fn remove_and_async(self) -> (K, Option<OccupiedEntry<'h, K, H>>) {
1065        let ((k, ()), occupied) = self.occupied.remove_and_async().await;
1066        (k, occupied.map(|occupied| Self { occupied }))
1067    }
1068
1069    /// Removes the entry and gets the next closest occupied entry.
1070    ///
1071    /// [`HashSet::begin_sync`] and this method together allow the [`OccupiedEntry`] to effectively
1072    /// act as a mutable iterator over entries. This method never acquires more than one lock, even
1073    /// when it searches other buckets for the next closest occupied entry.
1074    ///
1075    /// # Examples
1076    ///
1077    /// ```
1078    /// use scc::HashSet;
1079    ///
1080    /// let hashset: HashSet<u32> = HashSet::default();
1081    ///
1082    /// assert!(hashset.insert_sync(1).is_ok());
1083    /// assert!(hashset.insert_sync(2).is_ok());
1084    ///
1085    /// let first_entry = hashset.begin_sync().unwrap();
1086    /// let first_value = *first_entry.get();
1087    /// let (_, second_entry) = first_entry.remove_and_sync();
1088    /// assert_eq!(hashset.len(), 1);
1089    ///
1090    /// let second_entry = second_entry.unwrap();
1091    /// let second_value = *second_entry.get();
1092    ///
1093    /// assert!(second_entry.remove_and_sync().1.is_none());
1094    /// assert_eq!(first_value + second_value, 3);
1095    /// ```
1096    #[inline]
1097    #[must_use]
1098    pub fn remove_and_sync(self) -> (K, Option<Self>) {
1099        let ((k, ()), occupied) = self.occupied.remove_and_sync();
1100        (k, occupied.map(|occupied| Self { occupied }))
1101    }
1102
1103    /// Gets the next closest occupied entry.
1104    ///
1105    /// [`HashSet::begin_async`] and this method together allow the [`OccupiedEntry`] to
1106    /// effectively act as a mutable iterator over entries. This method never acquires more than one
1107    /// lock, even when it searches other buckets for the next closest occupied entry.
1108    ///
1109    /// # Examples
1110    ///
1111    /// ```
1112    /// use scc::HashSet;
1113    ///
1114    /// let hashset: HashSet<u32> = HashSet::default();
1115    ///
1116    /// assert!(hashset.insert_sync(1).is_ok());
1117    /// assert!(hashset.insert_sync(2).is_ok());
1118    ///
1119    /// let second_entry_future = hashset.begin_sync().unwrap().next_async();
1120    /// ```
1121    #[inline]
1122    pub async fn next_async(self) -> Option<OccupiedEntry<'h, K, H>> {
1123        self.occupied
1124            .next_async()
1125            .await
1126            .map(|occupied| Self { occupied })
1127    }
1128
1129    /// Gets the next closest occupied entry.
1130    ///
1131    /// [`HashSet::begin_sync`] and this method together allow the [`OccupiedEntry`] to effectively
1132    /// act as a mutable iterator over entries. This method never acquires more than one lock, even
1133    /// when it searches other buckets for the next closest occupied entry.
1134    ///
1135    /// # Examples
1136    ///
1137    /// ```
1138    /// use scc::HashSet;
1139    ///
1140    /// let hashset: HashSet<u32> = HashSet::default();
1141    ///
1142    /// assert!(hashset.insert_sync(1).is_ok());
1143    /// assert!(hashset.insert_sync(2).is_ok());
1144    ///
1145    /// let first_entry = hashset.begin_sync().unwrap();
1146    /// let first_value = *first_entry.get();
1147    /// let second_entry = first_entry.next_sync().unwrap();
1148    /// let second_value = *second_entry.get();
1149    ///
1150    /// assert!(second_entry.next_sync().is_none());
1151    /// assert_eq!(first_value + second_value, 3);
1152    /// ```
1153    #[inline]
1154    #[must_use]
1155    pub fn next_sync(self) -> Option<Self> {
1156        self.occupied.next_sync().map(|occupied| Self { occupied })
1157    }
1158}
1159
1160impl<K, H> Debug for OccupiedEntry<'_, K, H>
1161where
1162    K: Debug + Eq + Hash,
1163    H: BuildHasher,
1164{
1165    #[inline]
1166    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1167        f.debug_struct("OccupiedEntry")
1168            .field("data", self.get())
1169            .finish_non_exhaustive()
1170    }
1171}
1172
1173impl<K, H> Deref for OccupiedEntry<'_, K, H>
1174where
1175    K: Eq + Hash,
1176    H: BuildHasher,
1177{
1178    type Target = K;
1179
1180    #[inline]
1181    fn deref(&self) -> &Self::Target {
1182        self.get()
1183    }
1184}
1185
1186impl<K> ConsumableEntry<'_, K> {
1187    /// Consumes the entry by moving out the key.
1188    ///
1189    /// # Examples
1190    ///
1191    /// ```
1192    /// use scc::HashSet;
1193    ///
1194    /// let hashset: HashSet<u64> = HashSet::default();
1195    ///
1196    /// assert!(hashset.insert_sync(1).is_ok());
1197    /// assert!(hashset.insert_sync(2).is_ok());
1198    /// assert!(hashset.insert_sync(3).is_ok());
1199    ///
1200    /// let mut consumed = None;
1201    ///
1202    /// hashset.iter_mut_sync(|e| {
1203    ///     if *e == 1 {
1204    ///         consumed.replace(e.consume());
1205    ///     }
1206    ///     true
1207    /// });
1208    ///
1209    /// assert!(!hashset.contains_sync(&1));
1210    /// assert_eq!(consumed, Some(1));
1211    /// ```
1212    #[inline]
1213    #[must_use]
1214    pub fn consume(self) -> K {
1215        self.consumable.consume().0
1216    }
1217}
1218
1219impl<K> Deref for ConsumableEntry<'_, K> {
1220    type Target = K;
1221
1222    #[inline]
1223    fn deref(&self) -> &Self::Target {
1224        self.consumable.key()
1225    }
1226}