@@ -301,6 +301,18 @@ extension ProgressManager {
301301 }
302302
303303 // MARK: Clean up dirty paths
304+ internal struct FileCountUpdateInfo {
305+ let currentSummary : Int
306+ let dirtyChildren : [ ( index: Int , manager: ProgressManager ) ]
307+ let nonDirtySummaries : [ ( index: Int , summary: Int , isAlive: Bool ) ]
308+ let type : CountType
309+ }
310+
311+ internal struct FileCountUpdate {
312+ let index : Int
313+ let updatedSummary : Int
314+ }
315+
304316 internal struct ByteCountUpdateInfo {
305317 let currentSummary : UInt64
306318 let dirtyChildren : [ ( index: Int , manager: ProgressManager ) ]
@@ -335,6 +347,111 @@ extension ProgressManager {
335347 let updatedSummary : Duration
336348 }
337349
350+ internal mutating func getFileCountUpdateInfo( type: CountType ) -> FileCountUpdateInfo {
351+ let currentSummary : Int
352+ var dirtyChildren : [ ( index: Int , manager: ProgressManager ) ] = [ ]
353+ var nonDirtySummaries : [ ( index: Int , summary: Int , isAlive: Bool ) ] = [ ]
354+
355+ switch type {
356+ case . total:
357+ var value : Int = 0
358+ ProgressManager . Properties. TotalFileCount. reduce ( into: & value, value: totalFileCount)
359+ currentSummary = value
360+
361+ guard !children. isEmpty else {
362+ return FileCountUpdateInfo (
363+ currentSummary: currentSummary,
364+ dirtyChildren: [ ] ,
365+ nonDirtySummaries: [ ] ,
366+ type: type
367+ )
368+ }
369+
370+ for (idx, childState) in children. enumerated ( ) {
371+ if childState. totalFileCount. isDirty {
372+ if let child = childState. child {
373+ dirtyChildren. append ( ( idx, child) )
374+ }
375+ } else {
376+ let isAlive = childState. child != nil
377+ nonDirtySummaries. append ( ( idx, childState. totalFileCount. value, isAlive) )
378+ }
379+ }
380+
381+ case . completed:
382+ var value : Int = 0
383+ ProgressManager . Properties. CompletedFileCount. reduce ( into: & value, value: completedFileCount)
384+ currentSummary = value
385+
386+ guard !children. isEmpty else {
387+ return FileCountUpdateInfo (
388+ currentSummary: currentSummary,
389+ dirtyChildren: [ ] ,
390+ nonDirtySummaries: [ ] ,
391+ type: type
392+ )
393+ }
394+
395+ for (idx, childState) in children. enumerated ( ) {
396+ if childState. completedFileCount. 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. completedFileCount. value, isAlive) )
403+ }
404+ }
405+ }
406+
407+ return FileCountUpdateInfo (
408+ currentSummary: currentSummary,
409+ dirtyChildren: dirtyChildren,
410+ nonDirtySummaries: nonDirtySummaries,
411+ type: type
412+ )
413+ }
414+
415+ internal mutating func updateFileCount( _ updateInfo: FileCountUpdateInfo , _ childUpdates: [ FileCountUpdate ] ) -> Int {
416+ var value = updateInfo. currentSummary
417+
418+ switch updateInfo. type {
419+ case . total:
420+ // Apply updates from children that were dirty
421+ for update in childUpdates {
422+ children [ update. index] . totalFileCount = PropertyStateInt ( value: update. updatedSummary, isDirty: false )
423+ value = ProgressManager . Properties. TotalFileCount. merge ( value, update. updatedSummary)
424+ }
425+
426+ // Apply values from non-dirty children
427+ for (_, childSummary, isAlive) in updateInfo. nonDirtySummaries {
428+ if isAlive {
429+ value = ProgressManager . Properties. TotalFileCount. merge ( value, childSummary)
430+ } else {
431+ value = ProgressManager . Properties. TotalFileCount. finalSummary ( value, childSummary)
432+ }
433+ }
434+
435+ case . completed:
436+ // Apply updates from children that were dirty
437+ for update in childUpdates {
438+ children [ update. index] . completedFileCount = PropertyStateInt ( value: update. updatedSummary, isDirty: false )
439+ value = ProgressManager . Properties. CompletedFileCount. merge ( value, update. updatedSummary)
440+ }
441+
442+ // Apply values from non-dirty children
443+ for (_, childSummary, isAlive) in updateInfo. nonDirtySummaries {
444+ if isAlive {
445+ value = ProgressManager . Properties. CompletedFileCount. merge ( value, childSummary)
446+ } else {
447+ value = ProgressManager . Properties. CompletedFileCount. finalSummary ( value, childSummary)
448+ }
449+ }
450+ }
451+
452+ return value
453+ }
454+
338455 internal mutating func getByteCountUpdateInfo( type: CountType ) -> ByteCountUpdateInfo {
339456 let currentSummary : UInt64
340457 var dirtyChildren : [ ( index: Int , manager: ProgressManager ) ] = [ ]
0 commit comments