Skip to content

Commit 4d6dde3

Browse files
authored
Merge pull request #197 from cuviper/par_drain
impl ParallelDrainRange
2 parents f9a3ca9 + 1426285 commit 4d6dde3

File tree

6 files changed

+93
-5
lines changed

6 files changed

+93
-5
lines changed

Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ bench = false
3434
autocfg = "1"
3535
[dependencies]
3636
serde = { version = "1.0", optional = true, default-features = false }
37-
rayon = { version = "1.2", optional = true }
37+
rayon = { version = "1.4.1", optional = true }
3838

3939
# Internal feature, only used when building as part of rustc,
4040
# not part of the stable interface of this crate.

src/map.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -69,12 +69,12 @@ pub use self::core::{Entry, OccupiedEntry, VacantEntry};
6969
/// ```
7070
#[cfg(has_std)]
7171
pub struct IndexMap<K, V, S = RandomState> {
72-
core: IndexMapCore<K, V>,
72+
pub(crate) core: IndexMapCore<K, V>,
7373
hash_builder: S,
7474
}
7575
#[cfg(not(has_std))]
7676
pub struct IndexMap<K, V, S> {
77-
core: IndexMapCore<K, V>,
77+
pub(crate) core: IndexMapCore<K, V>,
7878
hash_builder: S,
7979
}
8080

src/map/core.rs

+13
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,19 @@ impl<K, V> IndexMapCore<K, V> {
166166
self.entries.drain(range)
167167
}
168168

169+
#[cfg(feature = "rayon")]
170+
pub(crate) fn par_drain<R>(&mut self, range: R) -> rayon::vec::Drain<'_, Bucket<K, V>>
171+
where
172+
K: Send,
173+
V: Send,
174+
R: RangeBounds<usize>,
175+
{
176+
use rayon::iter::ParallelDrainRange;
177+
let range = simplify_range(range, self.entries.len());
178+
self.erase_indices(range.start, range.end);
179+
self.entries.par_drain(range)
180+
}
181+
169182
pub(crate) fn split_off(&mut self, at: usize) -> Self {
170183
assert!(at <= self.entries.len());
171184
self.erase_indices(at, self.entries.len());

src/rayon/map.rs

+38
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ use crate::vec::Vec;
1313
use core::cmp::Ordering;
1414
use core::fmt;
1515
use core::hash::{BuildHasher, Hash};
16+
use core::ops::RangeBounds;
1617

1718
use crate::Bucket;
1819
use crate::Entries;
@@ -156,6 +157,43 @@ impl<K: Sync + Send, V: Send> IndexedParallelIterator for ParIterMut<'_, K, V> {
156157
indexed_parallel_iterator_methods!(Bucket::ref_mut);
157158
}
158159

160+
/// Requires crate feature `"rayon"`.
161+
impl<'a, K, V, S> ParallelDrainRange<usize> for &'a mut IndexMap<K, V, S>
162+
where
163+
K: Send,
164+
V: Send,
165+
{
166+
type Item = (K, V);
167+
type Iter = ParDrain<'a, K, V>;
168+
169+
fn par_drain<R: RangeBounds<usize>>(self, range: R) -> Self::Iter {
170+
ParDrain {
171+
entries: self.core.par_drain(range),
172+
}
173+
}
174+
}
175+
176+
/// A parallel draining iterator over the entries of a `IndexMap`.
177+
///
178+
/// This `struct` is created by the [`par_drain`] method on [`IndexMap`]
179+
/// (provided by rayon's `ParallelDrainRange` trait). See its documentation for more.
180+
///
181+
/// [`par_drain`]: ../struct.IndexMap.html#method.par_drain
182+
/// [`IndexMap`]: ../struct.IndexMap.html
183+
pub struct ParDrain<'a, K: Send, V: Send> {
184+
entries: rayon::vec::Drain<'a, Bucket<K, V>>,
185+
}
186+
187+
impl<K: Send, V: Send> ParallelIterator for ParDrain<'_, K, V> {
188+
type Item = (K, V);
189+
190+
parallel_iterator_methods!(Bucket::key_value);
191+
}
192+
193+
impl<K: Send, V: Send> IndexedParallelIterator for ParDrain<'_, K, V> {
194+
indexed_parallel_iterator_methods!(Bucket::key_value);
195+
}
196+
159197
/// Parallel iterator methods and other parallel methods.
160198
///
161199
/// The following methods **require crate feature `"rayon"`**.

src/rayon/set.rs

+37
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ use crate::vec::Vec;
1313
use core::cmp::Ordering;
1414
use core::fmt;
1515
use core::hash::{BuildHasher, Hash};
16+
use core::ops::RangeBounds;
1617

1718
use crate::Entries;
1819
use crate::IndexSet;
@@ -111,6 +112,42 @@ impl<T: Sync> IndexedParallelIterator for ParIter<'_, T> {
111112
indexed_parallel_iterator_methods!(Bucket::key_ref);
112113
}
113114

115+
/// Requires crate feature `"rayon"`.
116+
impl<'a, T, S> ParallelDrainRange<usize> for &'a mut IndexSet<T, S>
117+
where
118+
T: Send,
119+
{
120+
type Item = T;
121+
type Iter = ParDrain<'a, T>;
122+
123+
fn par_drain<R: RangeBounds<usize>>(self, range: R) -> Self::Iter {
124+
ParDrain {
125+
entries: self.map.core.par_drain(range),
126+
}
127+
}
128+
}
129+
130+
/// A parallel draining iterator over the items of a `IndexSet`.
131+
///
132+
/// This `struct` is created by the [`par_drain`] method on [`IndexSet`]
133+
/// (provided by rayon's `ParallelDrainRange` trait). See its documentation for more.
134+
///
135+
/// [`par_drain`]: ../struct.IndexSet.html#method.par_drain
136+
/// [`IndexSet`]: ../struct.IndexSet.html
137+
pub struct ParDrain<'a, T: Send> {
138+
entries: rayon::vec::Drain<'a, Bucket<T>>,
139+
}
140+
141+
impl<T: Send> ParallelIterator for ParDrain<'_, T> {
142+
type Item = T;
143+
144+
parallel_iterator_methods!(Bucket::key);
145+
}
146+
147+
impl<T: Send> IndexedParallelIterator for ParDrain<'_, T> {
148+
indexed_parallel_iterator_methods!(Bucket::key);
149+
}
150+
114151
/// Parallel iterator methods and other parallel methods.
115152
///
116153
/// The following methods **require crate feature `"rayon"`**.

src/set.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -61,11 +61,11 @@ type Bucket<T> = super::Bucket<T, ()>;
6161
/// ```
6262
#[cfg(has_std)]
6363
pub struct IndexSet<T, S = RandomState> {
64-
map: IndexMap<T, (), S>,
64+
pub(crate) map: IndexMap<T, (), S>,
6565
}
6666
#[cfg(not(has_std))]
6767
pub struct IndexSet<T, S> {
68-
map: IndexMap<T, (), S>,
68+
pub(crate) map: IndexMap<T, (), S>,
6969
}
7070

7171
impl<T, S> Clone for IndexSet<T, S>

0 commit comments

Comments
 (0)