@@ -20,7 +20,6 @@ extern mod extra;
20
20
use extra:: arc;
21
21
use extra:: time;
22
22
use extra:: deque:: Deque ;
23
- use extra:: par;
24
23
use std:: hashmap:: HashSet ;
25
24
use std:: int:: abs;
26
25
use std:: io;
@@ -34,6 +33,144 @@ type node_id = i64;
34
33
type graph = ~[ ~[ node_id ] ] ;
35
34
type bfs_result = ~[ node_id ] ;
36
35
36
+ // Moved from extra::par
37
+ mod par {
38
+ use std:: cast;
39
+ use std:: ptr;
40
+ use std:: sys;
41
+ use std:: uint;
42
+ use std:: vec;
43
+ use extra:: future;
44
+
45
+ /**
46
+ * The maximum number of tasks this module will spawn for a single
47
+ * operation.
48
+ */
49
+ static max_tasks : uint = 32 u;
50
+
51
+ /// The minimum number of elements each task will process.
52
+ static min_granularity : uint = 1024 u;
53
+
54
+ /**
55
+ * An internal helper to map a function over a large vector and
56
+ * return the intermediate results.
57
+ *
58
+ * This is used to build most of the other parallel vector functions,
59
+ * like map or alli.
60
+ */
61
+ fn map_slices < A : Copy + Owned , B : Copy + Owned > (
62
+ xs : & [ A ] ,
63
+ f : & fn ( ) -> ~fn ( uint , v : & [ A ] ) -> B )
64
+ -> ~[ B ] {
65
+
66
+ let len = xs. len ( ) ;
67
+ if len < min_granularity {
68
+ info ! ( "small slice" ) ;
69
+ // This is a small vector, fall back on the normal map.
70
+ ~[ f ( ) ( 0 u, xs) ]
71
+ }
72
+ else {
73
+ let num_tasks = uint:: min ( max_tasks, len / min_granularity) ;
74
+
75
+ let items_per_task = len / num_tasks;
76
+
77
+ let mut futures = ~[ ] ;
78
+ let mut base = 0 u;
79
+ info ! ( "spawning tasks" ) ;
80
+ while base < len {
81
+ let end = uint:: min ( len, base + items_per_task) ;
82
+ do vec:: as_imm_buf ( xs) |p, _len| {
83
+ let f = f ( ) ;
84
+ let base = base;
85
+ let f = do future:: spawn ( ) || {
86
+ unsafe {
87
+ let len = end - base;
88
+ let slice = ( ptr:: offset ( p, base) ,
89
+ len * sys:: size_of :: < A > ( ) ) ;
90
+ info ! ( "pre-slice: %?" , ( base, slice) ) ;
91
+ let slice : & [ A ] =
92
+ cast:: transmute ( slice) ;
93
+ info ! ( "slice: %?" , ( base, slice. len( ) , end - base) ) ;
94
+ assert_eq ! ( slice. len( ) , end - base) ;
95
+ f ( base, slice)
96
+ }
97
+ } ;
98
+ futures. push ( f) ;
99
+ } ;
100
+ base += items_per_task;
101
+ }
102
+ info ! ( "tasks spawned" ) ;
103
+
104
+ info ! ( "num_tasks: %?" , ( num_tasks, futures. len( ) ) ) ;
105
+ assert_eq ! ( num_tasks, futures. len( ) ) ;
106
+
107
+ let r = do vec:: map_consume ( futures) |ys| {
108
+ let mut ys = ys;
109
+ ys. get ( )
110
+ } ;
111
+ r
112
+ }
113
+ }
114
+
115
+ /// A parallel version of map.
116
+ pub fn map < A : Copy + Owned , B : Copy + Owned > (
117
+ xs : & [ A ] , fn_factory : & fn ( ) -> ~fn ( & A ) -> B ) -> ~[ B ] {
118
+ vec:: concat ( map_slices ( xs, || {
119
+ let f = fn_factory ( ) ;
120
+ let result: ~fn ( uint , & [ A ] ) -> ~[ B ] =
121
+ |_, slice| vec:: map ( slice, |x| f ( x) ) ;
122
+ result
123
+ } ) )
124
+ }
125
+
126
+ /// A parallel version of mapi.
127
+ pub fn mapi < A : Copy + Owned , B : Copy + Owned > (
128
+ xs : & [ A ] ,
129
+ fn_factory : & fn ( ) -> ~fn ( uint , & A ) -> B ) -> ~[ B ] {
130
+ let slices = map_slices ( xs, || {
131
+ let f = fn_factory ( ) ;
132
+ let result: ~fn ( uint , & [ A ] ) -> ~[ B ] = |base, slice| {
133
+ vec:: mapi ( slice, |i, x| {
134
+ f ( i + base, x)
135
+ } )
136
+ } ;
137
+ result
138
+ } ) ;
139
+ let r = vec:: concat ( slices) ;
140
+ info ! ( "%?" , ( r. len( ) , xs. len( ) ) ) ;
141
+ assert_eq ! ( r. len( ) , xs. len( ) ) ;
142
+ r
143
+ }
144
+
145
+ /// Returns true if the function holds for all elements in the vector.
146
+ pub fn alli < A : Copy + Owned > (
147
+ xs : & [ A ] ,
148
+ fn_factory : & fn ( ) -> ~fn ( uint , & A ) -> bool ) -> bool
149
+ {
150
+ do vec:: all ( map_slices ( xs, || {
151
+ let f = fn_factory ( ) ;
152
+ let result: ~fn ( uint , & [ A ] ) -> bool = |base, slice| {
153
+ vec:: alli ( slice, |i, x| {
154
+ f ( i + base, x)
155
+ } )
156
+ } ;
157
+ result
158
+ } ) ) |x| { * x }
159
+ }
160
+
161
+ /// Returns true if the function holds for any elements in the vector.
162
+ pub fn any < A : Copy + Owned > (
163
+ xs : & [ A ] ,
164
+ fn_factory : & fn ( ) -> ~fn ( & A ) -> bool ) -> bool {
165
+ do vec:: any ( map_slices ( xs, || {
166
+ let f = fn_factory ( ) ;
167
+ let result: ~fn ( uint , & [ A ] ) -> bool =
168
+ |_, slice| vec:: any ( slice, |x| f ( x) ) ;
169
+ result
170
+ } ) ) |x| { * x }
171
+ }
172
+ }
173
+
37
174
fn make_edges ( scale : uint , edgefactor : uint ) -> ~[ ( node_id , node_id ) ] {
38
175
let mut r = rand:: XorShiftRng :: new ( ) ;
39
176
0 commit comments