@@ -312,6 +312,17 @@ extension ProgressManager {
312
312
let updatedSummary : [ UInt64 ]
313
313
}
314
314
315
+ internal struct EstimatedTimeRemainingUpdateInfo {
316
+ let currentSummary : Duration
317
+ let dirtyChildren : [ ( index: Int , manager: ProgressManager ) ]
318
+ let nonDirtySummaries : [ ( index: Int , summary: Duration , isAlive: Bool ) ]
319
+ }
320
+
321
+ internal struct EstimatedTimeRemainingUpdate {
322
+ let index : Int
323
+ let updatedSummary : Duration
324
+ }
325
+
315
326
internal mutating func getThroughputUpdateInfo( ) -> ThroughputUpdateInfo {
316
327
var currentSummary = ProgressManager . Properties. Throughput. defaultSummary
317
328
ProgressManager . Properties. Throughput. reduce ( into: & currentSummary, value: throughput)
@@ -365,5 +376,59 @@ extension ProgressManager {
365
376
366
377
return value
367
378
}
379
+
380
+ internal mutating func getEstimatedTimeRemainingUpdateInfo( ) -> EstimatedTimeRemainingUpdateInfo {
381
+ var currentSummary : Duration = Duration . seconds ( 0 )
382
+ ProgressManager . Properties. EstimatedTimeRemaining. reduce ( into: & currentSummary, value: estimatedTimeRemaining)
383
+
384
+ guard !children. isEmpty else {
385
+ return EstimatedTimeRemainingUpdateInfo (
386
+ currentSummary: currentSummary,
387
+ dirtyChildren: [ ] ,
388
+ nonDirtySummaries: [ ]
389
+ )
390
+ }
391
+
392
+ var dirtyChildren : [ ( index: Int , manager: ProgressManager ) ] = [ ]
393
+ var nonDirtySummaries : [ ( index: Int , summary: Duration , isAlive: Bool ) ] = [ ]
394
+
395
+ for (idx, childState) in children. enumerated ( ) {
396
+ if childState. estimatedTimeRemaining. isDirty {
397
+ if let child = childState. child {
398
+ dirtyChildren. append ( ( idx, child) )
399
+ }
400
+ } else {
401
+ let isAlive = childState. child != nil
402
+ nonDirtySummaries. append ( ( idx, childState. estimatedTimeRemaining. value, isAlive) )
403
+ }
404
+ }
405
+
406
+ return EstimatedTimeRemainingUpdateInfo (
407
+ currentSummary: currentSummary,
408
+ dirtyChildren: dirtyChildren,
409
+ nonDirtySummaries: nonDirtySummaries
410
+ )
411
+ }
412
+
413
+ internal mutating func updateEstimatedTimeRemaining( _ updateInfo: EstimatedTimeRemainingUpdateInfo , _ childUpdates: [ EstimatedTimeRemainingUpdate ] ) -> Duration {
414
+ var value = updateInfo. currentSummary
415
+
416
+ // Apply updates from children that were dirty
417
+ for update in childUpdates {
418
+ children [ update. index] . estimatedTimeRemaining = PropertyStateDuration ( value: update. updatedSummary, isDirty: false )
419
+ value = ProgressManager . Properties. EstimatedTimeRemaining. merge ( value, update. updatedSummary)
420
+ }
421
+
422
+ // Apply values from non-dirty children
423
+ for (_, childSummary, isAlive) in updateInfo. nonDirtySummaries {
424
+ if isAlive {
425
+ value = ProgressManager . Properties. EstimatedTimeRemaining. merge ( value, childSummary)
426
+ } else {
427
+ value = ProgressManager . Properties. EstimatedTimeRemaining. finalSummary ( value, childSummary)
428
+ }
429
+ }
430
+
431
+ return value
432
+ }
368
433
}
369
434
}
0 commit comments