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}