Skip to content

Commit 931f52a

Browse files
committed
fix(model-sync-lib): reduced memory consumption
1 parent 5345506 commit 931f52a

File tree

1 file changed

+26
-36
lines changed

1 file changed

+26
-36
lines changed

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

Lines changed: 26 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ class ModelImporter(private val root: INode, val stats: ImportStats? = null) {
99

1010
private val originalIdToExisting: MutableMap<String, INode> = mutableMapOf()
1111
private val originalIdToSpec: MutableMap<String, NodeData> = mutableMapOf()
12-
private val originalIdToRef: MutableMap<String, INodeReference> = mutableMapOf()
1312

1413
fun import(jsonFile: File) {
1514
require(jsonFile.exists())
@@ -23,48 +22,41 @@ class ModelImporter(private val root: INode, val stats: ImportStats? = null) {
2322
stats?.reset()
2423
originalIdToExisting.clear()
2524
originalIdToSpec.clear()
26-
originalIdToRef.clear()
2725

2826
syncProperties(root, data.root) // root original id is required for following operations
29-
val allExistingNodes = root.getDescendants(true).toList()
3027
buildSpecIndex(data.root)
3128

32-
syncAllProperties(allExistingNodes)
33-
buildExistingIndex(allExistingNodes)
29+
syncAllProperties(root.getDescendants(false))
30+
buildExistingIndex(root)
3431

35-
sortAllExistingChildren(allExistingNodes)
32+
sortAllExistingChildren(root)
3633
val addedNodes = addAllMissingChildren(root)
37-
syncAllProperties(addedNodes)
34+
syncAllProperties(addedNodes.asSequence())
3835

39-
val allNodes = allExistingNodes + addedNodes
36+
handleAllMovesAcrossParents(root)
4037

41-
handleAllMovesAcrossParents(allNodes)
38+
addedNodes.forEach {node ->
39+
node.originalId()?.let { originalIdToExisting[it] = node }
40+
}
4241

43-
buildRefIndex(allNodes)
44-
syncAllReferences(allNodes)
42+
syncAllReferences(root)
4543

4644
deleteAllExtraChildren(root)
4745
}
4846

49-
private fun buildExistingIndex(allNodes: List<INode>) {
50-
allNodes.forEach {node ->
47+
private fun buildExistingIndex(root: INode) {
48+
root.getDescendants(true).forEach {node ->
5149
node.originalId()?.let { originalIdToExisting[it] = node }
5250
}
5351
}
5452

55-
private fun buildRefIndex(allNodes: List<INode>) {
56-
allNodes.forEach {node ->
57-
node.originalId()?.let { originalIdToRef[it] = node.reference }
58-
}
59-
}
60-
6153
private fun buildSpecIndex(nodeData: NodeData) {
6254
nodeData.originalId()?.let { originalIdToSpec[it] = nodeData }
6355
nodeData.children.forEach { buildSpecIndex(it) }
6456
}
6557

66-
private fun syncAllProperties(allNodes: List<INode>) {
67-
allNodes.forEach {node ->
58+
private fun syncAllProperties(nodeSequence: Sequence<INode>) {
59+
nodeSequence.forEach {node ->
6860
originalIdToSpec[node.originalId()]?.let { spec -> syncProperties(node, spec) }
6961
}
7062
}
@@ -86,23 +78,23 @@ class ModelImporter(private val root: INode, val stats: ImportStats? = null) {
8678
toBeRemoved.forEach { node.setPropertyValueWithStats(it, null) }
8779
}
8880

89-
private fun syncAllReferences(allNodes: List<INode>) {
90-
allNodes.forEach {node ->
91-
originalIdToSpec[node.originalId()]?.let { spec -> syncReferences(node, spec, originalIdToRef) }
81+
private fun syncAllReferences(root: INode) {
82+
root.getDescendants(true).forEach {node ->
83+
originalIdToSpec[node.originalId()]?.let { spec -> syncReferences(node, spec) }
9284
}
9385
}
9486

95-
private fun syncReferences(node: INode, nodeData: NodeData, originalIdToRef: Map<String, INodeReference>) {
87+
private fun syncReferences(node: INode, nodeData: NodeData) {
9688
nodeData.references.forEach {
97-
if (node.getReferenceTargetRef(it.key) != originalIdToRef[it.value]) {
98-
node.setReferenceTargetWithStats(it.key, originalIdToRef[it.value])
89+
if (node.getReferenceTargetRef(it.key) != originalIdToExisting[it.value]?.reference) {
90+
node.setReferenceTargetWithStats(it.key, originalIdToExisting[it.value]?.reference)
9991
}
10092
}
10193
val toBeRemoved = node.getReferenceRoles().toSet().subtract(nodeData.references.keys)
10294
toBeRemoved.forEach { node.setReferenceTargetWithStats(it, null) }
10395
}
10496

105-
private fun addAllMissingChildren(node: INode): MutableList<INode> {
97+
private fun addAllMissingChildren(node: INode): List<INode> {
10698
val addedNodes = mutableListOf<INode>()
10799
originalIdToSpec[node.originalId()]?.let {
108100
addedNodes.addAll(
@@ -135,10 +127,8 @@ class ModelImporter(private val root: INode, val stats: ImportStats? = null) {
135127
}
136128
}
137129

138-
private fun sortAllExistingChildren(
139-
allNodes: Iterable<INode>
140-
) {
141-
allNodes.forEach { node ->
130+
private fun sortAllExistingChildren(root: INode) {
131+
root.getDescendants(true).forEach { node ->
142132
originalIdToSpec[node.originalId()]?.let { sortExistingChildren(node, it) }
143133
}
144134
}
@@ -177,18 +167,18 @@ class ModelImporter(private val root: INode, val stats: ImportStats? = null) {
177167
}
178168
}
179169

180-
private fun handleAllMovesAcrossParents(allNodes: List<INode>) {
181-
val moves = collectMovesAcrossParents(allNodes)
170+
private fun handleAllMovesAcrossParents(root: INode) {
171+
val moves = collectMovesAcrossParents(root)
182172
while (moves.isNotEmpty()) {
183173
val nextMove = moves.first { !it.nodeToBeMoved.getDescendants(false).contains(it.targetParent) }
184174
performMoveAcrossParents(nextMove.targetParent, nextMove.nodeToBeMoved)
185175
moves.remove(nextMove)
186176
}
187177
}
188178

189-
private fun collectMovesAcrossParents(allNodes: List<INode>): MutableList<MoveAcrossParents> {
179+
private fun collectMovesAcrossParents(root: INode): MutableList<MoveAcrossParents> {
190180
val movesAcrossParents = mutableListOf<MoveAcrossParents>()
191-
allNodes.forEach {node ->
181+
root.getDescendants(true).forEach {node ->
192182
val nodeData = originalIdToSpec[node.originalId()] ?: return@forEach
193183

194184
val missingIds = nodeData.children.map { it.originalId() }.toSet()

0 commit comments

Comments
 (0)