-
Notifications
You must be signed in to change notification settings - Fork 6
Expand file tree
/
Copy pathmain.rs
More file actions
74 lines (65 loc) · 2.21 KB
/
main.rs
File metadata and controls
74 lines (65 loc) · 2.21 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
use std::collections::HashMap;
use std::sync::{mpsc, Arc, RwLock};
use std::thread;
use std::time::Duration;
#[macro_use]
extern crate slog;
extern crate slog_async;
extern crate slog_term;
use slog::Drain;
extern crate num;
use num::BigUint;
static THREAD_LENGTH: u32 = 3;
fn main() {
let decorator = slog_term::TermDecorator::new().build();
let drain = slog_term::FullFormat::new(decorator).build().fuse();
let drain = slog_async::Async::new(drain).build().fuse();
let logger = slog::Logger::root(drain, o!());
let (sender, receiver) = mpsc::channel();
let mut children = Vec::new();
let logger_cpy = logger.clone();
let output = Arc::new(RwLock::new(HashMap::<u32, BigUint>::new()));
let output_cpy = Arc::clone(&output);
// receiver
children.push(thread::spawn(move || {
while let Ok(number) = receiver.recv_timeout(Duration::from_secs(3)) {
info!(logger_cpy, "Received event-{number}");
let mut output = output_cpy.write().expect("RwLock poisoned");
output.insert(number, factorial(number));
info!(logger_cpy, "Processing event-{number} successful!\n");
}
warn!(logger_cpy, "No event emitted in last 10 seconds");
}));
// senders
for number in 0..THREAD_LENGTH {
let logger_cpy = logger.clone();
let thread_tx = sender.clone();
children.push(thread::spawn(move || {
info!(logger_cpy, "Sending event-{number}...");
thread_tx.send(number).unwrap();
}));
}
for child in children {
child.join().expect("oops! the child thread panicked");
}
info!(logger, "Finished!");
info!(logger, "Factorial output: {:#?}", output.read().unwrap());
}
fn factorial(number: u32) -> BigUint {
let big_1 = 1u32.into();
let big_2 = 2u32.into();
if number < big_2 {
big_1
} else {
let prev_factorial = factorial(number.clone() - 1);
number * prev_factorial
}
}
#[test]
fn test_factorial() {
assert_eq!(factorial(0), 1u32.into());
assert_eq!(factorial(1), 1u32.into());
assert_eq!(factorial(2), 2u32.into());
assert_eq!(factorial(3), 6u32.into());
assert_eq!(factorial(10), 3628800u32.into());
}