extern crate forkjoin; use forkjoin::{TaskResult,ForkPool,AlgoStyle,ReduceStyle,Algorithm}; #[cfg(test)] struct Tree { value: usize, children: Vec, } #[cfg(test)] fn create_tree() -> Tree { Tree { value: 100, children: vec![Tree { value: 250, children: vec![ Tree { value: 500, children: vec![], }, Tree { value: 10, children: vec![], }], }], } } #[test] fn sum_tree() { let tree = create_tree(); let seq_sum = sum_tree_seq(&tree); let par_sum = sum_tree_par(&tree, 1); assert_eq!(860, seq_sum); assert_eq!(seq_sum, par_sum); } #[cfg(test)] fn sum_tree_seq(t: &Tree) -> usize { t.value + t.children.iter().fold(0, |acc, t2| acc + sum_tree_seq(t2)) } #[cfg(test)] fn sum_tree_par(t: &Tree, nthreads: usize) -> usize { let forkpool = ForkPool::with_threads(nthreads); let sumpool = forkpool.init_algorithm(Algorithm { fun: sum_tree_task, style: AlgoStyle::Reduce(ReduceStyle::Arg(sum_tree_join)), }); let job = sumpool.schedule(t); job.recv().unwrap() } #[cfg(test)] fn sum_tree_task(t: &Tree, _: usize) -> TaskResult<&Tree, usize> { let val = t.value; if t.children.is_empty() { TaskResult::Done(val) } else { let mut fork_args: Vec<&Tree> = vec![]; for c in t.children.iter() { fork_args.push(c); } TaskResult::Fork(fork_args, Some(val)) } } #[cfg(test)] fn sum_tree_join(value: &usize, values: &[usize]) -> usize { *value + values.iter().fold(0, |acc, &v| acc + v) }