@@ -7,69 +7,110 @@ use std::time::SystemTime;
7
7
pub struct SchedulerStat {
8
8
work_id_name_map : HashMap < TypeId , & ' static str > ,
9
9
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 > > > > ,
17
11
}
18
12
19
13
#[ derive( Copy , Clone ) ]
20
- struct WorkDuration {
14
+ struct WorkCounterBase {
21
15
total : f64 ,
22
16
min : f64 ,
23
17
max : f64 ,
24
- start_value : Option < SystemTime > ,
25
- running : bool ,
26
18
}
27
19
28
- impl WorkDuration {
29
- fn new ( ) -> Self {
30
- WorkDuration {
20
+ impl Default for WorkCounterBase {
21
+ fn default ( ) -> Self {
22
+ WorkCounterBase {
31
23
total : 0.0 ,
32
24
min : f64:: INFINITY ,
33
25
max : f64:: NEG_INFINITY ,
34
- start_value : None ,
35
- running : false ,
36
26
}
37
27
}
28
+ }
38
29
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 {
46
32
let min = self . min . min ( other. min ) ;
47
33
let max = self . max . max ( other. max ) ;
48
34
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 }
56
36
}
57
37
58
- fn merge_duration_inplace ( & mut self , other : & Self ) {
38
+ fn merge_inplace ( & mut self , other : & Self ) {
59
39
self . min = self . min . min ( other. min ) ;
60
40
self . max = self . max . max ( other. max ) ;
61
41
self . total = self . total + other. total ;
62
42
}
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
+ }
63
49
}
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 {
65
94
fn start ( & mut self ) {
66
95
self . start_value = Some ( SystemTime :: now ( ) ) ;
67
96
self . running = true ;
68
97
}
69
98
70
99
fn stop ( & mut self ) {
71
100
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
73
114
}
74
115
}
75
116
@@ -99,25 +140,30 @@ impl SchedulerStat {
99
140
}
100
141
stat. insert ( "total-work.count" . to_owned ( ) , format ! ( "{}" , total_count) ) ;
101
142
// 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 {
104
145
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
+ }
121
167
}
122
168
123
169
stat. insert (
@@ -147,11 +193,14 @@ impl SchedulerStat {
147
193
self . work_counts . insert ( * id, * count) ;
148
194
}
149
195
}
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
152
199
. 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
+ }
155
204
}
156
205
}
157
206
}
@@ -172,17 +221,19 @@ impl WorkStat {
172
221
. insert ( self . type_id , self . type_name ) ;
173
222
* worker_stat. work_counts . entry ( self . type_id ) . or_insert ( 0 ) += 1 ;
174
223
worker_stat
175
- . work_durations
224
+ . work_counters
176
225
. entry ( self . type_id )
177
- . and_modify ( |v| v. stop ( ) ) ;
226
+ . and_modify ( |v| {
227
+ v. iter_mut ( ) . for_each ( |c| c. stop ( ) ) ;
228
+ } ) ;
178
229
}
179
230
}
180
231
181
232
#[ derive( Default ) ]
182
233
pub struct WorkerLocalStat {
183
234
work_id_name_map : HashMap < TypeId , & ' static str > ,
184
235
work_counts : HashMap < TypeId , usize > ,
185
- work_durations : HashMap < TypeId , WorkDuration > ,
236
+ work_counters : HashMap < TypeId , Vec < Box < dyn WorkCounter > > > ,
186
237
enabled : AtomicBool ,
187
238
}
188
239
@@ -201,10 +252,15 @@ impl WorkerLocalStat {
201
252
type_id : work_id,
202
253
type_name : work_name,
203
254
} ;
204
- self . work_durations
255
+ self . work_counters
205
256
. 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 ( ) ) ;
208
260
stat
209
261
}
262
+
263
+ fn counter_set ( ) -> Vec < Box < dyn WorkCounter > > {
264
+ vec ! [ Box :: new( WorkDuration :: new( ) ) ]
265
+ }
210
266
}
0 commit comments