@@ -301,6 +301,18 @@ extension ProgressManager {
301
301
}
302
302
303
303
// MARK: Clean up dirty paths
304
+ internal struct ByteCountUpdateInfo {
305
+ let currentSummary : UInt64
306
+ let dirtyChildren : [ ( index: Int , manager: ProgressManager ) ]
307
+ let nonDirtySummaries : [ ( index: Int , summary: UInt64 , isAlive: Bool ) ]
308
+ let type : CountType
309
+ }
310
+
311
+ internal struct ByteCountUpdate {
312
+ let index : Int
313
+ let updatedSummary : UInt64
314
+ }
315
+
304
316
internal struct ThroughputUpdateInfo {
305
317
let currentSummary : [ UInt64 ]
306
318
let dirtyChildren : [ ( index: Int , manager: ProgressManager ) ]
@@ -323,6 +335,111 @@ extension ProgressManager {
323
335
let updatedSummary : Duration
324
336
}
325
337
338
+ internal mutating func getByteCountUpdateInfo( type: CountType ) -> ByteCountUpdateInfo {
339
+ let currentSummary : UInt64
340
+ var dirtyChildren : [ ( index: Int , manager: ProgressManager ) ] = [ ]
341
+ var nonDirtySummaries : [ ( index: Int , summary: UInt64 , isAlive: Bool ) ] = [ ]
342
+
343
+ switch type {
344
+ case . total:
345
+ var value : UInt64 = 0
346
+ ProgressManager . Properties. TotalByteCount. reduce ( into: & value, value: totalByteCount)
347
+ currentSummary = value
348
+
349
+ guard !children. isEmpty else {
350
+ return ByteCountUpdateInfo (
351
+ currentSummary: currentSummary,
352
+ dirtyChildren: [ ] ,
353
+ nonDirtySummaries: [ ] ,
354
+ type: type
355
+ )
356
+ }
357
+
358
+ for (idx, childState) in children. enumerated ( ) {
359
+ if childState. totalByteCount. isDirty {
360
+ if let child = childState. child {
361
+ dirtyChildren. append ( ( idx, child) )
362
+ }
363
+ } else {
364
+ let isAlive = childState. child != nil
365
+ nonDirtySummaries. append ( ( idx, childState. totalByteCount. value, isAlive) )
366
+ }
367
+ }
368
+
369
+ case . completed:
370
+ var value : UInt64 = 0
371
+ ProgressManager . Properties. CompletedByteCount. reduce ( into: & value, value: completedByteCount)
372
+ currentSummary = value
373
+
374
+ guard !children. isEmpty else {
375
+ return ByteCountUpdateInfo (
376
+ currentSummary: currentSummary,
377
+ dirtyChildren: [ ] ,
378
+ nonDirtySummaries: [ ] ,
379
+ type: type
380
+ )
381
+ }
382
+
383
+ for (idx, childState) in children. enumerated ( ) {
384
+ if childState. completedByteCount. isDirty {
385
+ if let child = childState. child {
386
+ dirtyChildren. append ( ( idx, child) )
387
+ }
388
+ } else {
389
+ let isAlive = childState. child != nil
390
+ nonDirtySummaries. append ( ( idx, childState. completedByteCount. value, isAlive) )
391
+ }
392
+ }
393
+ }
394
+
395
+ return ByteCountUpdateInfo (
396
+ currentSummary: currentSummary,
397
+ dirtyChildren: dirtyChildren,
398
+ nonDirtySummaries: nonDirtySummaries,
399
+ type: type
400
+ )
401
+ }
402
+
403
+ internal mutating func updateByteCount( _ updateInfo: ByteCountUpdateInfo , _ childUpdates: [ ByteCountUpdate ] ) -> UInt64 {
404
+ var value = updateInfo. currentSummary
405
+
406
+ switch updateInfo. type {
407
+ case . total:
408
+ // Apply updates from children that were dirty
409
+ for update in childUpdates {
410
+ children [ update. index] . totalByteCount = PropertyStateUInt64 ( value: update. updatedSummary, isDirty: false )
411
+ value = ProgressManager . Properties. TotalByteCount. merge ( value, update. updatedSummary)
412
+ }
413
+
414
+ // Apply values from non-dirty children
415
+ for (_, childSummary, isAlive) in updateInfo. nonDirtySummaries {
416
+ if isAlive {
417
+ value = ProgressManager . Properties. TotalByteCount. merge ( value, childSummary)
418
+ } else {
419
+ value = ProgressManager . Properties. TotalByteCount. finalSummary ( value, childSummary)
420
+ }
421
+ }
422
+
423
+ case . completed:
424
+ // Apply updates from children that were dirty
425
+ for update in childUpdates {
426
+ children [ update. index] . completedByteCount = PropertyStateUInt64 ( value: update. updatedSummary, isDirty: false )
427
+ value = ProgressManager . Properties. CompletedByteCount. merge ( value, update. updatedSummary)
428
+ }
429
+
430
+ // Apply values from non-dirty children
431
+ for (_, childSummary, isAlive) in updateInfo. nonDirtySummaries {
432
+ if isAlive {
433
+ value = ProgressManager . Properties. CompletedByteCount. merge ( value, childSummary)
434
+ } else {
435
+ value = ProgressManager . Properties. CompletedByteCount. finalSummary ( value, childSummary)
436
+ }
437
+ }
438
+ }
439
+
440
+ return value
441
+ }
442
+
326
443
internal mutating func getThroughputUpdateInfo( ) -> ThroughputUpdateInfo {
327
444
var currentSummary = ProgressManager . Properties. Throughput. defaultSummary
328
445
ProgressManager . Properties. Throughput. reduce ( into: & currentSummary, value: throughput)
0 commit comments