@@ -160,103 +160,211 @@ impl SiteCtxt {
160
160
. unwrap ( ) ;
161
161
162
162
let index = self . index . load ( ) ;
163
- let mut all_commits = index
163
+ let all_commits = index
164
164
. commits ( )
165
165
. iter ( )
166
166
. map ( |commit| commit. sha . clone ( ) )
167
167
. collect :: < HashSet < _ > > ( ) ;
168
168
169
- let now = Utc :: now ( ) ;
170
- let mut master_commits = master_commits
171
- . into_iter ( )
172
- . filter ( |c| now. signed_duration_since ( c. time ) < Duration :: days ( 29 ) )
173
- . map ( |c| {
174
- (
175
- Commit {
176
- sha : c. sha ,
177
- date : Date ( c. time ) ,
178
- } ,
179
- // All recent master commits should have an associated PR
180
- MissingReason :: Master {
181
- pr : c. pr . unwrap_or ( 0 ) ,
182
- parent_sha : c. parent_sha ,
183
- } ,
184
- )
185
- } )
186
- . collect :: < Vec < _ > > ( ) ;
187
- master_commits. reverse ( ) ;
169
+ calculate_missing (
170
+ master_commits,
171
+ queued_pr_commits,
172
+ in_progress_artifacts,
173
+ all_commits,
174
+ )
175
+ }
176
+ }
188
177
189
- let mut missing = Vec :: with_capacity ( queued_pr_commits. len ( ) * 2 + master_commits. len ( ) ) ; // Two commits per every try commit and all master commits
190
- for database:: QueuedCommit {
191
- sha,
192
- parent_sha,
193
- pr,
194
- include,
195
- exclude,
196
- runs,
197
- } in queued_pr_commits
198
- . into_iter ( )
199
- // filter out any queued PR master commits (leaving only try commits)
200
- . filter ( |c| !master_commits. iter ( ) . any ( |( mc, _) | mc. sha == c. sha ) )
201
- {
202
- // Enqueue the `TryParent` commit before the `TryCommit` itself, so that
203
- // all of the `try` run's data is complete when the benchmark results
204
- // of that commit are available.
205
- if let Some ( ( try_parent, _) ) = master_commits
206
- . iter ( )
207
- . find ( |( m, _) | m. sha == parent_sha. as_str ( ) )
208
- {
209
- missing. push ( ( try_parent. clone ( ) , MissingReason :: TryParent ) ) ;
210
- }
211
- missing. push ( (
178
+ fn calculate_missing (
179
+ master_commits : Vec < collector:: MasterCommit > ,
180
+ queued_pr_commits : Vec < database:: QueuedCommit > ,
181
+ in_progress_artifacts : Vec < ArtifactId > ,
182
+ mut all_commits : HashSet < String > ,
183
+ ) -> Vec < ( Commit , MissingReason ) > {
184
+ let now = Utc :: now ( ) ;
185
+ let mut master_commits = master_commits
186
+ . into_iter ( )
187
+ . filter ( |c| now. signed_duration_since ( c. time ) < Duration :: days ( 29 ) )
188
+ . map ( |c| {
189
+ (
212
190
Commit {
213
- sha : sha . to_string ( ) ,
214
- date : Date :: ymd_hms ( 2001 , 01 , 01 , 0 , 0 , 0 ) ,
191
+ sha : c . sha ,
192
+ date : Date ( c . time ) ,
215
193
} ,
216
- MissingReason :: Try {
217
- pr,
218
- include,
219
- exclude,
220
- runs,
194
+ // All recent master commits should have an associated PR
195
+ MissingReason :: Master {
196
+ pr : c. pr . unwrap_or ( 0 ) ,
197
+ parent_sha : c. parent_sha ,
221
198
} ,
222
- ) ) ;
199
+ )
200
+ } )
201
+ . collect :: < Vec < _ > > ( ) ;
202
+ master_commits. reverse ( ) ;
203
+ let mut missing = Vec :: with_capacity ( queued_pr_commits. len ( ) * 2 + master_commits. len ( ) ) ;
204
+ for database:: QueuedCommit {
205
+ sha,
206
+ parent_sha,
207
+ pr,
208
+ include,
209
+ exclude,
210
+ runs,
211
+ } in queued_pr_commits
212
+ . into_iter ( )
213
+ // filter out any queued PR master commits (leaving only try commits)
214
+ . filter ( |c| !master_commits. iter ( ) . any ( |( mc, _) | mc. sha == c. sha ) )
215
+ {
216
+ // Enqueue the `TryParent` commit before the `TryCommit` itself, so that
217
+ // all of the `try` run's data is complete when the benchmark results
218
+ // of that commit are available.
219
+ if let Some ( ( try_parent, _) ) = master_commits
220
+ . iter ( )
221
+ . find ( |( m, _) | m. sha == parent_sha. as_str ( ) )
222
+ {
223
+ missing. push ( ( try_parent. clone ( ) , MissingReason :: TryParent ) ) ;
223
224
}
224
- missing. extend ( master_commits) ;
225
-
226
- for aid in in_progress_artifacts {
227
- match aid {
228
- ArtifactId :: Commit ( c) => {
229
- let previous = missing
230
- . iter ( )
231
- . find ( |( i, _) | i. sha == c. sha )
232
- . map ( |v| Box :: new ( v. 1 . clone ( ) ) ) ;
233
- all_commits. remove ( & c. sha ) ;
234
- missing. insert ( 0 , ( c, MissingReason :: InProgress ( previous) ) ) ;
235
- }
236
- ArtifactId :: Tag ( _) => {
237
- // do nothing, for now, though eventually we'll want an artifact queue
238
- }
225
+ missing. push ( (
226
+ Commit {
227
+ sha : sha. to_string ( ) ,
228
+ date : Date :: ymd_hms ( 2001 , 01 , 01 , 0 , 0 , 0 ) ,
229
+ } ,
230
+ MissingReason :: Try {
231
+ pr,
232
+ include,
233
+ exclude,
234
+ runs,
235
+ } ,
236
+ ) ) ;
237
+ }
238
+ missing. extend ( master_commits) ;
239
+ for aid in in_progress_artifacts {
240
+ match aid {
241
+ ArtifactId :: Commit ( c) => {
242
+ let previous = missing
243
+ . iter ( )
244
+ . find ( |( i, _) | i. sha == c. sha )
245
+ . map ( |v| Box :: new ( v. 1 . clone ( ) ) ) ;
246
+ all_commits. remove ( & c. sha ) ;
247
+ missing. insert ( 0 , ( c, MissingReason :: InProgress ( previous) ) ) ;
239
248
}
240
- }
241
-
242
- let mut already_tested = HashSet :: with_capacity ( all_commits. len ( ) ) ;
243
- already_tested. extend ( all_commits) ;
244
-
245
- // Remove commits from missing that have already been tested
246
- // FIXME: replace with Vec::drain_filter when it stabilizes
247
- let mut i = 0 ;
248
- while i != missing. len ( ) {
249
- if !already_tested. insert ( missing[ i] . 0 . sha . clone ( ) ) {
250
- missing. remove ( i) ;
251
- } else {
252
- i += 1 ;
249
+ ArtifactId :: Tag ( _) => {
250
+ // do nothing, for now, though eventually we'll want an artifact queue
253
251
}
254
252
}
255
-
256
- missing
257
253
}
254
+ let mut already_tested = HashSet :: with_capacity ( all_commits. len ( ) ) ;
255
+ already_tested. extend ( all_commits) ;
256
+ let mut i = 0 ;
257
+ while i != missing. len ( ) {
258
+ if !already_tested. insert ( missing[ i] . 0 . sha . clone ( ) ) {
259
+ missing. remove ( i) ;
260
+ } else {
261
+ i += 1 ;
262
+ }
263
+ }
264
+ missing
258
265
}
259
266
260
267
/// One decimal place rounded percent
261
268
#[ derive( Debug , Copy , Clone , PartialEq , Serialize , Deserialize ) ]
262
269
pub struct Percent ( #[ serde( with = "collector::round_float" ) ] pub f64 ) ;
270
+
271
+ #[ cfg( test) ]
272
+ mod tests {
273
+ use std:: str:: FromStr ;
274
+
275
+ use collector:: MasterCommit ;
276
+ use database:: QueuedCommit ;
277
+
278
+ use super :: * ;
279
+ #[ test]
280
+ fn calculates_missing_correct ( ) {
281
+ let time = chrono:: DateTime :: from_str ( "2021-09-01T00:00:00.000Z" ) . unwrap ( ) ;
282
+ let master_commits = vec ! [
283
+ // A not yet tested commit
284
+ MasterCommit {
285
+ sha: "123" . into( ) ,
286
+ parent_sha: "345" . into( ) ,
287
+ pr: Some ( 11 ) ,
288
+ time,
289
+ } ,
290
+ // An already tested commit
291
+ MasterCommit {
292
+ sha: "abc" . into( ) ,
293
+ parent_sha: "def" . into( ) ,
294
+ pr: Some ( 90 ) ,
295
+ time,
296
+ } ,
297
+ // A queued PR commit
298
+ MasterCommit {
299
+ sha: "foo" . into( ) ,
300
+ parent_sha: "bar" . into( ) ,
301
+ pr: Some ( 77 ) ,
302
+ time,
303
+ } ,
304
+ ] ;
305
+ let queued_pr_commits = vec ! [
306
+ // A master commit
307
+ QueuedCommit {
308
+ sha: "foo" . into( ) ,
309
+ parent_sha: "bar" . into( ) ,
310
+ pr: 77 ,
311
+ include: None ,
312
+ exclude: None ,
313
+ runs: None ,
314
+ } ,
315
+ // A try run
316
+ QueuedCommit {
317
+ sha: "baz" . into( ) ,
318
+ parent_sha: "foo" . into( ) ,
319
+ pr: 101 ,
320
+ include: None ,
321
+ exclude: None ,
322
+ runs: None ,
323
+ } ,
324
+ ] ;
325
+ let in_progress_artifacts = vec ! [ ] ;
326
+ let mut all_commits = HashSet :: new ( ) ;
327
+ all_commits. insert ( master_commits[ 1 ] . sha . clone ( ) ) ;
328
+
329
+ let expected = vec ! [
330
+ (
331
+ Commit {
332
+ sha: "foo" . into( ) ,
333
+ date: database:: Date ( time) ,
334
+ } ,
335
+ MissingReason :: TryParent ,
336
+ ) ,
337
+ (
338
+ Commit {
339
+ sha: "baz" . into( ) ,
340
+ date: database:: Date ( time) ,
341
+ } ,
342
+ MissingReason :: Try {
343
+ pr: 101 ,
344
+ include: None ,
345
+ exclude: None ,
346
+ runs: None ,
347
+ } ,
348
+ ) ,
349
+ (
350
+ Commit {
351
+ sha: "123" . into( ) ,
352
+ date: database:: Date ( time) ,
353
+ } ,
354
+ MissingReason :: Master {
355
+ pr: 11 ,
356
+ parent_sha: "345" . into( ) ,
357
+ } ,
358
+ ) ,
359
+ ] ;
360
+ assert_eq ! (
361
+ expected,
362
+ calculate_missing(
363
+ master_commits,
364
+ queued_pr_commits,
365
+ in_progress_artifacts,
366
+ all_commits
367
+ )
368
+ ) ;
369
+ }
370
+ }
0 commit comments