Skip to content

Commit 7446295

Browse files
committed
refactor(model-datastructure): introduction of IObjectGraph, which controls how objects are loaded
This makes it more flexible for different use cases. There can be lazy loading or a fully instantiated in-memory graph or something mixed. For the model client there is an implementation that keeps the model data inside a version in memory, but tries to unload the unused history. BREAKING CHANGE: Some of the constructors of `CLVersion` and `CLTree` were removed. There are either static methods as a replacements or some of the parameters need be converted to a non-deprecated type before passing them to the constructor.
1 parent 203d776 commit 7446295

File tree

93 files changed

+1705
-1110
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

93 files changed

+1705
-1110
lines changed

bulk-model-sync-lib/src/commonTest/kotlin/org/modelix/model/sync/bulk/AbstractModelSyncTest.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -605,7 +605,7 @@ internal fun createOTBranchFromModel(model: ModelData): OTBranch {
605605
pBranch.runWrite {
606606
ModelImporter(pBranch.getRootNode()).import(model)
607607
}
608-
return OTBranch(pBranch, IdGenerator.getInstance(1), createObjectStoreCache(MapBasedStore()))
608+
return OTBranch(pBranch, IdGenerator.getInstance(1))
609609
}
610610

611611
internal fun IBranch.importIncrementally(model: ModelData) {

bulk-model-sync-lib/src/commonTest/kotlin/org/modelix/model/sync/bulk/ModelImporterTest.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ class ModelImporterTest : AbstractModelSyncTest() {
5858
val importer = ModelImporter(branch1.getRootNode())
5959
importer.import(ModelData(root = initialState))
6060
}
61-
val otBranch = OTBranch(branch1, idGenerator, store)
61+
val otBranch = OTBranch(branch1, idGenerator)
6262

6363
otBranch.runWrite {
6464
val importer = ModelImporter(otBranch.getRootNode())

bulk-model-sync-lib/src/commonTest/kotlin/org/modelix/model/sync/bulk/ModelSynchronizerTest.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@ open class ModelSynchronizerTest : AbstractModelSyncTest() {
173173
importer.import(ModelData(root = sourceBranch.getRootNode().asExported()))
174174
}
175175
}
176-
val otBranch = OTBranch(targetBranch, idGenerator, store)
176+
val otBranch = OTBranch(targetBranch, idGenerator)
177177

178178
otBranch.runWrite {
179179
ModelSynchronizer(
@@ -196,5 +196,5 @@ open class ModelSynchronizerTest : AbstractModelSyncTest() {
196196
}
197197

198198
private fun IBranch.toOTBranch(): OTBranch {
199-
return OTBranch(this, IdGenerator.getInstance(1), createObjectStoreCache(MapBasedStore()))
199+
return OTBranch(this, IdGenerator.getInstance(1))
200200
}

bulk-model-sync-lib/src/jvmTest/kotlin/org/modelix/model/sync/bulk/ModelSynchronizerWithInvalidationTreeTest.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ class ModelSynchronizerWithInvalidationTreeTest : ModelSynchronizerTest() {
8383
sourceTree.visitChanges(targetTree, InvalidatingVisitor(sourceTree, invalidationTree))
8484
}
8585
}
86-
val otBranch = OTBranch(targetBranch, idGenerator, store)
86+
val otBranch = OTBranch(targetBranch, idGenerator)
8787
otBranch.runWrite {
8888
ModelSynchronizer(
8989
filter = invalidationTree,

gradle/libs.versions.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,8 @@ kotlin-serialization-yaml = { group = "com.charleskorn.kaml", name = "kaml", ver
5353
kotlin-logging = { group = "io.github.microutils", name = "kotlin-logging", version = "3.0.5" }
5454
kotlin-datetime = { group = "org.jetbrains.kotlinx", name = "kotlinx-datetime", version = "0.6.2" }
5555
kotlin-html = { group = "org.jetbrains.kotlinx", name = "kotlinx-html", version = "0.9.1" }
56+
kotlin-collections-immutable = { group = "org.jetbrains.kotlinx", name = "kotlinx-collections-immutable", version = "0.3.8" }
57+
kotlinJs = { module = "org.jetbrains.kotlin-wrappers:kotlin-js", version = "2025.1.4" }
5658
kotlin-gradlePlugin = { group = "org.jetbrains.kotlin", name = "kotlin-gradle-plugin", version.ref = "kotlin" }
5759

5860
kotlin-coroutines-core = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-core", version.ref = "kotlinCoroutines" }

kotlin-utils/build.gradle.kts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ kotlin {
1919
val jvmMain by getting {
2020
dependencies {
2121
implementation(libs.trove4j)
22+
implementation(libs.guava)
2223
}
2324
}
2425
val jvmTest by getting {
@@ -27,6 +28,7 @@ kotlin {
2728
}
2829
val jsMain by getting {
2930
dependencies {
31+
implementation(libs.kotlinJs)
3032
}
3133
}
3234
val jsTest by getting {
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,3 +25,19 @@ annotation class UnstableModelixFeature(
2525
val reason: String,
2626
val intendedFinalization: String,
2727
)
28+
29+
/**
30+
* Marks declarations in Modelix that are **delicate** —
31+
* they have limited use-case and shall be used with care in general code.
32+
* Any use of a delicate declaration has to be carefully reviewed to make sure it is
33+
* properly used.
34+
* Carefully read documentation of any declaration marked as `DelicateModelixApi`.
35+
*/
36+
@MustBeDocumented
37+
@Retention(value = AnnotationRetention.BINARY)
38+
@RequiresOptIn(
39+
level = RequiresOptIn.Level.WARNING,
40+
message = "This is a delicate API and its use requires care." +
41+
" Make sure you fully read and understand documentation of the declaration that is marked as a delicate API.",
42+
)
43+
annotation class DelicateModelixApi
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package org.modelix.kotlin.utils
2+
3+
expect class WeakValueMap<K : Any, V : Any>() {
4+
fun get(key: K): V?
5+
fun put(key: K, value: V)
6+
fun toMap(): Map<K, V>
7+
}
8+
9+
fun <K : Any, V : Any> WeakValueMap<K, V>.getOrPut(key: K, provider: () -> V): V {
10+
return get(key) ?: provider().also { put(key, it) }
11+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package org.modelix.kotlin.utils
2+
3+
import js.memory.FinalizationRegistry
4+
import js.memory.WeakRef
5+
6+
actual class WeakValueMap<K : Any, V : Any> {
7+
private val map = LinkedHashMap<K, WeakRef<V>>()
8+
private val registry = FinalizationRegistry<K> { map.remove(it) }
9+
10+
actual fun get(key: K): V? {
11+
return map[key]?.deref()
12+
}
13+
14+
actual fun put(key: K, value: V) {
15+
map.put(key, WeakRef(value))
16+
registry.register(value, key, value)
17+
}
18+
19+
actual fun toMap(): Map<K, V> {
20+
return map.mapValues { it.value.deref() }.filterNotNullValues()
21+
}
22+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package org.modelix.kotlin.utils
2+
3+
import com.google.common.collect.MapMaker
4+
5+
actual class WeakValueMap<K : Any, V : Any> {
6+
private val map = MapMaker().weakValues().makeMap<K, V>()
7+
8+
actual fun get(key: K): V? {
9+
return map[key]
10+
}
11+
12+
actual fun put(key: K, value: V) {
13+
map.put(key, value)
14+
}
15+
16+
actual fun toMap(): Map<K, V> {
17+
return map.toMap()
18+
}
19+
}

0 commit comments

Comments
 (0)