@@ -4,7 +4,7 @@ import comm::send;
4
4
import comm:: recv;
5
5
import future:: future;
6
6
7
- export map, mapi, alli, any;
7
+ export map, mapi, alli, any, mapi_factory ;
8
8
9
9
#[ doc="The maximum number of tasks this module will spawn for a single
10
10
operationg." ]
@@ -18,15 +18,16 @@ return the intermediate results.
18
18
19
19
This is used to build most of the other parallel vector functions,
20
20
like map or alli." ]
21
- fn map_slices < A : copy send, B : copy send> ( xs : [ A ] ,
22
- f : fn ~( uint , [ const A ] /& ) -> B )
21
+ fn map_slices < A : copy send, B : copy send> (
22
+ xs : [ A ] ,
23
+ f : fn ( ) -> fn ~( uint , [ const A ] /& ) -> B )
23
24
-> [ B ] {
24
25
25
26
let len = xs. len ( ) ;
26
27
if len < min_granularity {
27
28
log ( info, "small slice" ) ;
28
29
// This is a small vector, fall back on the normal map.
29
- [ f ( 0 u, xs) ]
30
+ [ f ( ) ( 0 u, xs) ]
30
31
}
31
32
else {
32
33
let num_tasks = uint:: min ( max_tasks, len / min_granularity) ;
@@ -40,7 +41,7 @@ fn map_slices<A: copy send, B: copy send>(xs: [A],
40
41
let end = uint:: min ( len, base + items_per_task) ;
41
42
// FIXME: why is the ::<A, ()> annotation required here?
42
43
vec:: unpack_slice :: < A , ( ) > ( xs) { |p, _len|
43
- let f = ptr :: addr_of ( f ) ;
44
+ let f = f ( ) ;
44
45
futures += [ future:: spawn ( ) { |copy base|
45
46
unsafe {
46
47
let len = end - base;
@@ -52,7 +53,7 @@ fn map_slices<A: copy send, B: copy send>(xs: [A],
52
53
log ( info, #fmt ( "slice: %?" ,
53
54
( base, vec:: len ( slice) , end - base) ) ) ;
54
55
assert ( vec:: len ( slice) == end - base) ;
55
- ( * f ) ( base, slice)
56
+ f ( base, slice)
56
57
}
57
58
} ] ;
58
59
} ;
@@ -73,16 +74,40 @@ fn map_slices<A: copy send, B: copy send>(xs: [A],
73
74
74
75
#[ doc="A parallel version of map." ]
75
76
fn map < A : copy send, B : copy send> ( xs : [ A ] , f : fn ~( A ) -> B ) -> [ B ] {
76
- vec:: concat ( map_slices ( xs) { |_base, slice|
77
- vec:: map ( slice, f)
77
+ vec:: concat ( map_slices ( xs) { ||
78
+ fn ~( _base: uint, slice : [ const A ] /& ) -> [ B ] {
79
+ vec:: map ( slice, f)
80
+ }
78
81
} )
79
82
}
80
83
81
84
#[ doc="A parallel version of mapi." ]
82
85
fn mapi < A : copy send, B : copy send> ( xs : [ A ] , f : fn ~( uint , A ) -> B ) -> [ B ] {
83
- let slices = map_slices ( xs) { |base, slice|
84
- vec:: mapi ( slice) { |i, x|
85
- f ( i + base, x)
86
+ let slices = map_slices ( xs) { ||
87
+ fn~( base: uint, slice : [ const A ] /& ) -> [ B ] {
88
+ vec:: mapi ( slice) { |i, x|
89
+ f ( i + base, x)
90
+ }
91
+ }
92
+ } ;
93
+ let r = vec:: concat ( slices) ;
94
+ log ( info, ( r. len ( ) , xs. len ( ) ) ) ;
95
+ assert ( r. len ( ) == xs. len ( ) ) ;
96
+ r
97
+ }
98
+
99
+ #[ doc="A parallel version of mapi.
100
+
101
+ In this case, f is a function that creates functions to run over the
102
+ inner elements. This is to skirt the need for copy constructors." ]
103
+ fn mapi_factory < A : copy send, B : copy send> (
104
+ xs : [ A ] , f : fn ( ) -> fn ~( uint , A ) -> B ) -> [ B ] {
105
+ let slices = map_slices ( xs) { ||
106
+ let f = f ( ) ;
107
+ fn ~( base: uint, slice : [ const A ] /& ) -> [ B ] {
108
+ vec:: mapi ( slice ) { |i, x|
109
+ f ( i + base, x)
110
+ }
86
111
}
87
112
} ;
88
113
let r = vec:: concat ( slices) ;
@@ -93,16 +118,16 @@ fn mapi<A: copy send, B: copy send>(xs: [A], f: fn~(uint, A) -> B) -> [B] {
93
118
94
119
#[ doc="Returns true if the function holds for all elements in the vector." ]
95
120
fn alli< A : copy send> ( xs : [ A ] , f : fn ~( uint , A ) -> bool ) -> bool {
96
- vec:: all ( map_slices ( xs) { |base, slice|
121
+ vec:: all( map_slices ( xs) { || fn ~ ( base: uint , slice : [ const A ] / & ) -> bool {
97
122
vec:: alli ( slice) { |i, x|
98
123
f ( i + base, x)
99
124
}
100
- } ) { |x| x }
125
+ } } ) { |x| x }
101
126
}
102
127
103
128
#[ doc="Returns true if the function holds for any elements in the vector." ]
104
129
fn any<A : copy send>( xs: [ A ] , f : fn ~( A ) -> bool) -> bool {
105
- vec:: any ( map_slices ( xs) { |_base, slice|
130
+ vec:: any( map_slices ( xs) { || fn ~ ( _base : uint , slice: [ const A ] / & ) -> bool {
106
131
vec:: any ( slice, f)
107
- } ) { |x| x }
132
+ } } ) { |x| x }
108
133
}
0 commit comments