Skip to main content

crossbeam_skiplist/
set.rs

1//! A set based on a lock-free skip list. See [`SkipSet`].
2
3use std::borrow::Borrow;
4use std::fmt;
5use std::ops::Deref;
6use std::ops::{Bound, RangeBounds};
7
8use crate::map;
9
10/// A set based on a lock-free skip list.
11///
12/// This is an alternative to [`BTreeSet`] which supports
13/// concurrent access across multiple threads.
14///
15/// [`BTreeSet`]: std::collections::BTreeSet
16pub struct SkipSet<T> {
17    inner: map::SkipMap<T, ()>,
18}
19
20impl<T> SkipSet<T> {
21    /// Returns a new, empty set.
22    ///
23    /// # Example
24    ///
25    /// ```
26    /// use crossbeam_skiplist::SkipSet;
27    ///
28    /// let set: SkipSet<i32> = SkipSet::new();
29    /// ```
30    pub fn new() -> Self {
31        Self {
32            inner: map::SkipMap::new(),
33        }
34    }
35
36    /// Returns `true` if the set is empty.
37    ///
38    /// # Example
39    ///
40    /// ```
41    /// use crossbeam_skiplist::SkipSet;
42    ///
43    /// let set = SkipSet::new();
44    /// assert!(set.is_empty());
45    ///
46    /// set.insert(1);
47    /// assert!(!set.is_empty());
48    /// ```
49    pub fn is_empty(&self) -> bool {
50        self.inner.is_empty()
51    }
52
53    /// Returns the number of entries in the set.
54    ///
55    /// If the set is being concurrently modified, consider the returned number just an
56    /// approximation without any guarantees.
57    ///
58    /// # Example
59    ///
60    /// ```
61    /// use crossbeam_skiplist::SkipSet;
62    ///
63    /// let set = SkipSet::new();
64    /// assert_eq!(set.len(), 0);
65    ///
66    /// set.insert(1);
67    /// assert_eq!(set.len(), 1);
68    /// ```
69    pub fn len(&self) -> usize {
70        self.inner.len()
71    }
72}
73
74impl<T> SkipSet<T>
75where
76    T: Ord,
77{
78    /// Returns the entry with the smallest key.
79    ///
80    /// # Example
81    ///
82    /// ```
83    /// use crossbeam_skiplist::SkipSet;
84    ///
85    /// let set = SkipSet::new();
86    /// set.insert(1);
87    /// assert_eq!(*set.front().unwrap(), 1);
88    /// set.insert(2);
89    /// assert_eq!(*set.front().unwrap(), 1);
90    /// ```
91    pub fn front(&self) -> Option<Entry<'_, T>> {
92        self.inner.front().map(Entry::new)
93    }
94
95    /// Returns the entry with the largest key.
96    ///
97    /// # Example
98    ///
99    /// ```
100    /// use crossbeam_skiplist::SkipSet;
101    ///
102    /// let set = SkipSet::new();
103    /// set.insert(1);
104    /// assert_eq!(*set.back().unwrap(), 1);
105    /// set.insert(2);
106    /// assert_eq!(*set.back().unwrap(), 2);
107    /// ```
108    pub fn back(&self) -> Option<Entry<'_, T>> {
109        self.inner.back().map(Entry::new)
110    }
111
112    /// Returns `true` if the set contains a value for the specified key.
113    ///
114    /// # Example
115    ///
116    /// ```
117    /// use crossbeam_skiplist::SkipSet;
118    ///
119    /// let set: SkipSet<_> = (1..=3).collect();
120    /// assert!(set.contains(&1));
121    /// assert!(!set.contains(&4));
122    /// ```
123    pub fn contains<Q>(&self, key: &Q) -> bool
124    where
125        T: Borrow<Q>,
126        Q: Ord + ?Sized,
127    {
128        self.inner.contains_key(key)
129    }
130
131    /// Returns an entry with the specified `key`.
132    ///
133    /// # Example
134    ///
135    /// ```
136    /// use crossbeam_skiplist::SkipSet;
137    ///
138    /// let set: SkipSet<_> = (1..=3).collect();
139    /// assert_eq!(*set.get(&3).unwrap(), 3);
140    /// assert!(set.get(&4).is_none());
141    /// ```
142    pub fn get<Q>(&self, key: &Q) -> Option<Entry<'_, T>>
143    where
144        T: Borrow<Q>,
145        Q: Ord + ?Sized,
146    {
147        self.inner.get(key).map(Entry::new)
148    }
149
150    /// Returns an `Entry` pointing to the lowest element whose key is above
151    /// the given bound. If no such element is found then `None` is
152    /// returned.
153    ///
154    /// # Example
155    ///
156    /// ```
157    /// use crossbeam_skiplist::SkipSet;
158    /// use std::ops::Bound::*;
159    ///
160    /// let set = SkipSet::new();
161    /// set.insert(6);
162    /// set.insert(7);
163    /// set.insert(12);
164    ///
165    /// let greater_than_five = set.lower_bound(Excluded(&5)).unwrap();
166    /// assert_eq!(*greater_than_five, 6);
167    ///
168    /// let greater_than_six = set.lower_bound(Excluded(&6)).unwrap();
169    /// assert_eq!(*greater_than_six, 7);
170    ///
171    /// let greater_than_thirteen = set.lower_bound(Excluded(&13));
172    /// assert!(greater_than_thirteen.is_none());
173    /// ```
174    pub fn lower_bound<'a, Q>(&'a self, bound: Bound<&Q>) -> Option<Entry<'a, T>>
175    where
176        T: Borrow<Q>,
177        Q: Ord + ?Sized,
178    {
179        self.inner.lower_bound(bound).map(Entry::new)
180    }
181
182    /// Returns an `Entry` pointing to the highest element whose key is below
183    /// the given bound. If no such element is found then `None` is
184    /// returned.
185    ///
186    /// # Example
187    ///
188    /// ```
189    /// use crossbeam_skiplist::SkipSet;
190    /// use std::ops::Bound::*;
191    ///
192    /// let set = SkipSet::new();
193    /// set.insert(6);
194    /// set.insert(7);
195    /// set.insert(12);
196    ///
197    /// let less_than_eight = set.upper_bound(Excluded(&8)).unwrap();
198    /// assert_eq!(*less_than_eight, 7);
199    ///
200    /// let less_than_six = set.upper_bound(Excluded(&6));
201    /// assert!(less_than_six.is_none());
202    /// ```
203    pub fn upper_bound<'a, Q>(&'a self, bound: Bound<&Q>) -> Option<Entry<'a, T>>
204    where
205        T: Borrow<Q>,
206        Q: Ord + ?Sized,
207    {
208        self.inner.upper_bound(bound).map(Entry::new)
209    }
210
211    /// Finds an entry with the specified key, or inserts a new `key`-`value` pair if none exist.
212    ///
213    /// # Example
214    ///
215    /// ```
216    /// use crossbeam_skiplist::SkipSet;
217    ///
218    /// let set = SkipSet::new();
219    /// let entry = set.get_or_insert(2);
220    /// assert_eq!(*entry, 2);
221    /// ```
222    pub fn get_or_insert(&self, key: T) -> Entry<'_, T> {
223        Entry::new(self.inner.get_or_insert(key, ()))
224    }
225
226    /// Returns an iterator over all entries in the set.
227    ///
228    /// # Examples
229    ///
230    /// ```
231    /// use crossbeam_skiplist::SkipSet;
232    ///
233    /// let set = SkipSet::new();
234    /// set.insert(6);
235    /// set.insert(7);
236    /// set.insert(12);
237    ///
238    /// let mut set_iter = set.iter();
239    /// assert_eq!(*set_iter.next().unwrap(), 6);
240    /// assert_eq!(*set_iter.next().unwrap(), 7);
241    /// assert_eq!(*set_iter.next().unwrap(), 12);
242    /// assert!(set_iter.next().is_none());
243    /// ```
244    pub fn iter(&self) -> Iter<'_, T> {
245        Iter {
246            inner: self.inner.iter(),
247        }
248    }
249
250    /// Returns an iterator over a subset of entries in the set.
251    ///
252    /// # Example
253    ///
254    /// ```
255    /// use crossbeam_skiplist::SkipSet;
256    ///
257    /// let set = SkipSet::new();
258    /// set.insert(6);
259    /// set.insert(7);
260    /// set.insert(12);
261    ///
262    /// let mut set_range = set.range(5..=8);
263    /// assert_eq!(*set_range.next().unwrap(), 6);
264    /// assert_eq!(*set_range.next().unwrap(), 7);
265    /// assert!(set_range.next().is_none());
266    /// ```
267    pub fn range<Q, R>(&self, range: R) -> Range<'_, Q, R, T>
268    where
269        T: Borrow<Q>,
270        R: RangeBounds<Q>,
271        Q: Ord + ?Sized,
272    {
273        Range {
274            inner: self.inner.range(range),
275        }
276    }
277}
278
279impl<T> SkipSet<T>
280where
281    T: Ord + Send + 'static,
282{
283    /// Inserts a `key`-`value` pair into the set and returns the new entry.
284    ///
285    /// If there is an existing entry with this key, it will be removed before inserting the new
286    /// one.
287    ///
288    /// # Example
289    ///
290    /// ```
291    /// use crossbeam_skiplist::SkipSet;
292    ///
293    /// let set = SkipSet::new();
294    /// set.insert(2);
295    /// assert_eq!(*set.get(&2).unwrap(), 2);
296    /// ```
297    pub fn insert(&self, key: T) -> Entry<'_, T> {
298        Entry::new(self.inner.insert(key, ()))
299    }
300
301    /// Removes an entry with the specified key from the set and returns it.
302    ///
303    /// The value will not actually be dropped until all references to it have gone
304    /// out of scope.
305    ///
306    /// # Example
307    ///
308    /// ```
309    /// use crossbeam_skiplist::SkipSet;
310    ///
311    /// let set = SkipSet::new();
312    /// set.insert(2);
313    /// assert_eq!(*set.remove(&2).unwrap(), 2);
314    /// assert!(set.remove(&2).is_none());
315    /// ```
316    pub fn remove<Q>(&self, key: &Q) -> Option<Entry<'_, T>>
317    where
318        T: Borrow<Q>,
319        Q: Ord + ?Sized,
320    {
321        self.inner.remove(key).map(Entry::new)
322    }
323
324    /// Removes an entry from the front of the set.
325    /// Returns the removed entry.
326    ///
327    /// The value will not actually be dropped until all references to it have gone
328    /// out of scope.
329    ///
330    /// # Example
331    ///
332    /// ```
333    /// use crossbeam_skiplist::SkipSet;
334    ///
335    /// let set = SkipSet::new();
336    /// set.insert(1);
337    /// set.insert(2);
338    ///
339    /// assert_eq!(*set.pop_front().unwrap(), 1);
340    /// assert_eq!(*set.pop_front().unwrap(), 2);
341    ///
342    /// // All entries have been removed now.
343    /// assert!(set.is_empty());
344    /// ```
345    pub fn pop_front(&self) -> Option<Entry<'_, T>> {
346        self.inner.pop_front().map(Entry::new)
347    }
348
349    /// Removes an entry from the back of the set.
350    /// Returns the removed entry.
351    ///
352    /// The value will not actually be dropped until all references to it have gone
353    /// out of scope.
354    ///
355    /// # Example
356    ///
357    /// ```
358    /// use crossbeam_skiplist::SkipSet;
359    ///
360    /// let set = SkipSet::new();
361    /// set.insert(1);
362    /// set.insert(2);
363    ///
364    /// assert_eq!(*set.pop_back().unwrap(), 2);
365    /// assert_eq!(*set.pop_back().unwrap(), 1);
366    ///
367    /// // All entries have been removed now.
368    /// assert!(set.is_empty());
369    /// ```
370    pub fn pop_back(&self) -> Option<Entry<'_, T>> {
371        self.inner.pop_back().map(Entry::new)
372    }
373
374    /// Iterates over the set and removes every entry.
375    ///
376    /// # Example
377    ///
378    /// ```
379    /// use crossbeam_skiplist::SkipSet;
380    ///
381    /// let set = SkipSet::new();
382    /// set.insert(1);
383    /// set.insert(2);
384    ///
385    /// set.clear();
386    /// assert!(set.is_empty());
387    /// ```
388    pub fn clear(&self) {
389        self.inner.clear();
390    }
391}
392
393impl<T> Default for SkipSet<T> {
394    fn default() -> Self {
395        Self::new()
396    }
397}
398
399impl<T> fmt::Debug for SkipSet<T>
400where
401    T: Ord + fmt::Debug,
402{
403    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
404        f.pad("SkipSet { .. }")
405    }
406}
407
408impl<T> IntoIterator for SkipSet<T> {
409    type Item = T;
410    type IntoIter = IntoIter<T>;
411
412    fn into_iter(self) -> IntoIter<T> {
413        IntoIter {
414            inner: self.inner.into_iter(),
415        }
416    }
417}
418
419impl<'a, T> IntoIterator for &'a SkipSet<T>
420where
421    T: Ord,
422{
423    type Item = Entry<'a, T>;
424    type IntoIter = Iter<'a, T>;
425
426    fn into_iter(self) -> Iter<'a, T> {
427        self.iter()
428    }
429}
430
431impl<T> FromIterator<T> for SkipSet<T>
432where
433    T: Ord,
434{
435    fn from_iter<I>(iter: I) -> Self
436    where
437        I: IntoIterator<Item = T>,
438    {
439        let s = Self::new();
440        for t in iter {
441            s.get_or_insert(t);
442        }
443        s
444    }
445}
446
447/// A reference-counted entry in a set.
448pub struct Entry<'a, T> {
449    inner: map::Entry<'a, T, ()>,
450}
451
452impl<'a, T> Entry<'a, T> {
453    fn new(inner: map::Entry<'a, T, ()>) -> Self {
454        Self { inner }
455    }
456
457    /// Returns a reference to the value.
458    pub fn value(&self) -> &T {
459        self.inner.key()
460    }
461
462    /// Returns `true` if the entry is removed from the set.
463    pub fn is_removed(&self) -> bool {
464        self.inner.is_removed()
465    }
466}
467
468impl<'a, T> Entry<'a, T>
469where
470    T: Ord,
471{
472    /// Moves to the next entry in the set.
473    pub fn move_next(&mut self) -> bool {
474        self.inner.move_next()
475    }
476
477    /// Moves to the previous entry in the set.
478    pub fn move_prev(&mut self) -> bool {
479        self.inner.move_prev()
480    }
481
482    /// Returns the next entry in the set.
483    pub fn next(&self) -> Option<Entry<'a, T>> {
484        self.inner.next().map(Entry::new)
485    }
486
487    /// Returns the previous entry in the set.
488    pub fn prev(&self) -> Option<Entry<'a, T>> {
489        self.inner.prev().map(Entry::new)
490    }
491}
492
493impl<T> Entry<'_, T>
494where
495    T: Ord + Send + 'static,
496{
497    /// Removes the entry from the set.
498    ///
499    /// Returns `true` if this call removed the entry and `false` if it was already removed.
500    pub fn remove(&self) -> bool {
501        self.inner.remove()
502    }
503}
504
505impl<T> Clone for Entry<'_, T> {
506    fn clone(&self) -> Self {
507        Self {
508            inner: self.inner.clone(),
509        }
510    }
511}
512
513impl<T> fmt::Debug for Entry<'_, T>
514where
515    T: fmt::Debug,
516{
517    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
518        f.debug_struct("Entry")
519            .field("value", self.value())
520            .finish()
521    }
522}
523
524impl<T> Deref for Entry<'_, T> {
525    type Target = T;
526
527    fn deref(&self) -> &Self::Target {
528        self.value()
529    }
530}
531
532/// An owning iterator over the entries of a `SkipSet`.
533pub struct IntoIter<T> {
534    inner: map::IntoIter<T, ()>,
535}
536
537impl<T> Iterator for IntoIter<T> {
538    type Item = T;
539
540    fn next(&mut self) -> Option<T> {
541        self.inner.next().map(|(k, ())| k)
542    }
543}
544
545impl<T> fmt::Debug for IntoIter<T> {
546    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
547        f.pad("IntoIter { .. }")
548    }
549}
550
551/// An iterator over the entries of a `SkipSet`.
552pub struct Iter<'a, T> {
553    inner: map::Iter<'a, T, ()>,
554}
555
556impl<'a, T> Iterator for Iter<'a, T>
557where
558    T: Ord,
559{
560    type Item = Entry<'a, T>;
561
562    fn next(&mut self) -> Option<Entry<'a, T>> {
563        self.inner.next().map(Entry::new)
564    }
565}
566
567impl<'a, T> DoubleEndedIterator for Iter<'a, T>
568where
569    T: Ord,
570{
571    fn next_back(&mut self) -> Option<Entry<'a, T>> {
572        self.inner.next_back().map(Entry::new)
573    }
574}
575
576impl<T> fmt::Debug for Iter<'_, T> {
577    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
578        f.pad("Iter { .. }")
579    }
580}
581
582/// An iterator over a subset of entries of a `SkipSet`.
583pub struct Range<'a, Q, R, T>
584where
585    T: Ord + Borrow<Q>,
586    R: RangeBounds<Q>,
587    Q: Ord + ?Sized,
588{
589    inner: map::Range<'a, Q, R, T, ()>,
590}
591
592impl<'a, Q, R, T> Iterator for Range<'a, Q, R, T>
593where
594    T: Ord + Borrow<Q>,
595    R: RangeBounds<Q>,
596    Q: Ord + ?Sized,
597{
598    type Item = Entry<'a, T>;
599
600    fn next(&mut self) -> Option<Entry<'a, T>> {
601        self.inner.next().map(Entry::new)
602    }
603}
604
605impl<'a, Q, R, T> DoubleEndedIterator for Range<'a, Q, R, T>
606where
607    T: Ord + Borrow<Q>,
608    R: RangeBounds<Q>,
609    Q: Ord + ?Sized,
610{
611    fn next_back(&mut self) -> Option<Entry<'a, T>> {
612        self.inner.next_back().map(Entry::new)
613    }
614}
615
616impl<Q, R, T> fmt::Debug for Range<'_, Q, R, T>
617where
618    T: Ord + Borrow<Q> + fmt::Debug,
619    R: RangeBounds<Q> + fmt::Debug,
620    Q: Ord + ?Sized,
621{
622    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
623        f.debug_struct("Range")
624            .field("range", &self.inner.inner.range)
625            .field("head", &self.inner.inner.head.as_ref().map(|e| e.key()))
626            .field("tail", &self.inner.inner.tail.as_ref().map(|e| e.key()))
627            .finish()
628    }
629}