Skip to content

Commit 8193d6c

Browse files
committed
refactor markSelfDirty methods + getUpdatedThroughput method
1 parent c977d01 commit 8193d6c

File tree

3 files changed

+154
-54
lines changed

3 files changed

+154
-54
lines changed

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

Lines changed: 23 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -363,34 +363,19 @@ extension ProgressManager {
363363
}
364364

365365
internal func getUpdatedThroughput() -> [UInt64] {
366+
// Collect information from state
367+
let updateInfo = state.withLock { state in
368+
state.getThroughputUpdateInfo()
369+
}
370+
371+
// Get updated summary for each dirty child
372+
let updatedSummaries = updateInfo.dirtyChildren.map { (index, child) in
373+
State.ThroughputUpdate(index: index, updatedSummary: child.getUpdatedThroughput())
374+
}
375+
376+
// Consolidate updated values
366377
return state.withLock { state in
367-
// Get self's throughput as part of summary
368-
var value = ProgressManager.Properties.Throughput.defaultSummary
369-
ProgressManager.Properties.Throughput.reduce(into: &value, value: state.throughput)
370-
371-
guard !state.children.isEmpty else {
372-
return value
373-
}
374-
375-
for (idx, childState) in state.children.enumerated() {
376-
if childState.throughput.isDirty {
377-
// Update dirty path
378-
if let child = childState.child {
379-
let updatedSummary = child.getUpdatedThroughput()
380-
let newThroughputState = PropertyStateThroughput(value: updatedSummary, isDirty: false)
381-
state.children[idx].throughput = newThroughputState
382-
value = ProgressManager.Properties.Throughput.merge(value, updatedSummary)
383-
}
384-
} else {
385-
if let _ = childState.child {
386-
// Merge non-dirty, updated value
387-
value = ProgressManager.Properties.Throughput.merge(value, childState.throughput.value)
388-
} else {
389-
value = ProgressManager.Properties.Throughput.finalSummary(value, childState.throughput.value)
390-
}
391-
}
392-
}
393-
return value
378+
state.getUpdatedThroughput(updateInfo, updatedSummaries)
394379
}
395380
}
396381

@@ -518,88 +503,77 @@ extension ProgressManager {
518503

519504
internal func markChildDirty(property: MetatypeWrapper<Int, Int>, at position: Int) {
520505
let parents = state.withLock { state in
521-
state.children[position].childPropertiesInt[property]?.isDirty = true
522-
return state.parents
506+
state.markChildDirty(property: property, at: position)
523507
}
524508
markSelfDirty(property: property, parents: parents)
525509
}
526510

527511
internal func markChildDirty(property: MetatypeWrapper<Double, Double>, at position: Int) {
528512
let parents = state.withLock { state in
529-
state.children[position].childPropertiesDouble[property]?.isDirty = true
530-
return state.parents
513+
state.markChildDirty(property: property, at: position)
531514
}
532515
markSelfDirty(property: property, parents: parents)
533516
}
534517

535518
internal func markChildDirty(property: MetatypeWrapper<String?, [String?]>, at position: Int) {
536519
let parents = state.withLock { state in
537-
state.children[position].childPropertiesString[property]?.isDirty = true
538-
return state.parents
520+
state.markChildDirty(property: property, at: position)
539521
}
540522
markSelfDirty(property: property, parents: parents)
541523
}
542524

543525
internal func markChildDirty(property: MetatypeWrapper<URL?, [URL?]>, at position: Int) {
544526
let parents = state.withLock { state in
545-
state.children[position].childPropertiesURL[property]?.isDirty = true
546-
return state.parents
527+
state.markChildDirty(property: property, at: position)
547528
}
548529
markSelfDirty(property: property, parents: parents)
549530
}
550531

551532
internal func markChildDirty(property: MetatypeWrapper<UInt64, [UInt64]>, at position: Int) {
552533
let parents = state.withLock { state in
553-
state.children[position].childPropertiesUInt64[property]?.isDirty = true
554-
return state.parents
534+
state.markChildDirty(property: property, at: position)
555535
}
556536
markSelfDirty(property: property, parents: parents)
557537
}
558538

559539
internal func markChildDirty(property: ProgressManager.Properties.TotalFileCount.Type, at position: Int) {
560540
let parents = state.withLock { state in
561-
state.children[position].totalFileCount.isDirty = true
562-
return state.parents
541+
state.markChildDirty(property: property, at: position)
563542
}
564543
markSelfDirty(property: property, parents: parents)
565544
}
566545

567546
internal func markChildDirty(property: ProgressManager.Properties.CompletedFileCount.Type, at position: Int) {
568547
let parents = state.withLock { state in
569-
state.children[position].completedFileCount.isDirty = true
570-
return state.parents
548+
state.markChildDirty(property: property, at: position)
571549
}
572550
markSelfDirty(property: property, parents: parents)
573551
}
574552

575553
internal func markChildDirty(property: ProgressManager.Properties.TotalByteCount.Type, at position: Int) {
576554
let parents = state.withLock { state in
577-
state.children[position].totalByteCount.isDirty = true
578-
return state.parents
555+
state.markChildDirty(property: property, at: position)
579556
}
580557
markSelfDirty(property: property, parents: parents)
581558
}
582559

583560
internal func markChildDirty(property: ProgressManager.Properties.CompletedByteCount.Type, at position: Int) {
584561
let parents = state.withLock { state in
585-
state.children[position].completedByteCount.isDirty = true
586-
return state.parents
562+
state.markChildDirty(property: property, at: position)
587563
}
588564
markSelfDirty(property: property, parents: parents)
589565
}
590566

591567
internal func markChildDirty(property: ProgressManager.Properties.Throughput.Type, at position: Int) {
592568
let parents = state.withLock { state in
593-
state.children[position].throughput.isDirty = true
594-
return state.parents
569+
state.markChildDirty(property: property, at: position)
595570
}
596571
markSelfDirty(property: property, parents: parents)
597572
}
598573

599574
internal func markChildDirty(property: ProgressManager.Properties.EstimatedTimeRemaining.Type, at position: Int) {
600575
let parents = state.withLock { state in
601-
state.children[position].estimatedTimeRemaining.isDirty = true
602-
return state.parents
576+
state.markChildDirty(property: property, at: position)
603577
}
604578
markSelfDirty(property: property, parents: parents)
605579
}

Sources/FoundationEssentials/ProgressManager/ProgressManager+State.swift

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,5 +235,135 @@ extension ProgressManager {
235235
}
236236
#endif
237237
}
238+
239+
// MARK: Mark paths dirty
240+
internal mutating func markChildDirty(at position: Int) -> [ParentState]? {
241+
guard !children[position].isDirty else {
242+
return nil
243+
}
244+
children[position].isDirty = true
245+
return parents
246+
}
247+
248+
internal mutating func markChildDirty(property: MetatypeWrapper<Int, Int>, at position: Int) -> [ParentState] {
249+
children[position].childPropertiesInt[property]?.isDirty = true
250+
return parents
251+
}
252+
253+
internal mutating func markChildDirty(property: MetatypeWrapper<Double, Double>, at position: Int) -> [ParentState] {
254+
children[position].childPropertiesDouble[property]?.isDirty = true
255+
return parents
256+
}
257+
258+
internal mutating func markChildDirty(property: MetatypeWrapper<String?, [String?]>, at position: Int) -> [ParentState] {
259+
children[position].childPropertiesString[property]?.isDirty = true
260+
return parents
261+
}
262+
263+
internal mutating func markChildDirty(property: MetatypeWrapper<URL?, [URL?]>, at position: Int) -> [ParentState] {
264+
children[position].childPropertiesURL[property]?.isDirty = true
265+
return parents
266+
}
267+
268+
internal mutating func markChildDirty(property: MetatypeWrapper<UInt64, [UInt64]>, at position: Int) -> [ParentState] {
269+
children[position].childPropertiesUInt64[property]?.isDirty = true
270+
return parents
271+
}
272+
273+
internal mutating func markChildDirty(property: ProgressManager.Properties.TotalFileCount.Type, at position: Int) -> [ParentState] {
274+
children[position].totalFileCount.isDirty = true
275+
return parents
276+
}
277+
278+
internal mutating func markChildDirty(property: ProgressManager.Properties.CompletedFileCount.Type, at position: Int) -> [ParentState] {
279+
children[position].completedFileCount.isDirty = true
280+
return parents
281+
}
282+
283+
internal mutating func markChildDirty(property: ProgressManager.Properties.TotalByteCount.Type, at position: Int) -> [ParentState] {
284+
children[position].totalByteCount.isDirty = true
285+
return parents
286+
}
287+
288+
internal mutating func markChildDirty(property: ProgressManager.Properties.CompletedByteCount.Type, at position: Int) -> [ParentState] {
289+
children[position].completedByteCount.isDirty = true
290+
return parents
291+
}
292+
293+
internal mutating func markChildDirty(property: ProgressManager.Properties.Throughput.Type, at position: Int) -> [ParentState] {
294+
children[position].throughput.isDirty = true
295+
return parents
296+
}
297+
298+
internal mutating func markChildDirty(property: ProgressManager.Properties.EstimatedTimeRemaining.Type, at position: Int) -> [ParentState] {
299+
children[position].estimatedTimeRemaining.isDirty = true
300+
return parents
301+
}
302+
303+
// MARK: Clean up dirty paths
304+
internal struct ThroughputUpdateInfo {
305+
let currentSummary: [UInt64]
306+
let dirtyChildren: [(index: Int, manager: ProgressManager)]
307+
let nonDirtySummaries: [(index: Int, summary: [UInt64], isAlive: Bool)]
308+
}
309+
310+
internal struct ThroughputUpdate {
311+
let index: Int
312+
let updatedSummary: [UInt64]
313+
}
314+
315+
internal mutating func getThroughputUpdateInfo() -> ThroughputUpdateInfo {
316+
var currentSummary = ProgressManager.Properties.Throughput.defaultSummary
317+
ProgressManager.Properties.Throughput.reduce(into: &currentSummary, value: throughput)
318+
319+
guard !children.isEmpty else {
320+
return ThroughputUpdateInfo(
321+
currentSummary: currentSummary,
322+
dirtyChildren: [],
323+
nonDirtySummaries: []
324+
)
325+
}
326+
327+
var dirtyChildren: [(index: Int, manager: ProgressManager)] = []
328+
var nonDirtySummaries: [(index: Int, summary: [UInt64], isAlive: Bool)] = []
329+
330+
for (idx, childState) in children.enumerated() {
331+
if childState.throughput.isDirty {
332+
if let child = childState.child {
333+
dirtyChildren.append((idx, child))
334+
}
335+
} else {
336+
let isAlive = childState.child != nil
337+
nonDirtySummaries.append((idx, childState.throughput.value, isAlive))
338+
}
339+
}
340+
341+
return ThroughputUpdateInfo(
342+
currentSummary: currentSummary,
343+
dirtyChildren: dirtyChildren,
344+
nonDirtySummaries: nonDirtySummaries
345+
)
346+
}
347+
348+
internal mutating func getUpdatedThroughput(_ updateInfo: ThroughputUpdateInfo, _ childUpdates: [ThroughputUpdate]) -> [UInt64] {
349+
var value = updateInfo.currentSummary
350+
351+
// Apply updates from children that were dirty
352+
for update in childUpdates {
353+
children[update.index].throughput = PropertyStateThroughput(value: update.updatedSummary, isDirty: false)
354+
value = ProgressManager.Properties.Throughput.merge(value, update.updatedSummary)
355+
}
356+
357+
// Apply values from non-dirty children
358+
for (_, childSummary, isAlive) in updateInfo.nonDirtySummaries {
359+
if isAlive {
360+
value = ProgressManager.Properties.Throughput.merge(value, childSummary)
361+
} else {
362+
value = ProgressManager.Properties.Throughput.finalSummary(value, childSummary)
363+
}
364+
}
365+
366+
return value
367+
}
238368
}
239369
}

Sources/FoundationEssentials/ProgressManager/ProgressManager.swift

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -227,11 +227,7 @@ internal import _FoundationCollections
227227

228228
private func markChildDirty(at position: Int) {
229229
let parents: [ParentState]? = state.withLock { state in
230-
guard !state.children[position].isDirty else {
231-
return nil
232-
}
233-
state.children[position].isDirty = true
234-
return state.parents
230+
state.markChildDirty(at: position)
235231
}
236232
if let parents = parents {
237233
markSelfDirty(parents: parents)

0 commit comments

Comments
 (0)