@@ -3,7 +3,9 @@ use anyhow::Context;
3
3
use chrono:: { DateTime , Utc } ;
4
4
use log:: { debug, info} ;
5
5
use ra_ap_project_model:: ProjectManifest ;
6
+ use serde:: ser:: SerializeMap ;
6
7
use serde:: Serialize ;
8
+ use std:: collections:: HashMap ;
7
9
use std:: fmt:: Display ;
8
10
use std:: fs:: File ;
9
11
use std:: path:: { Path , PathBuf } ;
@@ -72,27 +74,29 @@ pub struct Diagnostics<T> {
72
74
attributes : T ,
73
75
}
74
76
75
- #[ derive( Debug , Clone , Serialize ) ]
77
+ #[ derive( Default , Debug , Clone , Copy , Serialize , PartialEq , Eq , Hash ) ]
76
78
#[ serde( rename_all = "camelCase" ) ]
77
- enum ExtractionStepTarget {
78
- LoadManifest ( PathBuf ) ,
79
- FetchFile ( PathBuf ) ,
80
- Parse ( PathBuf ) ,
81
- Extract ( PathBuf ) ,
79
+ enum ExtractionStepKind {
80
+ #[ default]
81
+ LoadManifest ,
82
+ LoadSource ,
83
+ Parse ,
84
+ Extract ,
82
85
}
83
86
84
87
#[ derive( Debug , Clone , Serialize ) ]
85
88
#[ serde( rename_all = "camelCase" ) ]
86
89
pub struct ExtractionStep {
87
- # [ serde ( flatten ) ]
88
- target : ExtractionStepTarget ,
90
+ action : ExtractionStepKind ,
91
+ file : PathBuf ,
89
92
ms : u128 ,
90
93
}
91
94
92
95
impl ExtractionStep {
93
- fn new ( start : Instant , target : ExtractionStepTarget ) -> Self {
96
+ fn new ( start : Instant , action : ExtractionStepKind , file : PathBuf ) -> Self {
94
97
let ret = ExtractionStep {
95
- target,
98
+ action,
99
+ file,
96
100
ms : start. elapsed ( ) . as_millis ( ) ,
97
101
} ;
98
102
debug ! ( "{ret:?}" ) ;
@@ -102,70 +106,84 @@ impl ExtractionStep {
102
106
pub fn load_manifest ( start : Instant , target : & ProjectManifest ) -> Self {
103
107
Self :: new (
104
108
start,
105
- ExtractionStepTarget :: LoadManifest ( PathBuf :: from ( target. manifest_path ( ) ) ) ,
109
+ ExtractionStepKind :: LoadManifest ,
110
+ PathBuf :: from ( target. manifest_path ( ) ) ,
106
111
)
107
112
}
108
113
109
114
pub fn parse ( start : Instant , target : & Path ) -> Self {
110
- Self :: new ( start, ExtractionStepTarget :: Parse ( PathBuf :: from ( target) ) )
115
+ Self :: new ( start, ExtractionStepKind :: Parse , PathBuf :: from ( target) )
111
116
}
112
117
113
118
pub fn extract ( start : Instant , target : & Path ) -> Self {
114
- Self :: new ( start, ExtractionStepTarget :: Extract ( PathBuf :: from ( target) ) )
119
+ Self :: new ( start, ExtractionStepKind :: Extract , PathBuf :: from ( target) )
115
120
}
116
121
117
- pub fn fetch_file ( start : Instant , target : & Path ) -> Self {
118
- Self :: new (
119
- start,
120
- ExtractionStepTarget :: FetchFile ( PathBuf :: from ( target) ) ,
121
- )
122
+ pub fn load_source ( start : Instant , target : & Path ) -> Self {
123
+ Self :: new ( start, ExtractionStepKind :: LoadSource , PathBuf :: from ( target) )
122
124
}
123
125
}
124
126
125
- #[ derive( Debug , Default , Clone , Serialize ) ]
126
- #[ serde( rename_all = "camelCase" ) ]
127
- struct HumanReadableDuration {
128
- ms : u128 ,
129
- pretty : String ,
127
+ #[ derive( Debug , Default , Clone ) ]
128
+ struct HumanReadableDuration ( u128 ) ;
129
+
130
+ impl Serialize for HumanReadableDuration {
131
+ fn serialize < S : serde:: Serializer > ( & self , serializer : S ) -> Result < S :: Ok , S :: Error > {
132
+ let mut map = serializer. serialize_map ( Some ( 2 ) ) ?;
133
+ map. serialize_entry ( "ms" , & self . 0 ) ?;
134
+ map. serialize_entry ( "pretty" , & self . pretty ( ) ) ?;
135
+ map. end ( )
136
+ }
130
137
}
131
138
132
139
impl HumanReadableDuration {
133
- pub fn new ( ms : u128 ) -> Self {
134
- let seconds = ms / 1000 ;
135
- let minutes = seconds / 60 ;
140
+ pub fn add ( & mut self , other : u128 ) {
141
+ self . 0 += other;
142
+ }
143
+
144
+ pub fn pretty ( & self ) -> String {
145
+ let milliseconds = self . 0 % 1000 ;
146
+ let mut seconds = self . 0 / 1000 ;
147
+ if seconds < 60 {
148
+ return format ! ( "{seconds}.{milliseconds:03}s" ) ;
149
+ }
150
+ let mut minutes = seconds / 60 ;
151
+ seconds %= 60 ;
152
+ if minutes < 60 {
153
+ return format ! ( "{minutes}min{seconds:02}.{milliseconds:03}s" ) ;
154
+ }
136
155
let hours = minutes / 60 ;
137
- let pretty = format ! (
138
- "{hours}:{minutes:02}:{seconds:02}.{milliseconds:03}" ,
139
- minutes = minutes % 60 ,
140
- seconds = seconds % 60 ,
141
- milliseconds = ms % 1000 ,
142
- ) ;
143
- Self { ms, pretty }
156
+ minutes %= 60 ;
157
+ format ! ( "{hours}h{minutes:02}min{seconds:02}.{milliseconds:03}s" )
144
158
}
145
159
}
146
160
147
161
impl From < u128 > for HumanReadableDuration {
148
162
fn from ( val : u128 ) -> Self {
149
- HumanReadableDuration :: new ( val)
163
+ HumanReadableDuration ( val)
150
164
}
151
165
}
152
166
153
167
impl Display for HumanReadableDuration {
154
168
fn fmt ( & self , f : & mut std:: fmt:: Formatter ) -> std:: fmt:: Result {
155
- write ! ( f , "{}ms ({})" , self . ms , self . pretty)
169
+ f . write_str ( & self . pretty ( ) )
156
170
}
157
171
}
158
172
173
+ #[ derive( Debug , Default , Clone , Serialize ) ]
174
+ #[ serde( rename_all = "camelCase" ) ]
175
+ struct DurationsSummary {
176
+ #[ serde( flatten) ]
177
+ durations : HashMap < ExtractionStepKind , HumanReadableDuration > ,
178
+ total : HumanReadableDuration ,
179
+ }
180
+
159
181
#[ derive( Debug , Default , Clone , Serialize ) ]
160
182
#[ serde( rename_all = "camelCase" ) ]
161
183
struct ExtractionSummary {
162
184
number_of_manifests : usize ,
163
185
number_of_files : usize ,
164
- total_load_duration : HumanReadableDuration ,
165
- total_fetch_file_duration : HumanReadableDuration ,
166
- total_parse_duration : HumanReadableDuration ,
167
- total_extract_duration : HumanReadableDuration ,
168
- total_duration : HumanReadableDuration ,
186
+ durations : DurationsSummary ,
169
187
}
170
188
171
189
#[ derive( Debug , Default , Clone , Serialize ) ]
@@ -180,46 +198,32 @@ type ExtractionDiagnostics = Diagnostics<ExtractionAttributes>;
180
198
fn summary ( start : Instant , steps : & [ ExtractionStep ] ) -> ExtractionSummary {
181
199
let mut number_of_manifests = 0 ;
182
200
let mut number_of_files = 0 ;
183
- let mut total_load_duration = 0 ;
184
- let mut total_parse_duration = 0 ;
185
- let mut total_extract_duration = 0 ;
186
- let mut total_fetch_file_duration: u128 = 0 ;
201
+ let mut durations = HashMap :: new ( ) ;
187
202
for step in steps {
188
- match & step. target {
189
- ExtractionStepTarget :: LoadManifest ( _ ) => {
203
+ match & step. action {
204
+ ExtractionStepKind :: LoadManifest => {
190
205
number_of_manifests += 1 ;
191
- total_load_duration += step. ms ;
192
206
}
193
- ExtractionStepTarget :: FetchFile ( _ ) => {
207
+ ExtractionStepKind :: Parse => {
194
208
number_of_files += 1 ;
195
- total_fetch_file_duration += step. ms ;
196
- }
197
- ExtractionStepTarget :: Parse ( _) => {
198
- total_parse_duration += step. ms ;
199
- }
200
- ExtractionStepTarget :: Extract ( _) => {
201
- total_extract_duration += step. ms ;
202
209
}
210
+ _ => { }
203
211
}
212
+ durations
213
+ . entry ( step. action )
214
+ . or_insert ( HumanReadableDuration ( 0 ) )
215
+ . add ( step. ms ) ;
204
216
}
205
- let ret = ExtractionSummary {
217
+ let total = start. elapsed ( ) . as_millis ( ) . into ( ) ;
218
+ for ( key, value) in & durations {
219
+ info ! ( "total duration ({key:?}): {value}" ) ;
220
+ }
221
+ info ! ( "total duration: {total}" ) ;
222
+ ExtractionSummary {
206
223
number_of_manifests,
207
224
number_of_files,
208
- total_load_duration : total_load_duration. into ( ) ,
209
- total_fetch_file_duration : total_fetch_file_duration. into ( ) ,
210
- total_parse_duration : total_parse_duration. into ( ) ,
211
- total_extract_duration : total_extract_duration. into ( ) ,
212
- total_duration : start. elapsed ( ) . as_millis ( ) . into ( ) ,
213
- } ;
214
- info ! ( "total loadimg duration: {}" , ret. total_load_duration) ;
215
- info ! (
216
- "total file fetching duration: {}" ,
217
- ret. total_fetch_file_duration
218
- ) ;
219
- info ! ( "total parsing duration: {}" , ret. total_parse_duration) ;
220
- info ! ( "total extracting duration: {}" , ret. total_extract_duration) ;
221
- info ! ( "total duration: {}" , ret. total_duration) ;
222
- ret
225
+ durations : DurationsSummary { durations, total } ,
226
+ }
223
227
}
224
228
225
229
pub fn emit_extraction_diagnostics (
0 commit comments