@@ -14,41 +14,49 @@ where
14
14
F : FnOnce ( & mut C , & LinkedList < Vec < I :: Item > > ) ,
15
15
C : Extend < I :: Item > ,
16
16
{
17
- let list = par_iter
18
- . into_par_iter ( )
19
- . fold ( Vec :: new, |mut vec, elem| {
20
- vec. push ( elem) ;
21
- vec
22
- } )
23
- . map ( |vec| {
24
- let mut list = LinkedList :: new ( ) ;
25
- list. push_back ( vec) ;
26
- list
27
- } )
28
- . reduce ( LinkedList :: new, |mut list1, mut list2| {
29
- list1. append ( & mut list2) ;
30
- list1
31
- } ) ;
32
-
17
+ let list = collect ( par_iter) ;
33
18
reserve ( collection, & list) ;
34
19
for vec in list {
35
20
collection. extend ( vec) ;
36
21
}
37
22
}
38
23
24
+ pub ( super ) fn collect < I > ( par_iter : I ) -> LinkedList < Vec < I :: Item > >
25
+ where
26
+ I : IntoParallelIterator ,
27
+ {
28
+ par_iter
29
+ . into_par_iter ( )
30
+ . fold ( Vec :: new, vec_push)
31
+ . map ( as_list)
32
+ . reduce ( LinkedList :: new, list_append)
33
+ }
34
+
35
+ fn vec_push < T > ( mut vec : Vec < T > , elem : T ) -> Vec < T > {
36
+ vec. push ( elem) ;
37
+ vec
38
+ }
39
+
40
+ fn as_list < T > ( item : T ) -> LinkedList < T > {
41
+ let mut list = LinkedList :: new ( ) ;
42
+ list. push_back ( item) ;
43
+ list
44
+ }
45
+
46
+ fn list_append < T > ( mut list1 : LinkedList < T > , ref mut list2: LinkedList < T > ) -> LinkedList < T > {
47
+ list1. append ( list2) ;
48
+ list1
49
+ }
50
+
39
51
/// Compute the total length of a `LinkedList<Vec<_>>`.
40
- fn len < T > ( list : & LinkedList < Vec < T > > ) -> usize {
52
+ pub ( super ) fn len < T > ( list : & LinkedList < Vec < T > > ) -> usize {
41
53
list. iter ( ) . map ( Vec :: len) . sum ( )
42
54
}
43
55
44
- /// Compute the total string length of a `LinkedList<Vec<AsRef<str>>>`.
45
- fn str_len < T > ( list : & LinkedList < Vec < T > > ) -> usize
46
- where
47
- T : AsRef < str > ,
48
- {
49
- list. iter ( )
50
- . flat_map ( |vec| vec. iter ( ) . map ( |s| s. as_ref ( ) . len ( ) ) )
51
- . sum ( )
56
+ fn no_reserve < C , T > ( _: & mut C , _: & LinkedList < Vec < T > > ) { }
57
+
58
+ fn heap_reserve < T : Ord , U > ( heap : & mut BinaryHeap < T > , list : & LinkedList < Vec < U > > ) {
59
+ heap. reserve ( len ( list) ) ;
52
60
}
53
61
54
62
/// Extend a binary heap with items from a parallel iterator.
60
68
where
61
69
I : IntoParallelIterator < Item = T > ,
62
70
{
63
- extend ( self , par_iter, |heap , list| heap . reserve ( len ( list ) ) ) ;
71
+ extend ( self , par_iter, heap_reserve ) ;
64
72
}
65
73
}
66
74
73
81
where
74
82
I : IntoParallelIterator < Item = & ' a T > ,
75
83
{
76
- extend ( self , par_iter, |heap , list| heap . reserve ( len ( list ) ) ) ;
84
+ extend ( self , par_iter, heap_reserve ) ;
77
85
}
78
86
}
79
87
@@ -87,12 +95,12 @@ where
87
95
where
88
96
I : IntoParallelIterator < Item = ( K , V ) > ,
89
97
{
90
- extend ( self , par_iter, |_ , _| { } ) ;
98
+ extend ( self , par_iter, no_reserve ) ;
91
99
}
92
100
}
93
101
94
102
/// Extend a B-tree map with copied items from a parallel iterator.
95
- impl < ' a , K , V > ParallelExtend < ( & ' a K , & ' a V ) > for BTreeMap < K , V >
103
+ impl < ' a , K : ' a , V : ' a > ParallelExtend < ( & ' a K , & ' a V ) > for BTreeMap < K , V >
96
104
where
97
105
K : Copy + Ord + Send + Sync ,
98
106
V : Copy + Send + Sync ,
@@ -101,7 +109,7 @@ where
101
109
where
102
110
I : IntoParallelIterator < Item = ( & ' a K , & ' a V ) > ,
103
111
{
104
- extend ( self , par_iter, |_ , _| { } ) ;
112
+ extend ( self , par_iter, no_reserve ) ;
105
113
}
106
114
}
107
115
@@ -114,7 +122,7 @@ where
114
122
where
115
123
I : IntoParallelIterator < Item = T > ,
116
124
{
117
- extend ( self , par_iter, |_ , _| { } ) ;
125
+ extend ( self , par_iter, no_reserve ) ;
118
126
}
119
127
}
120
128
@@ -127,10 +135,18 @@ where
127
135
where
128
136
I : IntoParallelIterator < Item = & ' a T > ,
129
137
{
130
- extend ( self , par_iter, |_ , _| { } ) ;
138
+ extend ( self , par_iter, no_reserve ) ;
131
139
}
132
140
}
133
141
142
+ fn map_reserve < K , V , S , U > ( map : & mut HashMap < K , V , S > , list : & LinkedList < Vec < U > > )
143
+ where
144
+ K : Eq + Hash ,
145
+ S : BuildHasher ,
146
+ {
147
+ map. reserve ( len ( list) ) ;
148
+ }
149
+
134
150
/// Extend a hash map with items from a parallel iterator.
135
151
impl < K , V , S > ParallelExtend < ( K , V ) > for HashMap < K , V , S >
136
152
where
@@ -143,12 +159,12 @@ where
143
159
I : IntoParallelIterator < Item = ( K , V ) > ,
144
160
{
145
161
// See the map_collect benchmarks in rayon-demo for different strategies.
146
- extend ( self , par_iter, |map , list| map . reserve ( len ( list ) ) ) ;
162
+ extend ( self , par_iter, map_reserve ) ;
147
163
}
148
164
}
149
165
150
166
/// Extend a hash map with copied items from a parallel iterator.
151
- impl < ' a , K , V , S > ParallelExtend < ( & ' a K , & ' a V ) > for HashMap < K , V , S >
167
+ impl < ' a , K : ' a , V : ' a , S > ParallelExtend < ( & ' a K , & ' a V ) > for HashMap < K , V , S >
152
168
where
153
169
K : Copy + Eq + Hash + Send + Sync ,
154
170
V : Copy + Send + Sync ,
@@ -158,10 +174,18 @@ where
158
174
where
159
175
I : IntoParallelIterator < Item = ( & ' a K , & ' a V ) > ,
160
176
{
161
- extend ( self , par_iter, |map , list| map . reserve ( len ( list ) ) ) ;
177
+ extend ( self , par_iter, map_reserve ) ;
162
178
}
163
179
}
164
180
181
+ fn set_reserve < T , S , U > ( set : & mut HashSet < T , S > , list : & LinkedList < Vec < U > > )
182
+ where
183
+ T : Eq + Hash ,
184
+ S : BuildHasher ,
185
+ {
186
+ set. reserve ( len ( list) ) ;
187
+ }
188
+
165
189
/// Extend a hash set with items from a parallel iterator.
166
190
impl < T , S > ParallelExtend < T > for HashSet < T , S >
167
191
where
@@ -172,7 +196,7 @@ where
172
196
where
173
197
I : IntoParallelIterator < Item = T > ,
174
198
{
175
- extend ( self , par_iter, |set , list| set . reserve ( len ( list ) ) ) ;
199
+ extend ( self , par_iter, set_reserve ) ;
176
200
}
177
201
}
178
202
@@ -186,10 +210,15 @@ where
186
210
where
187
211
I : IntoParallelIterator < Item = & ' a T > ,
188
212
{
189
- extend ( self , par_iter, |set , list| set . reserve ( len ( list ) ) ) ;
213
+ extend ( self , par_iter, set_reserve ) ;
190
214
}
191
215
}
192
216
217
+ fn list_push_back < T > ( mut list : LinkedList < T > , elem : T ) -> LinkedList < T > {
218
+ list. push_back ( elem) ;
219
+ list
220
+ }
221
+
193
222
/// Extend a linked list with items from a parallel iterator.
194
223
impl < T > ParallelExtend < T > for LinkedList < T >
195
224
where
@@ -201,14 +230,8 @@ where
201
230
{
202
231
let mut list = par_iter
203
232
. into_par_iter ( )
204
- . fold ( LinkedList :: new, |mut list, elem| {
205
- list. push_back ( elem) ;
206
- list
207
- } )
208
- . reduce ( LinkedList :: new, |mut list1, mut list2| {
209
- list1. append ( & mut list2) ;
210
- list1
211
- } ) ;
233
+ . fold ( LinkedList :: new, list_push_back)
234
+ . reduce ( LinkedList :: new, list_append) ;
212
235
self . append ( & mut list) ;
213
236
}
214
237
}
@@ -226,6 +249,11 @@ where
226
249
}
227
250
}
228
251
252
+ fn string_push ( mut string : String , ch : char ) -> String {
253
+ string. push ( ch) ;
254
+ string
255
+ }
256
+
229
257
/// Extend a string with characters from a parallel iterator.
230
258
impl ParallelExtend < char > for String {
231
259
fn par_extend < I > ( & mut self , par_iter : I )
@@ -236,19 +264,9 @@ impl ParallelExtend<char> for String {
236
264
// with than `String`, so instead collect to `LinkedList<String>`.
237
265
let list: LinkedList < _ > = par_iter
238
266
. into_par_iter ( )
239
- . fold ( String :: new, |mut string, ch| {
240
- string. push ( ch) ;
241
- string
242
- } )
243
- . map ( |vec| {
244
- let mut list = LinkedList :: new ( ) ;
245
- list. push_back ( vec) ;
246
- list
247
- } )
248
- . reduce ( LinkedList :: new, |mut list1, mut list2| {
249
- list1. append ( & mut list2) ;
250
- list1
251
- } ) ;
267
+ . fold ( String :: new, string_push)
268
+ . map ( as_list)
269
+ . reduce ( LinkedList :: new, list_append) ;
252
270
253
271
self . reserve ( list. iter ( ) . map ( String :: len) . sum ( ) ) ;
254
272
self . extend ( list)
@@ -265,13 +283,23 @@ impl<'a> ParallelExtend<&'a char> for String {
265
283
}
266
284
}
267
285
286
+ fn string_reserve < T : AsRef < str > > ( string : & mut String , list : & LinkedList < Vec < T > > ) {
287
+ let len = list
288
+ . iter ( )
289
+ . flat_map ( |vec| vec)
290
+ . map ( T :: as_ref)
291
+ . map ( str:: len)
292
+ . sum ( ) ;
293
+ string. reserve ( len) ;
294
+ }
295
+
268
296
/// Extend a string with string slices from a parallel iterator.
269
297
impl < ' a > ParallelExtend < & ' a str > for String {
270
298
fn par_extend < I > ( & mut self , par_iter : I )
271
299
where
272
300
I : IntoParallelIterator < Item = & ' a str > ,
273
301
{
274
- extend ( self , par_iter, |string , list| string . reserve ( str_len ( list ) ) ) ;
302
+ extend ( self , par_iter, string_reserve ) ;
275
303
}
276
304
}
277
305
@@ -281,7 +309,7 @@ impl ParallelExtend<String> for String {
281
309
where
282
310
I : IntoParallelIterator < Item = String > ,
283
311
{
284
- extend ( self , par_iter, |string , list| string . reserve ( str_len ( list ) ) ) ;
312
+ extend ( self , par_iter, string_reserve ) ;
285
313
}
286
314
}
287
315
@@ -291,31 +319,14 @@ impl<'a> ParallelExtend<Cow<'a, str>> for String {
291
319
where
292
320
I : IntoParallelIterator < Item = Cow < ' a , str > > ,
293
321
{
294
- // This is like `extend`, but `Extend<Cow<'a, str>> for String`
295
- // wasn't added until Rust 1.19, so we can't use it directly yet.
296
- let list = par_iter
297
- . into_par_iter ( )
298
- . fold ( Vec :: new, |mut vec, elem| {
299
- vec. push ( elem) ;
300
- vec
301
- } )
302
- . map ( |vec| {
303
- let mut list = LinkedList :: new ( ) ;
304
- list. push_back ( vec) ;
305
- list
306
- } )
307
- . reduce ( LinkedList :: new, |mut list1, mut list2| {
308
- list1. append ( & mut list2) ;
309
- list1
310
- } ) ;
311
-
312
- self . reserve ( str_len ( & list) ) ;
313
- for vec in list {
314
- self . extend ( vec. iter ( ) . map ( |cow| & * * cow) ) ;
315
- }
322
+ extend ( self , par_iter, string_reserve) ;
316
323
}
317
324
}
318
325
326
+ fn deque_reserve < T , U > ( deque : & mut VecDeque < T > , list : & LinkedList < Vec < U > > ) {
327
+ deque. reserve ( len ( list) ) ;
328
+ }
329
+
319
330
/// Extend a deque with items from a parallel iterator.
320
331
impl < T > ParallelExtend < T > for VecDeque < T >
321
332
where
@@ -325,7 +336,7 @@ where
325
336
where
326
337
I : IntoParallelIterator < Item = T > ,
327
338
{
328
- extend ( self , par_iter, |deque , list| deque . reserve ( len ( list ) ) ) ;
339
+ extend ( self , par_iter, deque_reserve ) ;
329
340
}
330
341
}
331
342
@@ -338,7 +349,7 @@ where
338
349
where
339
350
I : IntoParallelIterator < Item = & ' a T > ,
340
351
{
341
- extend ( self , par_iter, |deque , list| deque . reserve ( len ( list ) ) ) ;
352
+ extend ( self , par_iter, deque_reserve ) ;
342
353
}
343
354
}
344
355
0 commit comments