Skip to content

Commit

Permalink
Fix the bug in differentiate sectioned collection
Browse files Browse the repository at this point in the history
  • Loading branch information
ra1028 committed Aug 12, 2018
1 parent e38cf35 commit 96bfe11
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 30 deletions.
2 changes: 1 addition & 1 deletion DifferenceKit.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -143,8 +143,8 @@
6B5B4097211066BF00A931DB /* ElementPathTest.swift */,
6B5B4098211066BF00A931DB /* ChangesetTest.swift */,
6B5B4099211066BF00A931DB /* MeasurementTest.swift */,
6B5B409A211066BF00A931DB /* Info.plist */,
6B5B409B211066BF00A931DB /* TestTools.swift */,
6B5B409A211066BF00A931DB /* Info.plist */,
);
path = Tests;
sourceTree = "<group>";
Expand Down
40 changes: 11 additions & 29 deletions Sources/Algorithm.swift
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ public extension StagedChangeset where Collection: RangeReplaceableCollection, C
let contiguousTargetSections = ContiguousArray(targetSections.map { ContiguousArray($0.elements) })

var firstStageSections = ContiguousArray<Section>()
var secondStageSections = ContiguousArray<Section>()
var thirdStageSections = ContiguousArray<Section>()

var sourceElementTraces = contiguousSourceSections.map { section in
Expand All @@ -142,7 +143,9 @@ public extension StagedChangeset where Collection: RangeReplaceableCollection, C
var flattenSourceIdentifiers = ContiguousArray<ElementIdentifier>()
var flattenSourceElementPaths = ContiguousArray<ElementPath>()

secondStageSections.reserveCapacity(contiguousTargetSections.count)
thirdStageSections.reserveCapacity(contiguousTargetSections.count)

flattenSourceIdentifiers.reserveCapacity(flattenSourceCount)
flattenSourceElementPaths.reserveCapacity(flattenSourceCount)

Expand Down Expand Up @@ -254,7 +257,6 @@ public extension StagedChangeset where Collection: RangeReplaceableCollection, C
elementDeleted.append(sourceElementPath)
sourceElementTraces[sourceElementPath].isTracked = true
offsetByDelete += 1
continue
}

let section = Section(model: sourceSections[sourceSectionIndex].model, elements: firstStageElements)
Expand All @@ -265,15 +267,21 @@ public extension StagedChangeset where Collection: RangeReplaceableCollection, C
for targetSectionIndex in contiguousTargetSections.indices {
// Should not calculate the element updates/moves/insertions in the inserted section.
guard let sourceSectionIndex = sectionResult.metadata.targetReferences[targetSectionIndex] else {
secondStageSections.append(targetSections[targetSectionIndex])
thirdStageSections.append(targetSections[targetSectionIndex])
continue
}

var untrackedSourceIndex: Int? = 0
let targetElements = contiguousTargetSections[targetSectionIndex]

let section = Section(model: sourceSections[sourceSectionIndex].model, elements: targetElements)
thirdStageSections.append(section)
let sectionDeleteOffset = sectionResult.metadata.sourceTraces[sourceSectionIndex].deleteOffset

let secondStageSection = firstStageSections[sourceSectionIndex - sectionDeleteOffset]
secondStageSections.append(secondStageSection)

let thirdStageSection = Section(model: secondStageSection.model, elements: targetElements)
thirdStageSections.append(thirdStageSection)

for targetElementIndex in targetElements.indices {
untrackedSourceIndex = untrackedSourceIndex.flatMap { index in
Expand Down Expand Up @@ -324,32 +332,6 @@ public extension StagedChangeset where Collection: RangeReplaceableCollection, C
// The 2nd stage changeset includes only the section insertions and moves and the collection
// that its changes applied to 1st stage collection.
if !sectionResult.inserted.isEmpty || !sectionResult.moved.isEmpty {
var secondStageSections = ContiguousArray<Section>()
secondStageSections.reserveCapacity(contiguousTargetSections.count)

for targetSectionIndex in contiguousTargetSections.indices {
guard let sourceSectionIndex = sectionResult.metadata.targetReferences[targetSectionIndex] else {
secondStageSections.append(targetSections[targetSectionIndex])
continue
}

let sourceElements = contiguousSourceSections[sourceSectionIndex]
var sectionChangedElements = ContiguousArray<Element>()
sectionChangedElements.reserveCapacity(sourceElements.count)

for sourceElementIndex in sourceElements.indices {
guard let targetElementPath = sourceElementTraces[sourceSectionIndex][sourceElementIndex].reference else {
continue
}

let targetElement = contiguousTargetSections[targetElementPath]
sectionChangedElements.append(targetElement)
}

let section = Section(model: sourceSections[sourceSectionIndex].model, elements: sectionChangedElements)
secondStageSections.append(section)
}

changesets.append(
Changeset(
data: Collection(secondStageSections),
Expand Down
19 changes: 19 additions & 0 deletions Tests/AlgorithmTest.swift
Original file line number Diff line number Diff line change
Expand Up @@ -647,4 +647,23 @@ extension AlgorithmTestCase {

XCTAssertReproducible(source: source, target: target)
}

func testComplicated11() {
let source = [
Section(model: 1, elements: ["A", "B", "C", "D"]),
Section(model: 2, elements: ["E", "F", "G", "H", "I"]),
Section(model: 3, elements: ["J", "K", "L", "M"]),
Section(model: 4, elements: ["N", "O", "P", "Q"])
]

let target = [
Section(model: 1, elements: ["A", "B", "C", "D"]),
Section(model: 2, elements: ["G"]),
Section(model: 3, elements: ["E", "F", "H", "I"]),
Section(model: 3, elements: ["J", "K", "L", "M"]),
Section(model: 4, elements: ["N", "O", "P", "Q"])
]

XCTAssertReproducible(source: source, target: target)
}
}
1 change: 1 addition & 0 deletions Tests/TestTools.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import XCTest
import DifferenceKit

extension Int: Differentiable {}
extension String: Differentiable {}

enum D: Differentiable {
case a, b, c, d, e
Expand Down

0 comments on commit 96bfe11

Please sign in to comment.