@@ -39,7 +39,6 @@ import org.modelix.model.sync.bulk.ModelSynchronizer
39
39
import org.modelix.model.sync.bulk.UnfilteredModelMask
40
40
import org.modelix.mps.api.ModelixMpsApi
41
41
import java.io.File
42
- import kotlin.invoke
43
42
import kotlin.system.exitProcess
44
43
45
44
class GitImporter (
@@ -81,51 +80,71 @@ class GitImporter(
81
80
val versionIndex = VersionIndex (initialRemoteVersion)
82
81
var lastPushedVersion = initialRemoteVersion
83
82
84
- val existingImports = HashMap <String , IVersion >()
83
+ val importQueue = LinkedHashMap <String , PendingImport >()
84
+ val fillQueue = DeepRecursiveFunction <ObjectId , PendingImport > { gitCommitId ->
85
+ val gitCommit = git.repository.parseCommit(gitCommitId)
86
+ importQueue[gitCommit.name]?.let { return @DeepRecursiveFunction it }
87
+
88
+ val existingVersionHash = versionIndex.findByGitCommitId(gitCommitId.name)
89
+ val queueElement = if (existingVersionHash != null ) {
90
+ PendingImport (
91
+ gitCommit = gitCommit,
92
+ parentImports = null ,
93
+ importedVersion = null ,
94
+ existingVersionHash = existingVersionHash,
95
+ )
96
+ } else {
97
+ PendingImport (
98
+ gitCommit = gitCommit,
99
+ parentImports = gitCommit.parents?.map { callRecursive(it) }.orEmpty(),
100
+ importedVersion = null ,
101
+ existingVersionHash = null ,
102
+ )
103
+ }
104
+ importQueue[gitCommit.name] = queueElement
105
+ queueElement
106
+ }
107
+ fillQueue(resolvedCommit)
85
108
86
- val importVersion = DeepRecursiveFunction <ObjectId , IVersion > { gitCommitId ->
109
+ println (" Starting import" )
110
+ for (commitId in importQueue.keys.toList()) {
111
+ val queueElement = importQueue.remove(commitId)!!
87
112
try {
88
- val gitCommit = git.repository.parseCommit(gitCommitId)
89
- existingImports[gitCommit.name]?.let { return @DeepRecursiveFunction it }
90
-
91
- val existingVersionHash = versionIndex.findByGitCommitId(gitCommitId.name)
92
- if (existingVersionHash != null ) {
93
- return @DeepRecursiveFunction runBlocking {
94
- client.loadVersion(repositoryId, existingVersionHash.toString(), null ).also { v ->
95
- (v as CLVersion ).gitCommit?.let { c -> existingImports[c] = v }
96
- }
113
+ when {
114
+ queueElement.importedVersion != null -> continue
115
+ queueElement.existingVersionHash != null -> {
116
+ val version = client.loadVersion(repositoryId, queueElement.existingVersionHash!! .toString(), null )
117
+ queueElement.success(version)
97
118
}
98
- }
99
-
100
- val parentImports = gitCommit.parents?.map { callRecursive(it) }.orEmpty()
101
- val mpsRepo = DummyRepo () // TODO dispose
102
- val importedVersion = ModelixMpsApi .runWithRepository(mpsRepo) {
103
- when (parentImports.size) {
104
- 0 -> runImport(listOf (versionIndex.getInitialVersion()), gitCommit, git.repository, mpsRepo)
105
- 1 , 2 -> runImport(parentImports, gitCommit, git.repository, mpsRepo)
106
- else -> TODO ()
119
+ else -> {
120
+ val parentImports = queueElement.parentImports.orEmpty().map { it.importedVersion!! }
121
+ DummyRepo ().use { mpsRepo ->
122
+ val gitCommit = queueElement.gitCommit
123
+ val importedVersion = ModelixMpsApi .runWithRepository(mpsRepo) {
124
+ when (parentImports.size) {
125
+ 0 -> runImport(listOf (versionIndex.getInitialVersion()), gitCommit, git.repository, mpsRepo)
126
+ 1 , 2 -> runImport(parentImports, gitCommit, git.repository, mpsRepo)
127
+ else -> TODO ()
128
+ }
129
+ }
130
+
131
+ runBlocking {
132
+ println (" Pushing $importedVersion " )
133
+ lastPushedVersion = client.push(targetBranch, importedVersion, importedVersion.getParentVersions(), force = true )
134
+ }
135
+
136
+ queueElement.success(importedVersion)
137
+ }
107
138
}
108
139
}
109
-
110
- runBlocking {
111
- println (" Pushing $importedVersion " )
112
- lastPushedVersion = client.push(targetBranch, importedVersion, importedVersion.getParentVersions(), force = true )
113
- }
114
-
115
- existingImports[gitCommit.name] = importedVersion
116
-
117
- importedVersion
118
140
} catch (ex: Exception ) {
119
- println (" Import failed for ${gitCommitId .name} " )
141
+ println (" Import failed for ${queueElement.gitCommit .name} " )
120
142
ex.printStackTrace()
121
143
throw ex
122
144
}
123
145
}
124
146
125
- println (" Starting import" )
126
- val importedVersion = importVersion(resolvedCommit)
127
- println (" Uploading new versions" )
128
- client.push(targetBranch, importedVersion, lastPushedVersion, force = true )
147
+ println (" Import done" )
129
148
}
130
149
131
150
/* *
@@ -270,6 +289,22 @@ class GitImporter(
270
289
}
271
290
}
272
291
}
292
+
293
+ /* *
294
+ * The purpose of this class is to build a queue of to be imported versions and keep the result only as long as
295
+ * necessary in memory. As soon as the result is consumed by all child imports, the result can be garbage collected.
296
+ */
297
+ private class PendingImport (
298
+ val gitCommit : RevCommit ,
299
+ var parentImports : List <PendingImport >? ,
300
+ var importedVersion : IVersion ? = null ,
301
+ var existingVersionHash : ObjectHash ? = null ,
302
+ ) {
303
+ fun success (version : IVersion ) {
304
+ importedVersion = version
305
+ parentImports = null
306
+ }
307
+ }
273
308
}
274
309
275
310
private fun IFile.findModuleFile (): IFile ? {
0 commit comments