Skip to content

Commit ed3fafe

Browse files
committed
fix(model-sync-lib): eliminated unnecessary operations in some cases
1 parent 15e7c6d commit ed3fafe

File tree

1 file changed

+27
-25
lines changed

1 file changed

+27
-25
lines changed

model-sync-lib/src/main/kotlin/org/modelix/model/sync/ModelImporter.kt

Lines changed: 27 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@ class ModelImporter(private val root: INode, val stats: ImportStats? = null) {
3434
buildRefIndex(root)
3535

3636
syncAllReferences(root, data.root)
37-
syncAllChildOrders(root, data.root)
3837
}
3938

4039
private fun buildExistingIndex(root: INode) {
@@ -91,24 +90,27 @@ class ModelImporter(private val root: INode, val stats: ImportStats? = null) {
9190
val existingIds = node.allChildren.map { it.originalId() }.toSet()
9291
val missingNodes = specifiedNodes.filter { !existingIds.contains(it.originalId()) }
9392

94-
val toBeMovedHere = missingNodes.filter { originalIdToExisting.containsKey(it.originalId()) }.toSet()
95-
val toBeAdded = missingNodes.subtract(toBeMovedHere)
93+
val toBeRemoved = node.allChildren.filter { !originalIdToSpec.contains(it.originalId()) }
94+
toBeRemoved.forEach { node.removeChildWithStats(it) }
9695

97-
toBeAdded.forEach {
98-
val index = nodeData.children.indexOf(it)
99-
node.addNewChildWithStats(it, index)
100-
}
96+
val toBeMovedAwayFromHere = existingIds.subtract(specifiedNodes.map { it.originalId() }.toSet())
97+
98+
syncExistingChildOrder(node, nodeData, existingIds, toBeMovedAwayFromHere)
10199

100+
val toBeMovedHere = missingNodes.filter { originalIdToExisting.containsKey(it.originalId()) }.toSet()
102101
toBeMovedHere.forEach {
103102
val actualNode = originalIdToExisting[it.originalId()]
104-
val targetIndex = it.getIndexWithinRole(nodeData)
103+
val targetIndex = it.getIndexWithinRole(nodeData,existingIds.size - 1)
105104
if (actualNode != null) {
106105
node.moveChildWithStats(it.role, targetIndex, actualNode)
107106
}
108107
}
109108

110-
val toBeRemoved = node.allChildren.filter { !originalIdToSpec.contains(it.originalId()) }
111-
toBeRemoved.forEach { node.removeChildWithStats(it) }
109+
val toBeAdded = missingNodes.subtract(toBeMovedHere)
110+
toBeAdded.forEach {
111+
val index = it.getIndexWithinRole(nodeData, existingIds.size - 1)
112+
node.addNewChildWithStats(it, index)
113+
}
112114

113115
node.allChildren.forEach {
114116
val childData = originalIdToSpec[it.originalId()]
@@ -118,34 +120,34 @@ class ModelImporter(private val root: INode, val stats: ImportStats? = null) {
118120
}
119121
}
120122

121-
private fun syncAllChildOrders(root: INode, rootData: NodeData) {
122-
syncChildOrder(root, rootData)
123-
for ((node, data) in root.allChildren zip rootData.children) {
124-
syncAllChildOrders(node, data)
125-
}
126-
}
127-
128-
private fun syncChildOrder(node: INode, nodeData: NodeData) {
123+
private fun syncExistingChildOrder(
124+
node: INode,
125+
nodeData: NodeData,
126+
existingIds: Set<String?>,
127+
toBeMovedAwayFromHere: Set<String?>
128+
) {
129129
val existingChildren = node.allChildren.toList()
130130
val specifiedChildren = nodeData.children
131-
require(existingChildren.size == specifiedChildren.size)
131+
require(existingChildren.size <= specifiedChildren.size)
132+
133+
val filteredSpecifiedChildren = specifiedChildren.filter { existingIds.contains(it.originalId()) }
132134

133135
val targetIndices = HashMap<String?, Int>(nodeData.children.size)
134-
for (specifiedChild in specifiedChildren) {
135-
val index = specifiedChild.getIndexWithinRole(nodeData)
136-
targetIndices[specifiedChild.originalId()] = index
136+
for (specifiedChild in filteredSpecifiedChildren) {
137+
val index = filteredSpecifiedChildren.filter { it.role == node.roleInParent }.indexOf(specifiedChild)
138+
targetIndices[specifiedChild.originalId()] = minOf(index, existingChildren.size - 1)
137139
}
138140

139141
for ((index, child) in existingChildren.withIndex()) {
140142
val targetIndex = targetIndices[child.originalId()] ?: -1
141-
if (targetIndex != index) {
143+
if (targetIndex != index && !toBeMovedAwayFromHere.contains(child.originalId())) {
142144
node.moveChildWithStats(child.roleInParent, targetIndex, child)
143145
}
144146
}
145147
}
146148

147-
private fun NodeData.getIndexWithinRole(parent: NodeData) : Int {
148-
return parent.children.filter { it.role == this.role }.indexOf(this)
149+
private fun NodeData.getIndexWithinRole(parent: NodeData, maxIndex: Int) : Int {
150+
return minOf(parent.children.filter { it.role == this.role }.indexOf(this), maxIndex)
149151
}
150152

151153
private fun INode.originalId(): String? {

0 commit comments

Comments
 (0)