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
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
use std::collections::HashMap;
use std::cmp::Eq;
use std::hash::Hash;
use crate::Tracker;
use crate::Source;
#[cfg(not(feature = "disable_timekeeper"))]
pub struct TimerSet<Key: Eq + Hash + Clone, T: Tracker, S: Source> {
trackers: HashMap<Key, T>,
source: S,
current: Option<(Key, u64)>,
}
#[cfg(not(feature = "disable_timekeeper"))]
impl <Key, T, S> TimerSet<Key, T, S> where Key: Eq + Hash + Clone, T: Tracker, S: Source {
pub fn new() -> Self {
Self {
trackers: HashMap::new(),
source: S::default(),
current: None,
}
}
pub fn start(&mut self, k: Key) {
let now = self.source.get_time();
if let Some((ref k, t)) = self.current {
self.trackers.get_mut(&k).unwrap().record(now - t);
}
self.current = Some((k.clone(), now));
self.trackers.entry(k).or_insert_with(T::default);
}
pub fn stop(&mut self) {
if let Some((ref k, t)) = self.current {
self.trackers.get_mut(&k).unwrap().record(self.source.get_time() - t);
}
self.current = None;
}
pub fn is_running(&self) -> bool {
self.current.is_some()
}
pub fn get_stats(&self, k: Key) -> Option<T::Statistics> {
let now = match self.current {
Some((ref current, t)) if *current == k => Some(self.source.get_time() - t),
_ => None,
};
self.trackers.get(&k).map(|t| t.get_stats(now))
}
pub fn num_nanoseconds(&self, k: Key) -> Option<u64> {
let now = match self.current {
Some((ref current, t)) if *current == k => Some(self.source.get_time() - t),
_ => None,
};
self.trackers.get(&k).map(|t| t.get(now))
}
pub fn num_microseconds(&self, k: Key) -> Option<u64> {
self.num_nanoseconds(k).map(|t| t / 1000)
}
pub fn num_milliseconds(&self, k: Key) -> Option<u64> {
self.num_nanoseconds(k).map(|t| t / 1000_000)
}
pub fn num_seconds(&self, k: Key) -> Option<u64> {
self.num_nanoseconds(k).map(|t| t / 1000_000_000)
}
pub fn num_minutes(&self, k: Key) -> Option<u64> {
self.num_nanoseconds(k).map(|t| t / 60_000_000_000)
}
pub fn num_hours(&self, k: Key) -> Option<u64> {
self.num_nanoseconds(k).map(|t| t / 3600_000_000_000)
}
}
#[test]
fn it_works() {
use crate::SimpleTracker;
use crate::RealTime;
let mut ts = TimerSet::<i32, SimpleTracker, RealTime>::new();
ts.start(1);
ts.start(2);
ts.stop();
assert!(ts.num_nanoseconds(1).unwrap() > 0);
assert!(ts.num_nanoseconds(2).unwrap() > 0);
assert!(ts.num_nanoseconds(3).is_none());
}