dashmap/rayon/
set.rs

1use crate::setref::multiple::RefMulti;
2use crate::DashSet;
3use core::hash::{BuildHasher, Hash};
4use rayon::iter::plumbing::UnindexedConsumer;
5use rayon::iter::{FromParallelIterator, IntoParallelIterator, ParallelExtend, ParallelIterator};
6
7impl<K, S> ParallelExtend<K> for DashSet<K, S>
8where
9    K: Send + Sync + Eq + Hash,
10    S: Send + Sync + Clone + BuildHasher,
11{
12    fn par_extend<I>(&mut self, par_iter: I)
13    where
14        I: IntoParallelIterator<Item = K>,
15    {
16        (&*self).par_extend(par_iter);
17    }
18}
19
20// Since we don't actually need mutability, we can implement this on a
21// reference, similar to `io::Write for &File`.
22impl<K, S> ParallelExtend<K> for &'_ DashSet<K, S>
23where
24    K: Send + Sync + Eq + Hash,
25    S: Send + Sync + Clone + BuildHasher,
26{
27    fn par_extend<I>(&mut self, par_iter: I)
28    where
29        I: IntoParallelIterator<Item = K>,
30    {
31        let &mut set = self;
32        par_iter.into_par_iter().for_each(move |key| {
33            set.insert(key);
34        });
35    }
36}
37
38impl<K, S> FromParallelIterator<K> for DashSet<K, S>
39where
40    K: Send + Sync + Eq + Hash,
41    S: Send + Sync + Clone + Default + BuildHasher,
42{
43    fn from_par_iter<I>(par_iter: I) -> Self
44    where
45        I: IntoParallelIterator<Item = K>,
46    {
47        let set = Self::default();
48        (&set).par_extend(par_iter);
49        set
50    }
51}
52
53impl<K, S> IntoParallelIterator for DashSet<K, S>
54where
55    K: Send + Eq + Hash,
56    S: Send + Clone + BuildHasher,
57{
58    type Iter = OwningIter<K>;
59    type Item = K;
60
61    fn into_par_iter(self) -> Self::Iter {
62        OwningIter {
63            inner: self.inner.into_par_iter(),
64        }
65    }
66}
67
68pub struct OwningIter<K> {
69    inner: super::map::OwningIter<K, ()>,
70}
71
72impl<K> ParallelIterator for OwningIter<K>
73where
74    K: Send + Eq + Hash,
75{
76    type Item = K;
77
78    fn drive_unindexed<C>(self, consumer: C) -> C::Result
79    where
80        C: UnindexedConsumer<Self::Item>,
81    {
82        self.inner.map(|(k, _)| k).drive_unindexed(consumer)
83    }
84}
85
86// This impl also enables `IntoParallelRefIterator::par_iter`
87impl<'a, K, S> IntoParallelIterator for &'a DashSet<K, S>
88where
89    K: Send + Sync + Eq + Hash,
90    S: Send + Sync + Clone + BuildHasher,
91{
92    type Iter = Iter<'a, K>;
93    type Item = RefMulti<'a, K>;
94
95    fn into_par_iter(self) -> Self::Iter {
96        Iter {
97            inner: (&self.inner).into_par_iter(),
98        }
99    }
100}
101
102pub struct Iter<'a, K> {
103    inner: super::map::Iter<'a, K, ()>,
104}
105
106impl<'a, K> ParallelIterator for Iter<'a, K>
107where
108    K: Send + Sync + Eq + Hash,
109{
110    type Item = RefMulti<'a, K>;
111
112    fn drive_unindexed<C>(self, consumer: C) -> C::Result
113    where
114        C: UnindexedConsumer<Self::Item>,
115    {
116        self.inner.map(RefMulti::new).drive_unindexed(consumer)
117    }
118}