Skip to content

Commit 1426285

Browse files
committed
impl ParallelDrainRange
1 parent a6e0188 commit 1426285

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
[dependencies.hashbrown]
4040
version = "0.11"

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;
@@ -149,6 +150,43 @@ impl<K: Sync + Send, V: Send> IndexedParallelIterator for ParIterMut<'_, K, V> {
149150
indexed_parallel_iterator_methods!(Bucket::ref_mut);
150151
}
151152

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