1
1
use std:: sync:: mpsc:: { self , Sender , Receiver } ;
2
- use std:: thread:: { self , JoinGuard } ;
3
2
use std:: cmp:: Ordering ;
4
3
use std:: collections:: BinaryHeap ;
5
4
use std:: iter:: IntoIterator ;
6
5
6
+ use crossbeam:: { Scope , ScopedJoinHandle } ;
7
+
7
8
struct Packet < T > {
8
9
// this should be unique for a given instance of `*ParMap`
9
10
idx : usize ,
@@ -25,12 +26,12 @@ impl<T> Eq for Packet<T> {}
25
26
26
27
/// A parallel-mapping iterator that doesn't care about the order in
27
28
/// which elements come out.
28
- pub struct UnorderedParMap < ' a , T : ' a + Send > {
29
+ pub struct UnorderedParMap < T : Send > {
29
30
rx : Receiver < Packet < T > > ,
30
- _guards : Vec < JoinGuard < ' a , ( ) > >
31
+ _guards : Vec < ScopedJoinHandle < ( ) > >
31
32
}
32
33
33
- impl < ' a , T : ' static + Send > Iterator for UnorderedParMap < ' a , T > {
34
+ impl < T : ' static + Send > Iterator for UnorderedParMap < T > {
34
35
type Item = ( usize , T ) ;
35
36
36
37
fn next ( & mut self ) -> Option < ( usize , T ) > {
@@ -62,9 +63,9 @@ impl<T: Send + 'static> Drop for Panicker<T> {
62
63
/// This behaves like `simple_parallel::map`, but does not make
63
64
/// efforts to ensure that the elements are returned in the order of
64
65
/// `iter`, hence this is cheaper.
65
- pub fn unordered_map < ' a , I : IntoIterator , F , T > ( iter : I , f : & ' a F ) -> UnorderedParMap < ' a , T >
66
+ pub fn unordered_map < ' a , I : IntoIterator , F , T > ( scope : & Scope < ' a > , iter : I , f : & ' a F ) -> UnorderedParMap < T >
66
67
where I :: Item : Send + ' a ,
67
- F : ' a + Sync + Fn ( I :: Item ) -> T ,
68
+ F : Sync + Fn ( I :: Item ) -> T ,
68
69
T : Send + ' static
69
70
{
70
71
let ( tx, rx) = mpsc:: channel ( ) ;
@@ -73,7 +74,7 @@ pub fn unordered_map<'a, I: IntoIterator, F, T>(iter: I, f: &'a F) -> UnorderedP
73
74
let tx = tx. clone ( ) ;
74
75
let f = f. clone ( ) ;
75
76
76
- thread :: scoped ( move || {
77
+ scope . spawn ( move || {
77
78
let mut p = Panicker { tx : tx, idx : idx, all_ok : false } ;
78
79
let val = f ( elem) ;
79
80
let _ = p. tx . send ( Packet { idx : idx, data : Some ( val) } ) ;
@@ -88,13 +89,13 @@ pub fn unordered_map<'a, I: IntoIterator, F, T>(iter: I, f: &'a F) -> UnorderedP
88
89
}
89
90
90
91
/// A parallel-mapping iterator.
91
- pub struct ParMap < ' a , T : ' a + Send > {
92
- unordered : UnorderedParMap < ' a , T > ,
92
+ pub struct ParMap < T : Send > {
93
+ unordered : UnorderedParMap < T > ,
93
94
looking_for : usize ,
94
95
queue : BinaryHeap < Packet < T > >
95
96
}
96
97
97
- impl < ' a , T : Send + ' static > Iterator for ParMap < ' a , T > {
98
+ impl < T : Send + ' static > Iterator for ParMap < T > {
98
99
type Item = T ;
99
100
100
101
fn next ( & mut self ) -> Option < T > {
@@ -127,13 +128,13 @@ impl<'a, T: Send + 'static> Iterator for ParMap<'a, T> {
127
128
/// This is a drop-in replacement for `iter.map(f)`, that runs in
128
129
/// parallel, and eagerly consumes `iter` spawning a thread for each
129
130
/// element.
130
- pub fn map < ' a , I : IntoIterator , F , T > ( iter : I , f : & ' a F ) -> ParMap < ' a , T >
131
- where I :: Item : Send + ' a ,
132
- F : ' a + Sync + Fn ( I :: Item ) -> T ,
131
+ pub fn map < ' a , I : IntoIterator , F , T > ( scope : & Scope < ' a > , iter : I , f : & ' a F ) -> ParMap < T >
132
+ where I :: Item : ' a + Send ,
133
+ F : Sync + Fn ( I :: Item ) -> T ,
133
134
T : Send + ' static
134
135
{
135
136
ParMap {
136
- unordered : unordered_map ( iter, f) ,
137
+ unordered : unordered_map ( scope , iter, f) ,
137
138
looking_for : 0 ,
138
139
queue : BinaryHeap :: new ( ) ,
139
140
}
0 commit comments