indexmap/rayon/
mod.rs

1use rayon::prelude::*;
2
3#[cfg(not(feature = "std"))]
4use alloc::collections::LinkedList;
5
6#[cfg(feature = "std")]
7use std::collections::LinkedList;
8
9use crate::vec::Vec;
10
11// generate `ParallelIterator` methods by just forwarding to the underlying
12// self.entries and mapping its elements.
13macro_rules! parallel_iterator_methods {
14    // $map_elt is the mapping function from the underlying iterator's element
15    ($map_elt:expr) => {
16        fn drive_unindexed<C>(self, consumer: C) -> C::Result
17        where
18            C: UnindexedConsumer<Self::Item>,
19        {
20            self.entries
21                .into_par_iter()
22                .map($map_elt)
23                .drive_unindexed(consumer)
24        }
25
26        // NB: This allows indexed collection, e.g. directly into a `Vec`, but the
27        // underlying iterator must really be indexed.  We should remove this if we
28        // start having tombstones that must be filtered out.
29        fn opt_len(&self) -> Option<usize> {
30            Some(self.entries.len())
31        }
32    };
33}
34
35// generate `IndexedParallelIterator` methods by just forwarding to the underlying
36// self.entries and mapping its elements.
37macro_rules! indexed_parallel_iterator_methods {
38    // $map_elt is the mapping function from the underlying iterator's element
39    ($map_elt:expr) => {
40        fn drive<C>(self, consumer: C) -> C::Result
41        where
42            C: Consumer<Self::Item>,
43        {
44            self.entries.into_par_iter().map($map_elt).drive(consumer)
45        }
46
47        fn len(&self) -> usize {
48            self.entries.len()
49        }
50
51        fn with_producer<CB>(self, callback: CB) -> CB::Output
52        where
53            CB: ProducerCallback<Self::Item>,
54        {
55            self.entries
56                .into_par_iter()
57                .map($map_elt)
58                .with_producer(callback)
59        }
60    };
61}
62
63pub mod map;
64pub mod set;
65
66// This form of intermediate collection is also how Rayon collects `HashMap`.
67// Note that the order will also be preserved!
68fn collect<I: IntoParallelIterator>(iter: I) -> LinkedList<Vec<I::Item>> {
69    iter.into_par_iter()
70        .fold(Vec::new, |mut vec, elem| {
71            vec.push(elem);
72            vec
73        })
74        .map(|vec| {
75            let mut list = LinkedList::new();
76            list.push_back(vec);
77            list
78        })
79        .reduce(LinkedList::new, |mut list1, mut list2| {
80            list1.append(&mut list2);
81            list1
82        })
83}