Skip to content

Commit ef79f0c

Browse files
committed
refactor getUpdatedByteCount method
1 parent afe8651 commit ef79f0c

File tree

2 files changed

+130
-61
lines changed

2 files changed

+130
-61
lines changed

Sources/FoundationEssentials/ProgressManager/ProgressManager+Properties+Helpers.swift

Lines changed: 13 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -298,67 +298,19 @@ extension ProgressManager {
298298
}
299299

300300
internal func getUpdatedByteCount(type: CountType) -> UInt64 {
301-
switch type {
302-
case .total:
303-
return state.withLock { state in
304-
// Get self's totalByteCount as part of summary
305-
var value: UInt64 = 0
306-
ProgressManager.Properties.TotalByteCount.reduce(into: &value, value: state.totalByteCount)
307-
308-
guard !state.children.isEmpty else {
309-
return value
310-
}
311-
312-
for (idx, childState) in state.children.enumerated() {
313-
if childState.totalByteCount.isDirty {
314-
// Update dirty path
315-
if let child = childState.child {
316-
let updatedSummary = child.getUpdatedByteCount(type: type)
317-
let newTotalByteCountState = PropertyStateUInt64(value: updatedSummary, isDirty: false)
318-
state.children[idx].totalByteCount = newTotalByteCountState
319-
value = ProgressManager.Properties.TotalByteCount.merge(value, updatedSummary)
320-
}
321-
} else {
322-
if let _ = childState.child {
323-
// Merge non-dirty, updated value
324-
value = ProgressManager.Properties.TotalByteCount.merge(value, childState.totalByteCount.value)
325-
} else {
326-
value = ProgressManager.Properties.TotalByteCount.finalSummary(value, childState.totalByteCount.value)
327-
}
328-
}
329-
}
330-
return value
331-
}
332-
case .completed:
333-
return state.withLock { state in
334-
// Get self's completedByteCount as part of summary
335-
var value: UInt64 = 0
336-
ProgressManager.Properties.CompletedByteCount.reduce(into: &value, value: state.completedByteCount)
337-
338-
guard !state.children.isEmpty else {
339-
return value
340-
}
341-
342-
for (idx, childState) in state.children.enumerated() {
343-
if childState.completedByteCount.isDirty {
344-
// Update dirty path
345-
if let child = childState.child {
346-
let updatedSummary = child.getUpdatedByteCount(type: type)
347-
let newCompletedByteCountState = PropertyStateUInt64(value: updatedSummary, isDirty: false)
348-
state.children[idx].completedByteCount = newCompletedByteCountState
349-
value = ProgressManager.Properties.CompletedByteCount.merge(value, updatedSummary)
350-
}
351-
} else {
352-
if let _ = childState.child {
353-
// Merge non-dirty, updated value
354-
value = ProgressManager.Properties.CompletedByteCount.merge(value, childState.completedByteCount.value)
355-
} else {
356-
value = ProgressManager.Properties.CompletedByteCount.finalSummary(value, childState.completedByteCount.value)
357-
}
358-
}
359-
}
360-
return value
361-
}
301+
// Collect information from state
302+
let updateInfo = state.withLock { state in
303+
state.getByteCountUpdateInfo(type: type)
304+
}
305+
306+
// Get updated summary for each dirty child
307+
let updatedSummaries = updateInfo.dirtyChildren.map { (index, child) in
308+
State.ByteCountUpdate(index: index, updatedSummary: child.getUpdatedByteCount(type: type))
309+
}
310+
311+
// Consolidate updated values
312+
return state.withLock { state in
313+
state.updateByteCount(updateInfo, updatedSummaries)
362314
}
363315
}
364316

Sources/FoundationEssentials/ProgressManager/ProgressManager+State.swift

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,18 @@ extension ProgressManager {
301301
}
302302

303303
// 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+
304316
internal struct ThroughputUpdateInfo {
305317
let currentSummary: [UInt64]
306318
let dirtyChildren: [(index: Int, manager: ProgressManager)]
@@ -323,6 +335,111 @@ extension ProgressManager {
323335
let updatedSummary: Duration
324336
}
325337

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+
326443
internal mutating func getThroughputUpdateInfo() -> ThroughputUpdateInfo {
327444
var currentSummary = ProgressManager.Properties.Throughput.defaultSummary
328445
ProgressManager.Properties.Throughput.reduce(into: &currentSummary, value: throughput)

0 commit comments

Comments
 (0)