1 //! Parallel iterator types for `IndexMap` with [rayon](https://docs.rs/rayon/1.0/rayon).
3 //! You will rarely need to interact with this module directly unless you need to name one of the
6 //! Requires crate feature `"rayon"`
9 use rayon
::iter
::plumbing
::{Consumer, ProducerCallback, UnindexedConsumer}
;
10 use rayon
::prelude
::*;
13 use core
::cmp
::Ordering
;
15 use core
::hash
::{BuildHasher, Hash}
;
16 use core
::ops
::RangeBounds
;
22 /// Requires crate feature `"rayon"`.
23 impl<K
, V
, S
> IntoParallelIterator
for IndexMap
<K
, V
, S
>
29 type Iter
= IntoParIter
<K
, V
>;
31 fn into_par_iter(self) -> Self::Iter
{
33 entries
: self.into_entries(),
38 /// A parallel owning iterator over the entries of a `IndexMap`.
40 /// This `struct` is created by the [`into_par_iter`] method on [`IndexMap`]
41 /// (provided by rayon's `IntoParallelIterator` trait). See its documentation for more.
43 /// [`into_par_iter`]: ../struct.IndexMap.html#method.into_par_iter
44 /// [`IndexMap`]: ../struct.IndexMap.html
45 pub struct IntoParIter
<K
, V
> {
46 entries
: Vec
<Bucket
<K
, V
>>,
49 impl<K
: fmt
::Debug
, V
: fmt
::Debug
> fmt
::Debug
for IntoParIter
<K
, V
> {
50 fn fmt(&self, f
: &mut fmt
::Formatter
<'_
>) -> fmt
::Result
{
51 let iter
= self.entries
.iter().map(Bucket
::refs
);
52 f
.debug_list().entries(iter
).finish()
56 impl<K
: Send
, V
: Send
> ParallelIterator
for IntoParIter
<K
, V
> {
59 parallel_iterator_methods
!(Bucket
::key_value
);
62 impl<K
: Send
, V
: Send
> IndexedParallelIterator
for IntoParIter
<K
, V
> {
63 indexed_parallel_iterator_methods
!(Bucket
::key_value
);
66 /// Requires crate feature `"rayon"`.
67 impl<'a
, K
, V
, S
> IntoParallelIterator
for &'a IndexMap
<K
, V
, S
>
72 type Item
= (&'a K
, &'a V
);
73 type Iter
= ParIter
<'a
, K
, V
>;
75 fn into_par_iter(self) -> Self::Iter
{
77 entries
: self.as_entries(),
82 /// A parallel iterator over the entries of a `IndexMap`.
84 /// This `struct` is created by the [`par_iter`] method on [`IndexMap`]
85 /// (provided by rayon's `IntoParallelRefIterator` trait). See its documentation for more.
87 /// [`par_iter`]: ../struct.IndexMap.html#method.par_iter
88 /// [`IndexMap`]: ../struct.IndexMap.html
89 pub struct ParIter
<'a
, K
, V
> {
90 entries
: &'a
[Bucket
<K
, V
>],
93 impl<K
, V
> Clone
for ParIter
<'_
, K
, V
> {
94 fn clone(&self) -> Self {
99 impl<K
: fmt
::Debug
, V
: fmt
::Debug
> fmt
::Debug
for ParIter
<'_
, K
, V
> {
100 fn fmt(&self, f
: &mut fmt
::Formatter
<'_
>) -> fmt
::Result
{
101 let iter
= self.entries
.iter().map(Bucket
::refs
);
102 f
.debug_list().entries(iter
).finish()
106 impl<'a
, K
: Sync
, V
: Sync
> ParallelIterator
for ParIter
<'a
, K
, V
> {
107 type Item
= (&'a K
, &'a V
);
109 parallel_iterator_methods
!(Bucket
::refs
);
112 impl<K
: Sync
, V
: Sync
> IndexedParallelIterator
for ParIter
<'_
, K
, V
> {
113 indexed_parallel_iterator_methods
!(Bucket
::refs
);
116 /// Requires crate feature `"rayon"`.
117 impl<'a
, K
, V
, S
> IntoParallelIterator
for &'a
mut IndexMap
<K
, V
, S
>
122 type Item
= (&'a K
, &'a
mut V
);
123 type Iter
= ParIterMut
<'a
, K
, V
>;
125 fn into_par_iter(self) -> Self::Iter
{
127 entries
: self.as_entries_mut(),
132 /// A parallel mutable iterator over the entries of a `IndexMap`.
134 /// This `struct` is created by the [`par_iter_mut`] method on [`IndexMap`]
135 /// (provided by rayon's `IntoParallelRefMutIterator` trait). See its documentation for more.
137 /// [`par_iter_mut`]: ../struct.IndexMap.html#method.par_iter_mut
138 /// [`IndexMap`]: ../struct.IndexMap.html
139 pub struct ParIterMut
<'a
, K
, V
> {
140 entries
: &'a
mut [Bucket
<K
, V
>],
143 impl<K
: fmt
::Debug
, V
: fmt
::Debug
> fmt
::Debug
for ParIterMut
<'_
, K
, V
> {
144 fn fmt(&self, f
: &mut fmt
::Formatter
<'_
>) -> fmt
::Result
{
145 let iter
= self.entries
.iter().map(Bucket
::refs
);
146 f
.debug_list().entries(iter
).finish()
150 impl<'a
, K
: Sync
+ Send
, V
: Send
> ParallelIterator
for ParIterMut
<'a
, K
, V
> {
151 type Item
= (&'a K
, &'a
mut V
);
153 parallel_iterator_methods
!(Bucket
::ref_mut
);
156 impl<K
: Sync
+ Send
, V
: Send
> IndexedParallelIterator
for ParIterMut
<'_
, K
, V
> {
157 indexed_parallel_iterator_methods
!(Bucket
::ref_mut
);
160 /// Requires crate feature `"rayon"`.
161 impl<'a
, K
, V
, S
> ParallelDrainRange
<usize> for &'a
mut IndexMap
<K
, V
, S
>
167 type Iter
= ParDrain
<'a
, K
, V
>;
169 fn par_drain
<R
: RangeBounds
<usize>>(self, range
: R
) -> Self::Iter
{
171 entries
: self.core
.par_drain(range
),
176 /// A parallel draining iterator over the entries of a `IndexMap`.
178 /// This `struct` is created by the [`par_drain`] method on [`IndexMap`]
179 /// (provided by rayon's `ParallelDrainRange` trait). See its documentation for more.
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
>>,
187 impl<K
: Send
, V
: Send
> ParallelIterator
for ParDrain
<'_
, K
, V
> {
190 parallel_iterator_methods
!(Bucket
::key_value
);
193 impl<K
: Send
, V
: Send
> IndexedParallelIterator
for ParDrain
<'_
, K
, V
> {
194 indexed_parallel_iterator_methods
!(Bucket
::key_value
);
197 /// Parallel iterator methods and other parallel methods.
199 /// The following methods **require crate feature `"rayon"`**.
201 /// See also the `IntoParallelIterator` implementations.
202 impl<K
, V
, S
> IndexMap
<K
, V
, S
>
207 /// Return a parallel iterator over the keys of the map.
209 /// While parallel iterators can process items in any order, their relative order
210 /// in the map is still preserved for operations like `reduce` and `collect`.
211 pub fn par_keys(&self) -> ParKeys
<'_
, K
, V
> {
213 entries
: self.as_entries(),
217 /// Return a parallel iterator over the values of the map.
219 /// While parallel iterators can process items in any order, their relative order
220 /// in the map is still preserved for operations like `reduce` and `collect`.
221 pub fn par_values(&self) -> ParValues
<'_
, K
, V
> {
223 entries
: self.as_entries(),
228 impl<K
, V
, S
> IndexMap
<K
, V
, S
>
234 /// Returns `true` if `self` contains all of the same key-value pairs as `other`,
235 /// regardless of each map's indexed order, determined in parallel.
236 pub fn par_eq
<V2
, S2
>(&self, other
: &IndexMap
<K
, V2
, S2
>) -> bool
240 S2
: BuildHasher
+ Sync
,
242 self.len() == other
.len()
245 .all(move |(key
, value
)| other
.get(key
).map_or(false, |v
| *value
== *v
))
249 /// A parallel iterator over the keys of a `IndexMap`.
251 /// This `struct` is created by the [`par_keys`] method on [`IndexMap`]. See its
252 /// documentation for more.
254 /// [`par_keys`]: ../struct.IndexMap.html#method.par_keys
255 /// [`IndexMap`]: ../struct.IndexMap.html
256 pub struct ParKeys
<'a
, K
, V
> {
257 entries
: &'a
[Bucket
<K
, V
>],
260 impl<K
, V
> Clone
for ParKeys
<'_
, K
, V
> {
261 fn clone(&self) -> Self {
266 impl<K
: fmt
::Debug
, V
> fmt
::Debug
for ParKeys
<'_
, K
, V
> {
267 fn fmt(&self, f
: &mut fmt
::Formatter
<'_
>) -> fmt
::Result
{
268 let iter
= self.entries
.iter().map(Bucket
::key_ref
);
269 f
.debug_list().entries(iter
).finish()
273 impl<'a
, K
: Sync
, V
: Sync
> ParallelIterator
for ParKeys
<'a
, K
, V
> {
276 parallel_iterator_methods
!(Bucket
::key_ref
);
279 impl<K
: Sync
, V
: Sync
> IndexedParallelIterator
for ParKeys
<'_
, K
, V
> {
280 indexed_parallel_iterator_methods
!(Bucket
::key_ref
);
283 /// A parallel iterator over the values of a `IndexMap`.
285 /// This `struct` is created by the [`par_values`] method on [`IndexMap`]. See its
286 /// documentation for more.
288 /// [`par_values`]: ../struct.IndexMap.html#method.par_values
289 /// [`IndexMap`]: ../struct.IndexMap.html
290 pub struct ParValues
<'a
, K
, V
> {
291 entries
: &'a
[Bucket
<K
, V
>],
294 impl<K
, V
> Clone
for ParValues
<'_
, K
, V
> {
295 fn clone(&self) -> Self {
296 ParValues { ..*self }
300 impl<K
, V
: fmt
::Debug
> fmt
::Debug
for ParValues
<'_
, K
, V
> {
301 fn fmt(&self, f
: &mut fmt
::Formatter
<'_
>) -> fmt
::Result
{
302 let iter
= self.entries
.iter().map(Bucket
::value_ref
);
303 f
.debug_list().entries(iter
).finish()
307 impl<'a
, K
: Sync
, V
: Sync
> ParallelIterator
for ParValues
<'a
, K
, V
> {
310 parallel_iterator_methods
!(Bucket
::value_ref
);
313 impl<K
: Sync
, V
: Sync
> IndexedParallelIterator
for ParValues
<'_
, K
, V
> {
314 indexed_parallel_iterator_methods
!(Bucket
::value_ref
);
317 /// Requires crate feature `"rayon"`.
318 impl<K
, V
, S
> IndexMap
<K
, V
, S
>
323 /// Return a parallel iterator over mutable references to the values of the map
325 /// While parallel iterators can process items in any order, their relative order
326 /// in the map is still preserved for operations like `reduce` and `collect`.
327 pub fn par_values_mut(&mut self) -> ParValuesMut
<'_
, K
, V
> {
329 entries
: self.as_entries_mut(),
334 impl<K
, V
, S
> IndexMap
<K
, V
, S
>
340 /// Sort the map’s key-value pairs in parallel, by the default ordering of the keys.
341 pub fn par_sort_keys(&mut self)
345 self.with_entries(|entries
| {
346 entries
.par_sort_by(|a
, b
| K
::cmp(&a
.key
, &b
.key
));
350 /// Sort the map’s key-value pairs in place and in parallel, using the comparison
353 /// The comparison function receives two key and value pairs to compare (you
354 /// can sort by keys or values or their combination as needed).
355 pub fn par_sort_by
<F
>(&mut self, cmp
: F
)
357 F
: Fn(&K
, &V
, &K
, &V
) -> Ordering
+ Sync
,
359 self.with_entries(|entries
| {
360 entries
.par_sort_by(move |a
, b
| cmp(&a
.key
, &a
.value
, &b
.key
, &b
.value
));
364 /// Sort the key-value pairs of the map in parallel and return a by-value parallel
365 /// iterator of the key-value pairs with the result.
366 pub fn par_sorted_by
<F
>(self, cmp
: F
) -> IntoParIter
<K
, V
>
368 F
: Fn(&K
, &V
, &K
, &V
) -> Ordering
+ Sync
,
370 let mut entries
= self.into_entries();
371 entries
.par_sort_by(move |a
, b
| cmp(&a
.key
, &a
.value
, &b
.key
, &b
.value
));
372 IntoParIter { entries }
375 /// Sort the map's key-value pairs in parallel, by the default ordering of the keys.
376 pub fn par_sort_unstable_keys(&mut self)
380 self.with_entries(|entries
| {
381 entries
.par_sort_unstable_by(|a
, b
| K
::cmp(&a
.key
, &b
.key
));
385 /// Sort the map's key-value pairs in place and in parallel, using the comparison
388 /// The comparison function receives two key and value pairs to compare (you
389 /// can sort by keys or values or their combination as needed).
390 pub fn par_sort_unstable_by
<F
>(&mut self, cmp
: F
)
392 F
: Fn(&K
, &V
, &K
, &V
) -> Ordering
+ Sync
,
394 self.with_entries(|entries
| {
395 entries
.par_sort_unstable_by(move |a
, b
| cmp(&a
.key
, &a
.value
, &b
.key
, &b
.value
));
399 /// Sort the key-value pairs of the map in parallel and return a by-value parallel
400 /// iterator of the key-value pairs with the result.
401 pub fn par_sorted_unstable_by
<F
>(self, cmp
: F
) -> IntoParIter
<K
, V
>
403 F
: Fn(&K
, &V
, &K
, &V
) -> Ordering
+ Sync
,
405 let mut entries
= self.into_entries();
406 entries
.par_sort_unstable_by(move |a
, b
| cmp(&a
.key
, &a
.value
, &b
.key
, &b
.value
));
407 IntoParIter { entries }
411 /// A parallel mutable iterator over the values of a `IndexMap`.
413 /// This `struct` is created by the [`par_values_mut`] method on [`IndexMap`]. See its
414 /// documentation for more.
416 /// [`par_values_mut`]: ../struct.IndexMap.html#method.par_values_mut
417 /// [`IndexMap`]: ../struct.IndexMap.html
418 pub struct ParValuesMut
<'a
, K
, V
> {
419 entries
: &'a
mut [Bucket
<K
, V
>],
422 impl<K
, V
: fmt
::Debug
> fmt
::Debug
for ParValuesMut
<'_
, K
, V
> {
423 fn fmt(&self, f
: &mut fmt
::Formatter
<'_
>) -> fmt
::Result
{
424 let iter
= self.entries
.iter().map(Bucket
::value_ref
);
425 f
.debug_list().entries(iter
).finish()
429 impl<'a
, K
: Send
, V
: Send
> ParallelIterator
for ParValuesMut
<'a
, K
, V
> {
430 type Item
= &'a
mut V
;
432 parallel_iterator_methods
!(Bucket
::value_mut
);
435 impl<K
: Send
, V
: Send
> IndexedParallelIterator
for ParValuesMut
<'_
, K
, V
> {
436 indexed_parallel_iterator_methods
!(Bucket
::value_mut
);
439 /// Requires crate feature `"rayon"`.
440 impl<K
, V
, S
> FromParallelIterator
<(K
, V
)> for IndexMap
<K
, V
, S
>
444 S
: BuildHasher
+ Default
+ Send
,
446 fn from_par_iter
<I
>(iter
: I
) -> Self
448 I
: IntoParallelIterator
<Item
= (K
, V
)>,
450 let list
= collect(iter
);
451 let len
= list
.iter().map(Vec
::len
).sum();
452 let mut map
= Self::with_capacity_and_hasher(len
, S
::default());
460 /// Requires crate feature `"rayon"`.
461 impl<K
, V
, S
> ParallelExtend
<(K
, V
)> for IndexMap
<K
, V
, S
>
465 S
: BuildHasher
+ Send
,
467 fn par_extend
<I
>(&mut self, iter
: I
)
469 I
: IntoParallelIterator
<Item
= (K
, V
)>,
471 for vec
in collect(iter
) {
477 /// Requires crate feature `"rayon"`.
478 impl<'a
, K
: 'a
, V
: 'a
, S
> ParallelExtend
<(&'a K
, &'a V
)> for IndexMap
<K
, V
, S
>
480 K
: Copy
+ Eq
+ Hash
+ Send
+ Sync
,
481 V
: Copy
+ Send
+ Sync
,
482 S
: BuildHasher
+ Send
,
484 fn par_extend
<I
>(&mut self, iter
: I
)
486 I
: IntoParallelIterator
<Item
= (&'a K
, &'a V
)>,
488 for vec
in collect(iter
) {
497 use std
::string
::String
;
501 let insert
= [0, 4, 2, 12, 8, 7, 11, 5, 3, 17, 19, 22, 23];
502 let mut map
= IndexMap
::new();
504 for &elt
in &insert
{
508 assert_eq
!(map
.par_keys().count(), map
.len());
509 assert_eq
!(map
.par_keys().count(), insert
.len());
510 insert
.par_iter().zip(map
.par_keys()).for_each(|(a
, b
)| {
517 assert_eq
!(map
.get_index(i
).unwrap().0, k
);
522 fn partial_eq_and_eq() {
523 let mut map_a
= IndexMap
::new();
524 map_a
.insert(1, "1");
525 map_a
.insert(2, "2");
526 let mut map_b
= map_a
.clone();
527 assert
!(map_a
.par_eq(&map_b
));
528 map_b
.swap_remove(&1);
529 assert
!(!map_a
.par_eq(&map_b
));
530 map_b
.insert(3, "3");
531 assert
!(!map_a
.par_eq(&map_b
));
533 let map_c
: IndexMap
<_
, String
> =
534 map_b
.into_par_iter().map(|(k
, v
)| (k
, v
.into())).collect();
535 assert
!(!map_a
.par_eq(&map_c
));
536 assert
!(!map_c
.par_eq(&map_a
));
541 let mut map
= IndexMap
::new();
542 map
.par_extend(vec
![(&1, &2), (&3, &4)]);
543 map
.par_extend(vec
![(5, 6)]);
545 map
.into_par_iter().collect
::<Vec
<_
>>(),
546 vec
![(1, 2), (3, 4), (5, 6)]
552 let vec
= vec
![(1, 'a'
), (2, 'b'
), (3, 'c'
)];
553 let map
: IndexMap
<_
, _
> = vec
.into_par_iter().collect();
554 let keys
: Vec
<_
> = map
.par_keys().copied().collect();
555 assert_eq
!(keys
.len(), 3);
556 assert
!(keys
.contains(&1));
557 assert
!(keys
.contains(&2));
558 assert
!(keys
.contains(&3));
563 let vec
= vec
![(1, 'a'
), (2, 'b'
), (3, 'c'
)];
564 let map
: IndexMap
<_
, _
> = vec
.into_par_iter().collect();
565 let values
: Vec
<_
> = map
.par_values().copied().collect();
566 assert_eq
!(values
.len(), 3);
567 assert
!(values
.contains(&'a'
));
568 assert
!(values
.contains(&'b'
));
569 assert
!(values
.contains(&'c'
));
574 let vec
= vec
![(1, 1), (2, 2), (3, 3)];
575 let mut map
: IndexMap
<_
, _
> = vec
.into_par_iter().collect();
576 map
.par_values_mut().for_each(|value
| *value
*= 2);
577 let values
: Vec
<_
> = map
.par_values().copied().collect();
578 assert_eq
!(values
.len(), 3);
579 assert
!(values
.contains(&2));
580 assert
!(values
.contains(&4));
581 assert
!(values
.contains(&6));