]>
Commit | Line | Data |
---|---|---|
1a4d82fc | 1 | // Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT |
223e47cc LB |
2 | // file at the top-level directory of this distribution and at |
3 | // http://rust-lang.org/COPYRIGHT. | |
4 | // | |
5 | // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or | |
6 | // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license | |
7 | // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your | |
8 | // option. This file may not be copied, modified, or distributed | |
9 | // except according to those terms. | |
10 | ||
5bcae85e SL |
11 | // ignore-emscripten No support for threads |
12 | ||
1a4d82fc | 13 | #![allow(unknown_features)] |
5bcae85e | 14 | #![feature(std_misc)] |
1a4d82fc | 15 | |
223e47cc LB |
16 | /** |
17 | A somewhat reduced test case to expose some Valgrind issues. | |
18 | ||
19 | This originally came from the word-count benchmark. | |
20 | */ | |
21 | ||
1a4d82fc JJ |
22 | pub fn map(filename: String, mut emit: map_reduce::putter) { |
23 | emit(filename, "1".to_string()); | |
24 | } | |
223e47cc LB |
25 | |
26 | mod map_reduce { | |
1a4d82fc JJ |
27 | use std::collections::HashMap; |
28 | use std::sync::mpsc::{channel, Sender}; | |
970d7e83 | 29 | use std::str; |
c34b1796 | 30 | use std::thread; |
223e47cc | 31 | |
1a4d82fc | 32 | pub type putter<'a> = Box<FnMut(String, String) + 'a>; |
223e47cc | 33 | |
1a4d82fc | 34 | pub type mapper = extern fn(String, putter); |
223e47cc | 35 | |
c34b1796 | 36 | enum ctrl_proto { find_reducer(Vec<u8>, Sender<isize>), mapper_done, } |
223e47cc | 37 | |
1a4d82fc | 38 | fn start_mappers(ctrl: Sender<ctrl_proto>, inputs: Vec<String>) { |
85aaf69f | 39 | for i in &inputs { |
223e47cc LB |
40 | let ctrl = ctrl.clone(); |
41 | let i = i.clone(); | |
c34b1796 | 42 | thread::spawn(move|| map_task(ctrl.clone(), i.clone()) ); |
223e47cc LB |
43 | } |
44 | } | |
45 | ||
1a4d82fc JJ |
46 | fn map_task(ctrl: Sender<ctrl_proto>, input: String) { |
47 | let mut intermediates = HashMap::new(); | |
223e47cc | 48 | |
c34b1796 | 49 | fn emit(im: &mut HashMap<String, isize>, |
1a4d82fc JJ |
50 | ctrl: Sender<ctrl_proto>, key: String, |
51 | _val: String) { | |
223e47cc LB |
52 | if im.contains_key(&key) { |
53 | return; | |
54 | } | |
1a4d82fc JJ |
55 | let (tx, rx) = channel(); |
56 | println!("sending find_reducer"); | |
57 | ctrl.send(ctrl_proto::find_reducer(key.as_bytes().to_vec(), tx)).unwrap(); | |
58 | println!("receiving"); | |
59 | let c = rx.recv().unwrap(); | |
60 | println!("{}", c); | |
223e47cc LB |
61 | im.insert(key, c); |
62 | } | |
63 | ||
64 | let ctrl_clone = ctrl.clone(); | |
c34b1796 | 65 | ::map(input, Box::new(|a,b| emit(&mut intermediates, ctrl.clone(), a, b))); |
1a4d82fc | 66 | ctrl_clone.send(ctrl_proto::mapper_done).unwrap(); |
223e47cc LB |
67 | } |
68 | ||
1a4d82fc JJ |
69 | pub fn map_reduce(inputs: Vec<String>) { |
70 | let (tx, rx) = channel(); | |
223e47cc | 71 | |
bd371182 | 72 | // This thread becomes the master control thread. It spawns others |
223e47cc LB |
73 | // to do the rest. |
74 | ||
c34b1796 | 75 | let mut reducers: HashMap<String, isize>; |
223e47cc | 76 | |
970d7e83 | 77 | reducers = HashMap::new(); |
223e47cc | 78 | |
1a4d82fc | 79 | start_mappers(tx, inputs.clone()); |
223e47cc | 80 | |
c34b1796 | 81 | let mut num_mappers = inputs.len() as isize; |
223e47cc LB |
82 | |
83 | while num_mappers > 0 { | |
1a4d82fc JJ |
84 | match rx.recv().unwrap() { |
85 | ctrl_proto::mapper_done => { num_mappers -= 1; } | |
86 | ctrl_proto::find_reducer(k, cc) => { | |
223e47cc | 87 | let mut c; |
85aaf69f | 88 | match reducers.get(&str::from_utf8(&k).unwrap().to_string()) { |
223e47cc LB |
89 | Some(&_c) => { c = _c; } |
90 | None => { c = 0; } | |
91 | } | |
1a4d82fc | 92 | cc.send(c).unwrap(); |
223e47cc LB |
93 | } |
94 | } | |
95 | } | |
96 | } | |
97 | } | |
98 | ||
99 | pub fn main() { | |
1a4d82fc | 100 | map_reduce::map_reduce( |
c30ab7b3 | 101 | vec!["../src/test/run-pass/hashmap-memory.rs".to_string()]); |
223e47cc | 102 | } |