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