@@ -312,6 +312,17 @@ extension ProgressManager {
312312 let updatedSummary : [ UInt64 ]
313313 }
314314
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+
315326 internal mutating func getThroughputUpdateInfo( ) -> ThroughputUpdateInfo {
316327 var currentSummary = ProgressManager . Properties. Throughput. defaultSummary
317328 ProgressManager . Properties. Throughput. reduce ( into: & currentSummary, value: throughput)
@@ -365,5 +376,59 @@ extension ProgressManager {
365376
366377 return value
367378 }
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+ }
368433 }
369434}
0 commit comments