@@ -5,38 +5,33 @@ use measureme::{Event, TimestampKind};
5
5
6
6
pub fn collapse_stacks < ' a > (
7
7
events : impl Iterator < Item = Event < ' a > > ,
8
- first_event_time : SystemTime ,
9
8
interval : u64 ,
10
9
) -> HashMap < String , usize > {
11
10
let mut recorded_stacks = HashMap :: < String , usize > :: new ( ) ;
12
-
13
- let mut next_observation_time = first_event_time;
14
-
15
- let mut thread_stacks: HashMap < u64 , Vec < Event > > = HashMap :: new ( ) ;
11
+ let mut thread_stacks: HashMap < u64 , ( SystemTime , Vec < Event > ) > = HashMap :: new ( ) ;
16
12
17
13
for event in events {
14
+ let ( next_observation_time, thread_stack) = thread_stacks
15
+ . entry ( event. thread_id )
16
+ . or_insert ( ( event. timestamp , Vec :: new ( ) ) ) ;
18
17
//if this event is after the next_observation_time then we need to record the current stacks
19
- while event. timestamp > next_observation_time {
20
- for ( _tid, stack) in & thread_stacks {
21
- let mut stack_string = String :: new ( ) ;
22
- stack_string. push_str ( "rustc;" ) ;
18
+ if event. timestamp > * next_observation_time {
19
+ let mut stack_string = String :: new ( ) ;
20
+ stack_string. push_str ( "rustc" ) ;
23
21
24
- for event in stack {
25
- stack_string. push_str ( & event. label ) ;
26
- stack_string. push ( ';' ) ;
27
- }
28
-
29
- //remove the trailing ';'
30
- stack_string. remove ( stack_string. len ( ) - 1 ) ;
22
+ for event in thread_stack. iter ( ) {
23
+ stack_string. push ( ';' ) ;
24
+ stack_string. push_str ( & event. label ) ;
25
+ }
31
26
32
- * recorded_stacks. entry ( stack_string) . or_default ( ) += 1 ;
27
+ let count = recorded_stacks. entry ( stack_string) . or_default ( ) ;
33
28
34
- next_observation_time += Duration :: from_millis ( interval) ;
29
+ while event. timestamp > * next_observation_time {
30
+ * count += 1 ;
31
+ * next_observation_time += Duration :: from_millis ( interval) ;
35
32
}
36
33
}
37
34
38
- let thread_stack = thread_stacks. entry ( event. thread_id ) . or_default ( ) ;
39
-
40
35
match event. timestamp_kind {
41
36
TimestampKind :: Start => {
42
37
thread_stack. push ( event) ;
@@ -112,9 +107,7 @@ mod test {
112
107
} ,
113
108
] ;
114
109
115
- let first_event_time = events[ 0 ] . timestamp ;
116
-
117
- let recorded_stacks = super :: collapse_stacks ( events. iter ( ) . cloned ( ) , first_event_time, 1 ) ;
110
+ let recorded_stacks = super :: collapse_stacks ( events. iter ( ) . cloned ( ) , 1 ) ;
118
111
119
112
let mut expected_stacks = HashMap :: < String , usize > :: new ( ) ;
120
113
expected_stacks. insert ( "rustc;EventB;EventA" . into ( ) , 1000 ) ;
@@ -124,4 +117,67 @@ mod test {
124
117
125
118
assert_eq ! ( expected_stacks, recorded_stacks) ;
126
119
}
120
+
121
+ #[ test]
122
+ fn multi_threaded_test ( ) {
123
+ let events = [
124
+ Event {
125
+ event_kind : "Query" . into ( ) ,
126
+ label : "EventA" . into ( ) ,
127
+ additional_data : & [ ] ,
128
+ timestamp : SystemTime :: UNIX_EPOCH + Duration :: from_secs ( 1 ) ,
129
+ timestamp_kind : TimestampKind :: Start ,
130
+ thread_id : 1 ,
131
+ } ,
132
+ Event {
133
+ event_kind : "Query" . into ( ) ,
134
+ label : "EventB" . into ( ) ,
135
+ additional_data : & [ ] ,
136
+ timestamp : SystemTime :: UNIX_EPOCH + Duration :: from_secs ( 3 ) ,
137
+ timestamp_kind : TimestampKind :: Start ,
138
+ thread_id : 2 ,
139
+ } ,
140
+ Event {
141
+ event_kind : "Query" . into ( ) ,
142
+ label : "EventA" . into ( ) ,
143
+ additional_data : & [ ] ,
144
+ timestamp : SystemTime :: UNIX_EPOCH + Duration :: from_secs ( 2 ) ,
145
+ timestamp_kind : TimestampKind :: End ,
146
+ thread_id : 1 ,
147
+ } ,
148
+ Event {
149
+ event_kind : "Query" . into ( ) ,
150
+ label : "EventA" . into ( ) ,
151
+ additional_data : & [ ] ,
152
+ timestamp : SystemTime :: UNIX_EPOCH + Duration :: from_secs ( 4 ) ,
153
+ timestamp_kind : TimestampKind :: Start ,
154
+ thread_id : 2 ,
155
+ } ,
156
+ Event {
157
+ event_kind : "Query" . into ( ) ,
158
+ label : "EventA" . into ( ) ,
159
+ additional_data : & [ ] ,
160
+ timestamp : SystemTime :: UNIX_EPOCH + Duration :: from_secs ( 5 ) ,
161
+ timestamp_kind : TimestampKind :: End ,
162
+ thread_id : 2 ,
163
+ } ,
164
+ Event {
165
+ event_kind : "Query" . into ( ) ,
166
+ label : "EventB" . into ( ) ,
167
+ additional_data : & [ ] ,
168
+ timestamp : SystemTime :: UNIX_EPOCH + Duration :: from_secs ( 6 ) ,
169
+ timestamp_kind : TimestampKind :: End ,
170
+ thread_id : 2 ,
171
+ } ,
172
+ ] ;
173
+
174
+ let recorded_stacks = super :: collapse_stacks ( events. iter ( ) . cloned ( ) , 1000 ) ;
175
+
176
+ let mut expected_stacks = HashMap :: < String , usize > :: new ( ) ;
177
+ expected_stacks. insert ( "rustc;EventB;EventA" . into ( ) , 1 ) ;
178
+ expected_stacks. insert ( "rustc;EventB" . into ( ) , 2 ) ;
179
+ expected_stacks. insert ( "rustc;EventA" . into ( ) , 1 ) ;
180
+
181
+ assert_eq ! ( expected_stacks, recorded_stacks) ;
182
+ }
127
183
}
0 commit comments