Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 369 lines (304 sloc) 9.582 kB
640886c Polymorphic MapReduce!
Eric Holk authored
1 /**
2 A parallel word-frequency counting program.
3
4 This is meant primarily to demonstrate Rust's MapReduce framework.
5
6 It takes a list of files on the command line and outputs a list of
7 words along with how many times each word is used.
8
9 */
10
05543fd @eholk Make tests pass
eholk authored
11 // xfail-pretty
12
640886c Polymorphic MapReduce!
Eric Holk authored
13 use std;
14
e5d095d @catamorphism Change option::t to option
catamorphism authored
15 import option = option;
fa9ad98 @graydon Copy first batch of material from libstd to libcore.
graydon authored
16 import option::some;
17 import option::none;
18 import str;
1a276db @eholk Switch map-reduce control protocol to use pipes. This exposed a bug i…
eholk authored
19 import std::map;
20 import std::map::hashmap;
fa9ad98 @graydon Copy first batch of material from libstd to libcore.
graydon authored
21 import vec;
0c3a128 @eholk Update word-count-generic to latest syntax and un-xfail it. Closes #1…
eholk authored
22 import io;
23 import io::{reader_util, writer_util};
640886c Polymorphic MapReduce!
Eric Holk authored
24
25 import std::time;
fa9ad98 @graydon Copy first batch of material from libstd to libcore.
graydon authored
26 import u64;
27
28 import task;
29 import comm;
30 import comm::chan;
31 import comm::port;
32 import comm::recv;
33 import comm::send;
0c3a128 @eholk Update word-count-generic to latest syntax and un-xfail it. Closes #1…
eholk authored
34 import comm::methods;
35
1a276db @eholk Switch map-reduce control protocol to use pipes. This exposed a bug i…
eholk authored
36 macro_rules! move {
37 { $x:expr } => { unsafe { let y <- *ptr::addr_of($x); y } }
38 }
39
a00478b @eholk word-count-generic now generates random words in benchmark mode.
eholk authored
40 trait word_reader {
92743dc @msullivan Move the world over to using the new style string literals and types.…
msullivan authored
41 fn read_word() -> option<~str>;
a00478b @eholk word-count-generic now generates random words in benchmark mode.
eholk authored
42 }
43
1a276db @eholk Switch map-reduce control protocol to use pipes. This exposed a bug i…
eholk authored
44 trait hash_key {
45 fn hash() -> uint;
46 fn eq(self) -> bool;
47 }
48
49 fn mk_hash<K: const hash_key, V: copy>() -> map::hashmap<K, V> {
50 fn hashfn<K: const hash_key>(k: K) -> uint { k.hash() }
51
52 map::hashmap(hashfn::<K>, |x, y| x.eq(y))
53 }
54
92743dc @msullivan Move the world over to using the new style string literals and types.…
msullivan authored
55 impl of hash_key for ~str {
1a276db @eholk Switch map-reduce control protocol to use pipes. This exposed a bug i…
eholk authored
56 fn hash() -> uint { str::hash(self) }
92743dc @msullivan Move the world over to using the new style string literals and types.…
msullivan authored
57 fn eq(&&x: ~str) -> bool { str::eq(self, x) }
1a276db @eholk Switch map-reduce control protocol to use pipes. This exposed a bug i…
eholk authored
58 }
59
0c3a128 @eholk Update word-count-generic to latest syntax and un-xfail it. Closes #1…
eholk authored
60 // These used to be in task, but they disappeard.
61 type joinable_task = port<()>;
d1fc2b5 @brson Convert to new closure syntax
brson authored
62 fn spawn_joinable(+f: fn~()) -> joinable_task {
0c3a128 @eholk Update word-count-generic to latest syntax and un-xfail it. Closes #1…
eholk authored
63 let p = port();
64 let c = chan(p);
d1fc2b5 @brson Convert to new closure syntax
brson authored
65 do task::spawn() |move f| {
0c3a128 @eholk Update word-count-generic to latest syntax and un-xfail it. Closes #1…
eholk authored
66 f();
67 c.send(());
68 }
69 p
70 }
71
72 fn join(t: joinable_task) {
73 t.recv()
74 }
640886c Polymorphic MapReduce!
Eric Holk authored
75
a00478b @eholk word-count-generic now generates random words in benchmark mode.
eholk authored
76 impl of word_reader for io::reader {
92743dc @msullivan Move the world over to using the new style string literals and types.…
msullivan authored
77 fn read_word() -> option<~str> { read_word(self) }
a00478b @eholk word-count-generic now generates random words in benchmark mode.
eholk authored
78 }
79
92743dc @msullivan Move the world over to using the new style string literals and types.…
msullivan authored
80 fn file_word_reader(filename: ~str) -> word_reader {
a00478b @eholk word-count-generic now generates random words in benchmark mode.
eholk authored
81 alt io::file_reader(filename) {
82 result::ok(f) { f as word_reader }
0c3a128 @eholk Update word-count-generic to latest syntax and un-xfail it. Closes #1…
eholk authored
83 result::err(e) { fail #fmt("%?", e) }
a00478b @eholk word-count-generic now generates random words in benchmark mode.
eholk authored
84 }
85 }
640886c Polymorphic MapReduce!
Eric Holk authored
86
92743dc @msullivan Move the world over to using the new style string literals and types.…
msullivan authored
87 fn map(f: fn~() -> word_reader, emit: map_reduce::putter<~str, int>) {
a00478b @eholk word-count-generic now generates random words in benchmark mode.
eholk authored
88 let f = f();
321fd80 @catamorphism Add an infinite loop construct
catamorphism authored
89 loop {
a00478b @eholk word-count-generic now generates random words in benchmark mode.
eholk authored
90 alt f.read_word() {
df83a79 @eholk In generic word count, use str instead of [u8], and use built in is_a…
eholk authored
91 some(w) { emit(w, 1); }
04a2887 @catamorphism Remove '.' after nullary tags in patterns
catamorphism authored
92 none { break; }
640886c Polymorphic MapReduce!
Eric Holk authored
93 }
94 }
95 }
96
92743dc @msullivan Move the world over to using the new style string literals and types.…
msullivan authored
97 fn reduce(&&word: ~str, get: map_reduce::getter<int>) {
0c3a128 @eholk Update word-count-generic to latest syntax and un-xfail it. Closes #1…
eholk authored
98 let mut count = 0;
640886c Polymorphic MapReduce!
Eric Holk authored
99
321fd80 @catamorphism Add an infinite loop construct
catamorphism authored
100 loop { alt get() { some(_) { count += 1; } none { break; } } }
0c3a128 @eholk Update word-count-generic to latest syntax and un-xfail it. Closes #1…
eholk authored
101
df83a79 @eholk In generic word count, use str instead of [u8], and use built in is_a…
eholk authored
102 io::println(#fmt("%s\t%?", word, count));
640886c Polymorphic MapReduce!
Eric Holk authored
103 }
104
1a276db @eholk Switch map-reduce control protocol to use pipes. This exposed a bug i…
eholk authored
105 class box<T> {
106 let mut contents: option<T>;
107 new(+x: T) { self.contents = some(x); }
108
109 fn swap(f: fn(+T) -> T) {
110 let mut tmp = none;
111 self.contents <-> tmp;
112 self.contents = some(f(option::unwrap(tmp)));
113 }
114
115 fn unwrap() -> T {
116 let mut tmp = none;
117 self.contents <-> tmp;
118 option::unwrap(tmp)
119 }
120 }
121
640886c Polymorphic MapReduce!
Eric Holk authored
122 mod map_reduce {
123 export putter;
124 export getter;
125 export mapper;
126 export reducer;
127 export map_reduce;
128
60ae159 @marijnh Switch to new param kind bound syntax
marijnh authored
129 type putter<K: send, V: send> = fn(K, V);
640886c Polymorphic MapReduce!
Eric Holk authored
130
0c3a128 @eholk Update word-count-generic to latest syntax and un-xfail it. Closes #1…
eholk authored
131 type mapper<K1: send, K2: send, V: send> = fn~(K1, putter<K2, V>);
640886c Polymorphic MapReduce!
Eric Holk authored
132
60ae159 @marijnh Switch to new param kind bound syntax
marijnh authored
133 type getter<V: send> = fn() -> option<V>;
640886c Polymorphic MapReduce!
Eric Holk authored
134
0c3a128 @eholk Update word-count-generic to latest syntax and un-xfail it. Closes #1…
eholk authored
135 type reducer<K: copy send, V: copy send> = fn~(K, getter<V>);
640886c Polymorphic MapReduce!
Eric Holk authored
136
0c3a128 @eholk Update word-count-generic to latest syntax and un-xfail it. Closes #1…
eholk authored
137 enum ctrl_proto<K: copy send, V: copy send> {
138 find_reducer(K, chan<chan<reduce_proto<V>>>),
139 mapper_done
640886c Polymorphic MapReduce!
Eric Holk authored
140 }
141
1a276db @eholk Switch map-reduce control protocol to use pipes. This exposed a bug i…
eholk authored
142
143 proto! ctrl_proto {
144 open: send<K: copy send, V: copy send> {
145 find_reducer(K) -> reducer_response<K, V>,
6748f78 @eholk Polymorphic protocols work well enough to do MapReduce.
eholk authored
146 mapper_done -> !
1a276db @eholk Switch map-reduce control protocol to use pipes. This exposed a bug i…
eholk authored
147 }
148
149 reducer_response: recv<K: copy send, V: copy send> {
150 reducer(chan<reduce_proto<V>>) -> open<K, V>
151 }
152 }
153
0c3a128 @eholk Update word-count-generic to latest syntax and un-xfail it. Closes #1…
eholk authored
154 enum reduce_proto<V: copy send> { emit_val(V), done, ref, release }
640886c Polymorphic MapReduce!
Eric Holk authored
155
1a276db @eholk Switch map-reduce control protocol to use pipes. This exposed a bug i…
eholk authored
156 fn start_mappers<K1: copy send, K2: const copy send hash_key,
157 V: copy send>(
0c3a128 @eholk Update word-count-generic to latest syntax and un-xfail it. Closes #1…
eholk authored
158 map: mapper<K1, K2, V>,
1a276db @eholk Switch map-reduce control protocol to use pipes. This exposed a bug i…
eholk authored
159 &ctrls: ~[ctrl_proto::server::open<K2, V>],
160 inputs: ~[K1])
98e161f @msullivan Switch the compiler over to using ~[] notation instead of []/~. Close…
msullivan authored
161 -> ~[joinable_task]
0c3a128 @eholk Update word-count-generic to latest syntax and un-xfail it. Closes #1…
eholk authored
162 {
98e161f @msullivan Switch the compiler over to using ~[] notation instead of []/~. Close…
msullivan authored
163 let mut tasks = ~[];
d1fc2b5 @brson Convert to new closure syntax
brson authored
164 for inputs.each |i| {
1a276db @eholk Switch map-reduce control protocol to use pipes. This exposed a bug i…
eholk authored
165 let (ctrl, ctrl_server) = ctrl_proto::init();
166 let ctrl = box(ctrl);
bf88ff5 @eholk Remove slow vec+=, and make word-count difficulty harder.
eholk authored
167 vec::push(tasks, spawn_joinable(|| map_task(map, ctrl, i) ));
1a276db @eholk Switch map-reduce control protocol to use pipes. This exposed a bug i…
eholk authored
168 vec::push(ctrls, ctrl_server);
640886c Polymorphic MapReduce!
Eric Holk authored
169 }
170 ret tasks;
171 }
172
1a276db @eholk Switch map-reduce control protocol to use pipes. This exposed a bug i…
eholk authored
173 fn map_task<K1: copy send, K2: const copy send hash_key, V: copy send>(
0c3a128 @eholk Update word-count-generic to latest syntax and un-xfail it. Closes #1…
eholk authored
174 map: mapper<K1, K2, V>,
1a276db @eholk Switch map-reduce control protocol to use pipes. This exposed a bug i…
eholk authored
175 ctrl: box<ctrl_proto::client::open<K2, V>>,
0c3a128 @eholk Update word-count-generic to latest syntax and un-xfail it. Closes #1…
eholk authored
176 input: K1)
177 {
f0dfbe7 @graydon Register new snapshots, purge log_err and log_full in favour of log(.…
graydon authored
178 // log(error, "map_task " + input);
1a276db @eholk Switch map-reduce control protocol to use pipes. This exposed a bug i…
eholk authored
179 let intermediates = mk_hash();
640886c Polymorphic MapReduce!
Eric Holk authored
180
1a276db @eholk Switch map-reduce control protocol to use pipes. This exposed a bug i…
eholk authored
181 do map(input) |key, val| {
182 let mut c = none;
183 alt intermediates.find(key) {
184 some(_c) { c = some(_c); }
04a2887 @catamorphism Remove '.' after nullary tags in patterns
catamorphism authored
185 none {
1a276db @eholk Switch map-reduce control protocol to use pipes. This exposed a bug i…
eholk authored
186 do ctrl.swap |ctrl| {
187 let ctrl = ctrl_proto::client::find_reducer(ctrl, key);
188 alt pipes::recv(ctrl) {
189 ctrl_proto::reducer(c_, ctrl) {
190 c = some(c_);
191 move!{ctrl}
192 }
193 }
194 }
195 intermediates.insert(key, c.get());
196 send(c.get(), ref);
640886c Polymorphic MapReduce!
Eric Holk authored
197 }
198 }
1a276db @eholk Switch map-reduce control protocol to use pipes. This exposed a bug i…
eholk authored
199 send(c.get(), emit_val(val));
640886c Polymorphic MapReduce!
Eric Holk authored
200 }
201
0c3a128 @eholk Update word-count-generic to latest syntax and un-xfail it. Closes #1…
eholk authored
202 fn finish<K: copy send, V: copy send>(_k: K, v: chan<reduce_proto<V>>)
203 {
640886c Polymorphic MapReduce!
Eric Holk authored
204 send(v, release);
205 }
1a276db @eholk Switch map-reduce control protocol to use pipes. This exposed a bug i…
eholk authored
206 for intermediates.each_value |v| { send(v, release) }
207 ctrl_proto::client::mapper_done(ctrl.unwrap());
640886c Polymorphic MapReduce!
Eric Holk authored
208 }
209
0c3a128 @eholk Update word-count-generic to latest syntax and un-xfail it. Closes #1…
eholk authored
210 fn reduce_task<K: copy send, V: copy send>(
211 reduce: reducer<K, V>,
212 key: K,
213 out: chan<chan<reduce_proto<V>>>)
214 {
640886c Polymorphic MapReduce!
Eric Holk authored
215 let p = port();
216
217 send(out, chan(p));
218
4dcf84e @brson Remove bind. Issue #2189
brson authored
219 let mut ref_count = 0;
220 let mut is_done = false;
640886c Polymorphic MapReduce!
Eric Holk authored
221
0c3a128 @eholk Update word-count-generic to latest syntax and un-xfail it. Closes #1…
eholk authored
222 fn get<V: copy send>(p: port<reduce_proto<V>>,
223 &ref_count: int, &is_done: bool)
ca1df2b @marijnh Pretty-print for new arg-mode syntax
marijnh authored
224 -> option<V> {
640886c Polymorphic MapReduce!
Eric Holk authored
225 while !is_done || ref_count > 0 {
226 alt recv(p) {
227 emit_val(v) {
8b58095 @graydon Register snapshots and switch logging over to use of log_full or #err…
graydon authored
228 // #error("received %d", v);
640886c Polymorphic MapReduce!
Eric Holk authored
229 ret some(v);
230 }
04a2887 @catamorphism Remove '.' after nullary tags in patterns
catamorphism authored
231 done {
8b58095 @graydon Register snapshots and switch logging over to use of log_full or #err…
graydon authored
232 // #error("all done");
640886c Polymorphic MapReduce!
Eric Holk authored
233 is_done = true;
234 }
0c3a128 @eholk Update word-count-generic to latest syntax and un-xfail it. Closes #1…
eholk authored
235 ref { ref_count += 1; }
236 release { ref_count -= 1; }
640886c Polymorphic MapReduce!
Eric Holk authored
237 }
238 }
239 ret none;
240 }
241
d1fc2b5 @brson Convert to new closure syntax
brson authored
242 reduce(key, || get(p, ref_count, is_done) );
640886c Polymorphic MapReduce!
Eric Holk authored
243 }
244
1a276db @eholk Switch map-reduce control protocol to use pipes. This exposed a bug i…
eholk authored
245 fn map_reduce<K1: copy send, K2: const copy send hash_key, V: copy send>(
0c3a128 @eholk Update word-count-generic to latest syntax and un-xfail it. Closes #1…
eholk authored
246 map: mapper<K1, K2, V>,
247 reduce: reducer<K2, V>,
98e161f @msullivan Switch the compiler over to using ~[] notation instead of []/~. Close…
msullivan authored
248 inputs: ~[K1])
0c3a128 @eholk Update word-count-generic to latest syntax and un-xfail it. Closes #1…
eholk authored
249 {
1a276db @eholk Switch map-reduce control protocol to use pipes. This exposed a bug i…
eholk authored
250 let mut ctrl = ~[];
640886c Polymorphic MapReduce!
Eric Holk authored
251
252 // This task becomes the master control task. It task::_spawns
253 // to do the rest.
254
1a276db @eholk Switch map-reduce control protocol to use pipes. This exposed a bug i…
eholk authored
255 let reducers = mk_hash();
256 let mut tasks = start_mappers(map, ctrl, inputs);
0c3a128 @eholk Update word-count-generic to latest syntax and un-xfail it. Closes #1…
eholk authored
257 let mut num_mappers = vec::len(inputs) as int;
640886c Polymorphic MapReduce!
Eric Holk authored
258
259 while num_mappers > 0 {
1a276db @eholk Switch map-reduce control protocol to use pipes. This exposed a bug i…
eholk authored
260 let (_ready, message, ctrls) = pipes::select(ctrl);
261 alt option::unwrap(message) {
6748f78 @eholk Polymorphic protocols work well enough to do MapReduce.
eholk authored
262 ctrl_proto::mapper_done {
8b58095 @graydon Register snapshots and switch logging over to use of log_full or #err…
graydon authored
263 // #error("received mapper terminated.");
640886c Polymorphic MapReduce!
Eric Holk authored
264 num_mappers -= 1;
1a276db @eholk Switch map-reduce control protocol to use pipes. This exposed a bug i…
eholk authored
265 ctrl = ctrls;
640886c Polymorphic MapReduce!
Eric Holk authored
266 }
1a276db @eholk Switch map-reduce control protocol to use pipes. This exposed a bug i…
eholk authored
267 ctrl_proto::find_reducer(k, cc) {
640886c Polymorphic MapReduce!
Eric Holk authored
268 let c;
f0dfbe7 @graydon Register new snapshots, purge log_err and log_full in favour of log(.…
graydon authored
269 // log(error, "finding reducer for " + k);
1a276db @eholk Switch map-reduce control protocol to use pipes. This exposed a bug i…
eholk authored
270 alt reducers.find(k) {
640886c Polymorphic MapReduce!
Eric Holk authored
271 some(_c) {
f0dfbe7 @graydon Register new snapshots, purge log_err and log_full in favour of log(.…
graydon authored
272 // log(error,
8b58095 @graydon Register snapshots and switch logging over to use of log_full or #err…
graydon authored
273 // "reusing existing reducer for " + k);
640886c Polymorphic MapReduce!
Eric Holk authored
274 c = _c;
275 }
04a2887 @catamorphism Remove '.' after nullary tags in patterns
catamorphism authored
276 none {
f0dfbe7 @graydon Register new snapshots, purge log_err and log_full in favour of log(.…
graydon authored
277 // log(error, "creating new reducer for " + k);
640886c Polymorphic MapReduce!
Eric Holk authored
278 let p = port();
a1ef79c @nikomatsakis update to use new spawn syntax
nikomatsakis authored
279 let ch = chan(p);
640886c Polymorphic MapReduce!
Eric Holk authored
280 let r = reduce, kk = k;
bf88ff5 @eholk Remove slow vec+=, and make word-count difficulty harder.
eholk authored
281 vec::push(tasks,
282 spawn_joinable(|| reduce_task(r, kk, ch) ));
640886c Polymorphic MapReduce!
Eric Holk authored
283 c = recv(p);
1a276db @eholk Switch map-reduce control protocol to use pipes. This exposed a bug i…
eholk authored
284 reducers.insert(k, c);
640886c Polymorphic MapReduce!
Eric Holk authored
285 }
286 }
1a276db @eholk Switch map-reduce control protocol to use pipes. This exposed a bug i…
eholk authored
287 ctrl = vec::append_one(
288 ctrls,
289 ctrl_proto::server::reducer(move!{cc}, c));
640886c Polymorphic MapReduce!
Eric Holk authored
290 }
291 }
292 }
293
1a276db @eholk Switch map-reduce control protocol to use pipes. This exposed a bug i…
eholk authored
294 for reducers.each_value |v| { send(v, done) }
640886c Polymorphic MapReduce!
Eric Holk authored
295
d1fc2b5 @brson Convert to new closure syntax
brson authored
296 for tasks.each |t| { join(t); }
640886c Polymorphic MapReduce!
Eric Holk authored
297 }
298 }
299
92743dc @msullivan Move the world over to using the new style string literals and types.…
msullivan authored
300 fn main(argv: ~[~str]) {
301 if vec::len(argv) < 2u && !os::getenv(~"RUST_BENCH").is_some() {
640886c Polymorphic MapReduce!
Eric Holk authored
302 let out = io::stdout();
303
5c49e4f @brson Reformat. Issue #855
brson authored
304 out.write_line(#fmt["Usage: %s <filename> ...", argv[0]]);
640886c Polymorphic MapReduce!
Eric Holk authored
305
306 ret;
307 }
308
a00478b @eholk word-count-generic now generates random words in benchmark mode.
eholk authored
309 let readers: ~[fn~() -> word_reader] = if argv.len() >= 2 {
05543fd @eholk Make tests pass
eholk authored
310 // FIXME (#2880)
311 vec::slice(argv, 1u, argv.len()).map(
a00478b @eholk word-count-generic now generates random words in benchmark mode.
eholk authored
312 |f| fn~() -> word_reader { file_word_reader(f) } )
313 }
314 else {
315 let num_readers = 50;
1a276db @eholk Switch map-reduce control protocol to use pipes. This exposed a bug i…
eholk authored
316 let words_per_reader = 600;
a00478b @eholk word-count-generic now generates random words in benchmark mode.
eholk authored
317 vec::from_fn(
318 num_readers,
319 |_i| fn~() -> word_reader {
320 random_word_reader(words_per_reader) as word_reader
321 })
322 };
323
640886c Polymorphic MapReduce!
Eric Holk authored
324 let start = time::precise_time_ns();
325
a00478b @eholk word-count-generic now generates random words in benchmark mode.
eholk authored
326 map_reduce::map_reduce(map, reduce, readers);
640886c Polymorphic MapReduce!
Eric Holk authored
327 let stop = time::precise_time_ns();
328
0c3a128 @eholk Update word-count-generic to latest syntax and un-xfail it. Closes #1…
eholk authored
329 let elapsed = (stop - start) / 1000000u64;
640886c Polymorphic MapReduce!
Eric Holk authored
330
92743dc @msullivan Move the world over to using the new style string literals and types.…
msullivan authored
331 log(error, ~"MapReduce completed in "
332 + u64::str(elapsed) + ~"ms");
640886c Polymorphic MapReduce!
Eric Holk authored
333 }
334
92743dc @msullivan Move the world over to using the new style string literals and types.…
msullivan authored
335 fn read_word(r: io::reader) -> option<~str> {
336 let mut w = ~"";
640886c Polymorphic MapReduce!
Eric Holk authored
337
338 while !r.eof() {
339 let c = r.read_char();
340
341 if is_word_char(c) {
ab6bb03 @brson Rename std::istr to std::str. Issue #855
brson authored
342 w += str::from_char(c);
92743dc @msullivan Move the world over to using the new style string literals and types.…
msullivan authored
343 } else { if w != ~"" { ret some(w); } }
640886c Polymorphic MapReduce!
Eric Holk authored
344 }
345 ret none;
346 }
a00478b @eholk word-count-generic now generates random words in benchmark mode.
eholk authored
347
df83a79 @eholk In generic word count, use str instead of [u8], and use built in is_a…
eholk authored
348 fn is_word_char(c: char) -> bool {
a00478b @eholk word-count-generic now generates random words in benchmark mode.
eholk authored
349 char::is_alphabetic(c) || char::is_digit(c) || c == '_'
350 }
351
352 class random_word_reader: word_reader {
353 let mut remaining: uint;
354 let rng: rand::rng;
355 new(count: uint) {
356 self.remaining = count;
357 self.rng = rand::rng();
358 }
359
92743dc @msullivan Move the world over to using the new style string literals and types.…
msullivan authored
360 fn read_word() -> option<~str> {
a00478b @eholk word-count-generic now generates random words in benchmark mode.
eholk authored
361 if self.remaining > 0 {
362 self.remaining -= 1;
1a276db @eholk Switch map-reduce control protocol to use pipes. This exposed a bug i…
eholk authored
363 let len = self.rng.gen_uint_range(1, 4);
364 some(self.rng.gen_str(len))
a00478b @eholk word-count-generic now generates random words in benchmark mode.
eholk authored
365 }
366 else { none }
367 }
368 }
Something went wrong with that request. Please try again.