]>
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 | ||
1a4d82fc | 11 | #![allow(unknown_features)] |
c34b1796 | 12 | #![feature(unboxed_closures, std_misc)] |
1a4d82fc | 13 | |
223e47cc LB |
14 | /** |
15 | A somewhat reduced test case to expose some Valgrind issues. | |
16 | ||
17 | This originally came from the word-count benchmark. | |
18 | */ | |
19 | ||
1a4d82fc JJ |
20 | pub fn map(filename: String, mut emit: map_reduce::putter) { |
21 | emit(filename, "1".to_string()); | |
22 | } | |
223e47cc LB |
23 | |
24 | mod map_reduce { | |
1a4d82fc JJ |
25 | use std::collections::HashMap; |
26 | use std::sync::mpsc::{channel, Sender}; | |
970d7e83 | 27 | use std::str; |
c34b1796 | 28 | use std::thread; |
223e47cc | 29 | |
1a4d82fc | 30 | pub type putter<'a> = Box<FnMut(String, String) + 'a>; |
223e47cc | 31 | |
1a4d82fc | 32 | pub type mapper = extern fn(String, putter); |
223e47cc | 33 | |
c34b1796 | 34 | enum ctrl_proto { find_reducer(Vec<u8>, Sender<isize>), mapper_done, } |
223e47cc | 35 | |
1a4d82fc | 36 | fn start_mappers(ctrl: Sender<ctrl_proto>, inputs: Vec<String>) { |
85aaf69f | 37 | for i in &inputs { |
223e47cc LB |
38 | let ctrl = ctrl.clone(); |
39 | let i = i.clone(); | |
c34b1796 | 40 | thread::spawn(move|| map_task(ctrl.clone(), i.clone()) ); |
223e47cc LB |
41 | } |
42 | } | |
43 | ||
1a4d82fc JJ |
44 | fn map_task(ctrl: Sender<ctrl_proto>, input: String) { |
45 | let mut intermediates = HashMap::new(); | |
223e47cc | 46 | |
c34b1796 | 47 | fn emit(im: &mut HashMap<String, isize>, |
1a4d82fc JJ |
48 | ctrl: Sender<ctrl_proto>, key: String, |
49 | _val: String) { | |
223e47cc LB |
50 | if im.contains_key(&key) { |
51 | return; | |
52 | } | |
1a4d82fc JJ |
53 | let (tx, rx) = channel(); |
54 | println!("sending find_reducer"); | |
55 | ctrl.send(ctrl_proto::find_reducer(key.as_bytes().to_vec(), tx)).unwrap(); | |
56 | println!("receiving"); | |
57 | let c = rx.recv().unwrap(); | |
58 | println!("{}", c); | |
223e47cc LB |
59 | im.insert(key, c); |
60 | } | |
61 | ||
62 | let ctrl_clone = ctrl.clone(); | |
c34b1796 AL |
63 | // FIXME (#22405): Replace `Box::new` with `box` here when/if possible. |
64 | ::map(input, Box::new(|a,b| emit(&mut intermediates, ctrl.clone(), a, b))); | |
1a4d82fc | 65 | ctrl_clone.send(ctrl_proto::mapper_done).unwrap(); |
223e47cc LB |
66 | } |
67 | ||
1a4d82fc JJ |
68 | pub fn map_reduce(inputs: Vec<String>) { |
69 | let (tx, rx) = channel(); | |
223e47cc LB |
70 | |
71 | // This task becomes the master control task. It spawns others | |
72 | // to do the rest. | |
73 | ||
c34b1796 | 74 | let mut reducers: HashMap<String, isize>; |
223e47cc | 75 | |
970d7e83 | 76 | reducers = HashMap::new(); |
223e47cc | 77 | |
1a4d82fc | 78 | start_mappers(tx, inputs.clone()); |
223e47cc | 79 | |
c34b1796 | 80 | let mut num_mappers = inputs.len() as isize; |
223e47cc LB |
81 | |
82 | while num_mappers > 0 { | |
1a4d82fc JJ |
83 | match rx.recv().unwrap() { |
84 | ctrl_proto::mapper_done => { num_mappers -= 1; } | |
85 | ctrl_proto::find_reducer(k, cc) => { | |
223e47cc | 86 | let mut c; |
85aaf69f | 87 | match reducers.get(&str::from_utf8(&k).unwrap().to_string()) { |
223e47cc LB |
88 | Some(&_c) => { c = _c; } |
89 | None => { c = 0; } | |
90 | } | |
1a4d82fc | 91 | cc.send(c).unwrap(); |
223e47cc LB |
92 | } |
93 | } | |
94 | } | |
95 | } | |
96 | } | |
97 | ||
98 | pub fn main() { | |
1a4d82fc JJ |
99 | map_reduce::map_reduce( |
100 | vec!("../src/test/run-pass/hashmap-memory.rs".to_string())); | |
223e47cc | 101 | } |