1 use super::noop
::NoopConsumer
;
2 use super::{IntoParallelIterator, ParallelExtend, ParallelIterator}
;
5 use std
::collections
::LinkedList
;
6 use std
::collections
::{BTreeMap, BTreeSet, HashMap, HashSet}
;
7 use std
::collections
::{BinaryHeap, VecDeque}
;
8 use std
::hash
::{BuildHasher, Hash}
;
10 /// Perform a generic `par_extend` by collecting to a `LinkedList<Vec<_>>` in
11 /// parallel, then extending the collection sequentially.
12 fn extend
<C
, I
, F
>(collection
: &mut C
, par_iter
: I
, reserve
: F
)
14 I
: IntoParallelIterator
,
15 F
: FnOnce(&mut C
, &LinkedList
<Vec
<I
::Item
>>),
18 let list
= collect(par_iter
);
19 reserve(collection
, &list
);
21 collection
.extend(vec
);
25 pub(super) fn collect
<I
>(par_iter
: I
) -> LinkedList
<Vec
<I
::Item
>>
27 I
: IntoParallelIterator
,
31 .fold(Vec
::new
, vec_push
)
33 .reduce(LinkedList
::new
, list_append
)
36 fn vec_push
<T
>(mut vec
: Vec
<T
>, elem
: T
) -> Vec
<T
> {
41 fn as_list
<T
>(item
: T
) -> LinkedList
<T
> {
42 let mut list
= LinkedList
::new();
47 fn list_append
<T
>(mut list1
: LinkedList
<T
>, mut list2
: LinkedList
<T
>) -> LinkedList
<T
> {
48 list1
.append(&mut list2
);
52 /// Compute the total length of a `LinkedList<Vec<_>>`.
53 pub(super) fn len
<T
>(list
: &LinkedList
<Vec
<T
>>) -> usize {
54 list
.iter().map(Vec
::len
).sum()
57 fn no_reserve
<C
, T
>(_
: &mut C
, _
: &LinkedList
<Vec
<T
>>) {}
59 fn heap_reserve
<T
: Ord
, U
>(heap
: &mut BinaryHeap
<T
>, list
: &LinkedList
<Vec
<U
>>) {
60 heap
.reserve(len(list
));
63 /// Extend a binary heap with items from a parallel iterator.
64 impl<T
> ParallelExtend
<T
> for BinaryHeap
<T
>
68 fn par_extend
<I
>(&mut self, par_iter
: I
)
70 I
: IntoParallelIterator
<Item
= T
>,
72 extend(self, par_iter
, heap_reserve
);
76 /// Extend a binary heap with copied items from a parallel iterator.
77 impl<'a
, T
> ParallelExtend
<&'a T
> for BinaryHeap
<T
>
79 T
: 'a
+ Copy
+ Ord
+ Send
+ Sync
,
81 fn par_extend
<I
>(&mut self, par_iter
: I
)
83 I
: IntoParallelIterator
<Item
= &'a T
>,
85 extend(self, par_iter
, heap_reserve
);
89 /// Extend a B-tree map with items from a parallel iterator.
90 impl<K
, V
> ParallelExtend
<(K
, V
)> for BTreeMap
<K
, V
>
95 fn par_extend
<I
>(&mut self, par_iter
: I
)
97 I
: IntoParallelIterator
<Item
= (K
, V
)>,
99 extend(self, par_iter
, no_reserve
);
103 /// Extend a B-tree map with copied items from a parallel iterator.
104 impl<'a
, K
: 'a
, V
: 'a
> ParallelExtend
<(&'a K
, &'a V
)> for BTreeMap
<K
, V
>
106 K
: Copy
+ Ord
+ Send
+ Sync
,
107 V
: Copy
+ Send
+ Sync
,
109 fn par_extend
<I
>(&mut self, par_iter
: I
)
111 I
: IntoParallelIterator
<Item
= (&'a K
, &'a V
)>,
113 extend(self, par_iter
, no_reserve
);
117 /// Extend a B-tree set with items from a parallel iterator.
118 impl<T
> ParallelExtend
<T
> for BTreeSet
<T
>
122 fn par_extend
<I
>(&mut self, par_iter
: I
)
124 I
: IntoParallelIterator
<Item
= T
>,
126 extend(self, par_iter
, no_reserve
);
130 /// Extend a B-tree set with copied items from a parallel iterator.
131 impl<'a
, T
> ParallelExtend
<&'a T
> for BTreeSet
<T
>
133 T
: 'a
+ Copy
+ Ord
+ Send
+ Sync
,
135 fn par_extend
<I
>(&mut self, par_iter
: I
)
137 I
: IntoParallelIterator
<Item
= &'a T
>,
139 extend(self, par_iter
, no_reserve
);
143 fn map_reserve
<K
, V
, S
, U
>(map
: &mut HashMap
<K
, V
, S
>, list
: &LinkedList
<Vec
<U
>>)
148 map
.reserve(len(list
));
151 /// Extend a hash map with items from a parallel iterator.
152 impl<K
, V
, S
> ParallelExtend
<(K
, V
)> for HashMap
<K
, V
, S
>
156 S
: BuildHasher
+ Send
,
158 fn par_extend
<I
>(&mut self, par_iter
: I
)
160 I
: IntoParallelIterator
<Item
= (K
, V
)>,
162 // See the map_collect benchmarks in rayon-demo for different strategies.
163 extend(self, par_iter
, map_reserve
);
167 /// Extend a hash map with copied items from a parallel iterator.
168 impl<'a
, K
: 'a
, V
: 'a
, S
> ParallelExtend
<(&'a K
, &'a V
)> for HashMap
<K
, V
, S
>
170 K
: Copy
+ Eq
+ Hash
+ Send
+ Sync
,
171 V
: Copy
+ Send
+ Sync
,
172 S
: BuildHasher
+ Send
,
174 fn par_extend
<I
>(&mut self, par_iter
: I
)
176 I
: IntoParallelIterator
<Item
= (&'a K
, &'a V
)>,
178 extend(self, par_iter
, map_reserve
);
182 fn set_reserve
<T
, S
, U
>(set
: &mut HashSet
<T
, S
>, list
: &LinkedList
<Vec
<U
>>)
187 set
.reserve(len(list
));
190 /// Extend a hash set with items from a parallel iterator.
191 impl<T
, S
> ParallelExtend
<T
> for HashSet
<T
, S
>
194 S
: BuildHasher
+ Send
,
196 fn par_extend
<I
>(&mut self, par_iter
: I
)
198 I
: IntoParallelIterator
<Item
= T
>,
200 extend(self, par_iter
, set_reserve
);
204 /// Extend a hash set with copied items from a parallel iterator.
205 impl<'a
, T
, S
> ParallelExtend
<&'a T
> for HashSet
<T
, S
>
207 T
: 'a
+ Copy
+ Eq
+ Hash
+ Send
+ Sync
,
208 S
: BuildHasher
+ Send
,
210 fn par_extend
<I
>(&mut self, par_iter
: I
)
212 I
: IntoParallelIterator
<Item
= &'a T
>,
214 extend(self, par_iter
, set_reserve
);
218 fn list_push_back
<T
>(mut list
: LinkedList
<T
>, elem
: T
) -> LinkedList
<T
> {
219 list
.push_back(elem
);
223 /// Extend a linked list with items from a parallel iterator.
224 impl<T
> ParallelExtend
<T
> for LinkedList
<T
>
228 fn par_extend
<I
>(&mut self, par_iter
: I
)
230 I
: IntoParallelIterator
<Item
= T
>,
232 let mut list
= par_iter
234 .fold(LinkedList
::new
, list_push_back
)
235 .reduce(LinkedList
::new
, list_append
);
236 self.append(&mut list
);
240 /// Extend a linked list with copied items from a parallel iterator.
241 impl<'a
, T
> ParallelExtend
<&'a T
> for LinkedList
<T
>
243 T
: 'a
+ Copy
+ Send
+ Sync
,
245 fn par_extend
<I
>(&mut self, par_iter
: I
)
247 I
: IntoParallelIterator
<Item
= &'a T
>,
249 self.par_extend(par_iter
.into_par_iter().cloned())
253 fn string_push(mut string
: String
, ch
: char) -> String
{
258 /// Extend a string with characters from a parallel iterator.
259 impl ParallelExtend
<char> for String
{
260 fn par_extend
<I
>(&mut self, par_iter
: I
)
262 I
: IntoParallelIterator
<Item
= char>,
264 // This is like `extend`, but `Vec<char>` is less efficient to deal
265 // with than `String`, so instead collect to `LinkedList<String>`.
266 let list
: LinkedList
<_
> = par_iter
268 .fold(String
::new
, string_push
)
270 .reduce(LinkedList
::new
, list_append
);
272 self.reserve(list
.iter().map(String
::len
).sum());
277 /// Extend a string with copied characters from a parallel iterator.
278 impl<'a
> ParallelExtend
<&'a
char> for String
{
279 fn par_extend
<I
>(&mut self, par_iter
: I
)
281 I
: IntoParallelIterator
<Item
= &'a
char>,
283 self.par_extend(par_iter
.into_par_iter().cloned())
287 fn string_reserve
<T
: AsRef
<str>>(string
: &mut String
, list
: &LinkedList
<Vec
<T
>>) {
297 /// Extend a string with string slices from a parallel iterator.
298 impl<'a
> ParallelExtend
<&'a
str> for String
{
299 fn par_extend
<I
>(&mut self, par_iter
: I
)
301 I
: IntoParallelIterator
<Item
= &'a
str>,
303 extend(self, par_iter
, string_reserve
);
307 /// Extend a string with strings from a parallel iterator.
308 impl ParallelExtend
<String
> for String
{
309 fn par_extend
<I
>(&mut self, par_iter
: I
)
311 I
: IntoParallelIterator
<Item
= String
>,
313 extend(self, par_iter
, string_reserve
);
317 /// Extend a string with string slices from a parallel iterator.
318 impl<'a
> ParallelExtend
<Cow
<'a
, str>> for String
{
319 fn par_extend
<I
>(&mut self, par_iter
: I
)
321 I
: IntoParallelIterator
<Item
= Cow
<'a
, str>>,
323 extend(self, par_iter
, string_reserve
);
327 fn deque_reserve
<T
, U
>(deque
: &mut VecDeque
<T
>, list
: &LinkedList
<Vec
<U
>>) {
328 deque
.reserve(len(list
));
331 /// Extend a deque with items from a parallel iterator.
332 impl<T
> ParallelExtend
<T
> for VecDeque
<T
>
336 fn par_extend
<I
>(&mut self, par_iter
: I
)
338 I
: IntoParallelIterator
<Item
= T
>,
340 extend(self, par_iter
, deque_reserve
);
344 /// Extend a deque with copied items from a parallel iterator.
345 impl<'a
, T
> ParallelExtend
<&'a T
> for VecDeque
<T
>
347 T
: 'a
+ Copy
+ Send
+ Sync
,
349 fn par_extend
<I
>(&mut self, par_iter
: I
)
351 I
: IntoParallelIterator
<Item
= &'a T
>,
353 extend(self, par_iter
, deque_reserve
);
357 // See the `collect` module for the `Vec<T>` implementation.
358 // impl<T> ParallelExtend<T> for Vec<T>
360 /// Extend a vector with copied items from a parallel iterator.
361 impl<'a
, T
> ParallelExtend
<&'a T
> for Vec
<T
>
363 T
: 'a
+ Copy
+ Send
+ Sync
,
365 fn par_extend
<I
>(&mut self, par_iter
: I
)
367 I
: IntoParallelIterator
<Item
= &'a T
>,
369 self.par_extend(par_iter
.into_par_iter().cloned())
373 /// Collapses all unit items from a parallel iterator into one.
374 impl ParallelExtend
<()> for () {
375 fn par_extend
<I
>(&mut self, par_iter
: I
)
377 I
: IntoParallelIterator
<Item
= ()>,
379 par_iter
.into_par_iter().drive_unindexed(NoopConsumer
)