Skip to content

Commit a354064

Browse files
committed
Implement as trait object
1 parent bc8a1aa commit a354064

File tree

1 file changed

+116
-60
lines changed

1 file changed

+116
-60
lines changed

src/scheduler/stat.rs

Lines changed: 116 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -7,69 +7,110 @@ use std::time::SystemTime;
77
pub struct SchedulerStat {
88
work_id_name_map: HashMap<TypeId, &'static str>,
99
work_counts: HashMap<TypeId, usize>,
10-
work_durations: HashMap<TypeId, Vec<WorkDuration>>,
11-
}
12-
13-
trait SimpleCounter {
14-
// TODO: consolidate with crate::util::statistics::counter::Counter;
15-
fn start(&mut self);
16-
fn stop(&mut self);
10+
work_counters: HashMap<TypeId, Vec<Vec<Box<dyn WorkCounter>>>>,
1711
}
1812

1913
#[derive(Copy, Clone)]
20-
struct WorkDuration {
14+
struct WorkCounterBase {
2115
total: f64,
2216
min: f64,
2317
max: f64,
24-
start_value: Option<SystemTime>,
25-
running: bool,
2618
}
2719

28-
impl WorkDuration {
29-
fn new() -> Self {
30-
WorkDuration {
20+
impl Default for WorkCounterBase {
21+
fn default() -> Self {
22+
WorkCounterBase {
3123
total: 0.0,
3224
min: f64::INFINITY,
3325
max: f64::NEG_INFINITY,
34-
start_value: None,
35-
running: false,
3626
}
3727
}
28+
}
3829

39-
fn process_duration(&mut self, duration: f64) {
40-
self.min = self.min.min(duration);
41-
self.max = self.max.max(duration);
42-
self.total = self.total + duration;
43-
}
44-
45-
fn merge_duration(&self, other: &Self) -> Self {
30+
impl WorkCounterBase {
31+
fn merge(&self, other: &Self) -> Self {
4632
let min = self.min.min(other.min);
4733
let max = self.max.max(other.max);
4834
let total = self.total + other.total;
49-
WorkDuration {
50-
total,
51-
min,
52-
max,
53-
start_value: None,
54-
running: false,
55-
}
35+
WorkCounterBase { total, min, max }
5636
}
5737

58-
fn merge_duration_inplace(&mut self, other: &Self) {
38+
fn merge_inplace(&mut self, other: &Self) {
5939
self.min = self.min.min(other.min);
6040
self.max = self.max.max(other.max);
6141
self.total = self.total + other.total;
6242
}
43+
44+
fn merge_val(&mut self, val: f64) {
45+
self.min = self.min.min(val);
46+
self.max = self.max.max(val);
47+
self.total = self.total + val;
48+
}
6349
}
64-
impl SimpleCounter for WorkDuration {
50+
51+
trait WorkCounter: WorkCounterClone {
52+
// TODO: consolidate with crate::util::statistics::counter::Counter;
53+
fn start(&mut self);
54+
fn stop(&mut self);
55+
fn name(&self) -> &'static str;
56+
fn get_base(&self) -> &WorkCounterBase;
57+
fn get_base_mut(&mut self) -> &mut WorkCounterBase;
58+
}
59+
60+
trait WorkCounterClone {
61+
fn clone_box(&self) -> Box<dyn WorkCounter>;
62+
}
63+
64+
impl<T: 'static + WorkCounter + Clone> WorkCounterClone for T {
65+
fn clone_box(&self) -> Box<dyn WorkCounter> {
66+
Box::new(self.clone())
67+
}
68+
}
69+
70+
impl Clone for Box<dyn WorkCounter> {
71+
fn clone(&self) -> Box<dyn WorkCounter> {
72+
self.clone_box()
73+
}
74+
}
75+
76+
#[derive(Copy, Clone)]
77+
struct WorkDuration {
78+
base: WorkCounterBase,
79+
start_value: Option<SystemTime>,
80+
running: bool,
81+
}
82+
83+
impl WorkDuration {
84+
fn new() -> Self {
85+
WorkDuration {
86+
base: Default::default(),
87+
start_value: None,
88+
running: false,
89+
}
90+
}
91+
}
92+
93+
impl WorkCounter for WorkDuration {
6594
fn start(&mut self) {
6695
self.start_value = Some(SystemTime::now());
6796
self.running = true;
6897
}
6998

7099
fn stop(&mut self) {
71100
let duration = self.start_value.unwrap().elapsed().unwrap().as_nanos() as f64;
72-
self.process_duration(duration);
101+
self.base.merge_val(duration);
102+
}
103+
104+
fn name(&self) -> &'static str {
105+
"time"
106+
}
107+
108+
fn get_base(&self) -> &WorkCounterBase {
109+
&self.base
110+
}
111+
112+
fn get_base_mut(&mut self) -> &mut WorkCounterBase {
113+
&mut self.base
73114
}
74115
}
75116

@@ -99,25 +140,30 @@ impl SchedulerStat {
99140
}
100141
stat.insert("total-work.count".to_owned(), format!("{}", total_count));
101142
// Work execution times
102-
let mut duration_overall = WorkDuration::new();
103-
for (t, durations) in &self.work_durations {
143+
let mut duration_overall: WorkCounterBase = Default::default();
144+
for (t, vs) in &self.work_counters {
104145
let n = self.work_id_name_map[t];
105-
let fold = durations
106-
.iter()
107-
.fold(WorkDuration::new(), |acc, x| acc.merge_duration(x));
108-
duration_overall.merge_duration_inplace(&fold);
109-
stat.insert(
110-
format!("work.{}.time.total", self.work_name(n)),
111-
format!("{:.2}", fold.total),
112-
);
113-
stat.insert(
114-
format!("work.{}.time.min", self.work_name(n)),
115-
format!("{:.2}", fold.min),
116-
);
117-
stat.insert(
118-
format!("work.{}.time.max", self.work_name(n)),
119-
format!("{:.2}", fold.max),
120-
);
146+
for v in vs.iter() {
147+
let fold = v
148+
.iter()
149+
.fold(Default::default(), |acc: WorkCounterBase, x| {
150+
acc.merge(x.get_base())
151+
});
152+
duration_overall.merge_inplace(&fold);
153+
let name = v.first().unwrap().name();
154+
stat.insert(
155+
format!("work.{}.{}.total", self.work_name(n), name),
156+
format!("{:.2}", fold.total),
157+
);
158+
stat.insert(
159+
format!("work.{}.{}.min", self.work_name(n), name),
160+
format!("{:.2}", fold.min),
161+
);
162+
stat.insert(
163+
format!("work.{}.{}.max", self.work_name(n), name),
164+
format!("{:.2}", fold.max),
165+
);
166+
}
121167
}
122168

123169
stat.insert(
@@ -147,11 +193,14 @@ impl SchedulerStat {
147193
self.work_counts.insert(*id, *count);
148194
}
149195
}
150-
for (id, duration) in &stat.work_durations {
151-
self.work_durations
196+
for (id, counters) in &stat.work_counters {
197+
let vs = self
198+
.work_counters
152199
.entry(*id)
153-
.and_modify(|v| v.push(*duration))
154-
.or_insert(vec![*duration]);
200+
.or_insert(vec![vec![]; counters.len()]);
201+
for (v, c) in vs.iter_mut().zip(counters.iter()) {
202+
v.push(c.clone());
203+
}
155204
}
156205
}
157206
}
@@ -172,17 +221,19 @@ impl WorkStat {
172221
.insert(self.type_id, self.type_name);
173222
*worker_stat.work_counts.entry(self.type_id).or_insert(0) += 1;
174223
worker_stat
175-
.work_durations
224+
.work_counters
176225
.entry(self.type_id)
177-
.and_modify(|v| v.stop());
226+
.and_modify(|v| {
227+
v.iter_mut().for_each(|c| c.stop());
228+
});
178229
}
179230
}
180231

181232
#[derive(Default)]
182233
pub struct WorkerLocalStat {
183234
work_id_name_map: HashMap<TypeId, &'static str>,
184235
work_counts: HashMap<TypeId, usize>,
185-
work_durations: HashMap<TypeId, WorkDuration>,
236+
work_counters: HashMap<TypeId, Vec<Box<dyn WorkCounter>>>,
186237
enabled: AtomicBool,
187238
}
188239

@@ -201,10 +252,15 @@ impl WorkerLocalStat {
201252
type_id: work_id,
202253
type_name: work_name,
203254
};
204-
self.work_durations
255+
self.work_counters
205256
.entry(work_id)
206-
.or_insert(WorkDuration::new())
207-
.start();
257+
.or_insert(WorkerLocalStat::counter_set())
258+
.iter_mut()
259+
.for_each(|c| c.start());
208260
stat
209261
}
262+
263+
fn counter_set() -> Vec<Box<dyn WorkCounter>> {
264+
vec![Box::new(WorkDuration::new())]
265+
}
210266
}

0 commit comments

Comments
 (0)