flat_multimap/rayon/
set.rs

1use std::hash::{BuildHasher, Hash};
2
3use super::{collect, map};
4use crate::FlatMultiset;
5use rayon::iter::plumbing::UnindexedConsumer;
6use rayon::iter::{FromParallelIterator, IntoParallelIterator, ParallelExtend, ParallelIterator};
7
8/// Parallel iterator over elements of a consumed set.
9pub struct IntoParIter<T> {
10    inner: map::IntoParIter<T, ()>,
11}
12
13impl<T: Send> ParallelIterator for IntoParIter<T> {
14    type Item = T;
15
16    fn drive_unindexed<C>(self, consumer: C) -> C::Result
17    where
18        C: UnindexedConsumer<Self::Item>,
19    {
20        self.inner.map(|(k, _)| k).drive_unindexed(consumer)
21    }
22}
23
24/// Parallel draining iterator over entries of a set.
25pub struct ParDrain<'a, T> {
26    inner: map::ParDrain<'a, T, ()>,
27}
28
29impl<T: Send> ParallelIterator for ParDrain<'_, T> {
30    type Item = T;
31
32    fn drive_unindexed<C>(self, consumer: C) -> C::Result
33    where
34        C: UnindexedConsumer<Self::Item>,
35    {
36        self.inner.map(|(k, _)| k).drive_unindexed(consumer)
37    }
38}
39
40/// Parallel iterator over shared references to elements in a set.
41pub struct ParIter<'a, T> {
42    inner: map::ParKeys<'a, T, ()>,
43}
44
45impl<'a, T: Sync> ParallelIterator for ParIter<'a, T> {
46    type Item = &'a T;
47
48    fn drive_unindexed<C>(self, consumer: C) -> C::Result
49    where
50        C: UnindexedConsumer<Self::Item>,
51    {
52        self.inner.drive_unindexed(consumer)
53    }
54}
55
56impl<T, S> FlatMultiset<T, S>
57where
58    T: Eq + Hash + Send,
59{
60    /// Consumes (potentially in parallel) all values in an arbitrary order.
61    pub fn par_drain(&mut self) -> ParDrain<'_, T> {
62        ParDrain {
63            inner: self.map.par_drain(),
64        }
65    }
66}
67
68impl<T: Send, S> IntoParallelIterator for FlatMultiset<T, S> {
69    type Item = T;
70    type Iter = IntoParIter<T>;
71
72    fn into_par_iter(self) -> Self::Iter {
73        IntoParIter {
74            inner: self.map.into_par_iter(),
75        }
76    }
77}
78
79impl<'a, T: Sync, S> IntoParallelIterator for &'a FlatMultiset<T, S> {
80    type Item = &'a T;
81    type Iter = ParIter<'a, T>;
82
83    fn into_par_iter(self) -> Self::Iter {
84        ParIter {
85            inner: self.map.par_keys(),
86        }
87    }
88}
89
90impl<T, S> FromParallelIterator<T> for FlatMultiset<T, S>
91where
92    T: Eq + Hash + Send,
93    S: BuildHasher + Default,
94{
95    fn from_par_iter<P>(par_iter: P) -> Self
96    where
97        P: IntoParallelIterator<Item = T>,
98    {
99        let mut set = FlatMultiset::default();
100        set.par_extend(par_iter);
101        set
102    }
103}
104
105impl<T, S> ParallelExtend<T> for FlatMultiset<T, S>
106where
107    T: Eq + Hash + Send,
108    S: BuildHasher,
109{
110    fn par_extend<I>(&mut self, par_iter: I)
111    where
112        I: IntoParallelIterator<Item = T>,
113    {
114        extend(self, par_iter);
115    }
116}
117
118impl<'a, T, S> ParallelExtend<&'a T> for FlatMultiset<T, S>
119where
120    T: 'a + Copy + Eq + Hash + Sync,
121    S: BuildHasher,
122{
123    fn par_extend<I>(&mut self, par_iter: I)
124    where
125        I: IntoParallelIterator<Item = &'a T>,
126    {
127        extend(self, par_iter);
128    }
129}
130
131fn extend<T, S, I>(set: &mut FlatMultiset<T, S>, par_iter: I)
132where
133    T: Eq + Hash,
134    S: BuildHasher,
135    I: IntoParallelIterator,
136    FlatMultiset<T, S>: Extend<I::Item>,
137{
138    let (list, len) = collect(par_iter);
139
140    set.reserve(len);
141
142    for vec in list {
143        set.extend(vec);
144    }
145}