Skip to content

Commit 6c85ff4

Browse files
Use custom lazy delegate
1 parent 80ea789 commit 6c85ff4

File tree

2 files changed

+42
-32
lines changed

2 files changed

+42
-32
lines changed

jupyter-lib/api/src/main/kotlin/org/jetbrains/kotlinx/jupyter/api/VariableState.kt

+20-4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package org.jetbrains.kotlinx.jupyter.api
22

33
import java.lang.reflect.Field
4+
import kotlin.reflect.KProperty
45
import kotlin.reflect.KProperty1
56
import kotlin.reflect.full.declaredMemberProperties
67
import kotlin.reflect.jvm.isAccessible
@@ -13,6 +14,18 @@ interface VariableState {
1314
val isRecursive: Boolean
1415
}
1516

17+
class DependentLazyDelegate<T>(val initializer: () -> T?) {
18+
private var cachedPropertyValue: T? = null
19+
var isChanged: Boolean = true
20+
21+
operator fun getValue(thisRef: Any?, property: KProperty<*>): T? {
22+
if (isChanged) {
23+
cachedPropertyValue = initializer()
24+
}
25+
return cachedPropertyValue
26+
}
27+
}
28+
1629
data class VariableStateImpl(
1730
override val property: Field,
1831
override val scriptInstance: Any,
@@ -32,18 +45,18 @@ data class VariableStateImpl(
3245
}
3346
property.isAccessible = wasAccessible
3447

35-
val isChanged = cachedValue.getOrNull() !== fieldValue.getOrNull()
48+
customDelegate.isChanged = cachedValue.getOrNull() !== fieldValue.getOrNull()
3649
cachedValue = fieldValue
37-
return isChanged
50+
return customDelegate.isChanged
3851
}
3952

40-
override val stringValue: String? by lazy {
53+
private val customDelegate = DependentLazyDelegate {
4154
fun getRecursiveObjectName(): String {
4255
val kClassName = cachedValue.getOrNull()!!::class.simpleName
4356
return "$kClassName: recursive structure"
4457
}
4558
if (cachedValue.getOrNull() == null) {
46-
return@lazy null
59+
return@DependentLazyDelegate null
4760
}
4861
handleIfRecursiveStructure()
4962

@@ -54,6 +67,9 @@ data class VariableStateImpl(
5467
}
5568
}
5669

70+
override val stringValue: String?
71+
get() = customDelegate.getValue(this, this::stringValue)
72+
5773
override val value: Result<Any?>
5874
get() = cachedValue
5975

src/main/kotlin/org/jetbrains/kotlinx/jupyter/serializationUtils.kt

+22-28
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,16 @@ class VariablesSerializer(
175175
value::class.java.isArray
176176
} == true
177177
}
178+
fun getProperEntrySetRepresentation(value: Any?): String {
179+
value as Set<*>
180+
val size = value.size
181+
if (size == 0) return ""
182+
val firstProper = value.firstOrNull {
183+
it as Map.Entry<*, *>
184+
it.key != null && it.value != null
185+
} as Map.Entry<*, *> ?: return ""
186+
return "<${firstProper.key!!::class.simpleName}, ${firstProper.value!!::class.simpleName}>"
187+
}
178188

179189
val kProperties = try {
180190
if (value != null) value::class.declaredMemberProperties else {
@@ -183,7 +193,11 @@ class VariablesSerializer(
183193
} catch (ex: Exception) { null }
184194
val stringedValue = getProperString(value)
185195
val varID = if (value !is String) {
186-
value.getUniqueID(stringedValue.contains(": recursive structure"))
196+
val isRecursive = stringedValue.contains(": recursive structure")
197+
if (!isRecursive && simpleTypeName == "LinkedEntrySet") {
198+
getProperEntrySetRepresentation(value)
199+
} else
200+
value.getUniqueID(isRecursive)
187201
} else {
188202
""
189203
}
@@ -382,10 +396,12 @@ class VariablesSerializer(
382396
val wasRedeclared = !unchangedVariables.contains(it)
383397
if (wasRedeclared) {
384398
removedFromSightVariables.remove(it)
385-
} /*
386-
(unchangedVariables.contains(it) || serializedVariablesCache[it]?.value != variablesState[it]?.value?.getOrNull().toString()) &&
387-
!removedFromSightVariables.contains(it)*/
388-
(unchangedVariables.contains(it)) &&
399+
}
400+
// todo: might consider self-recursive elements always to recompute since it's non comparable via strings
401+
if (serializedVariablesCache.isEmpty()) {
402+
true
403+
} else
404+
(!unchangedVariables.contains(it) || serializedVariablesCache[it]?.value != variablesState[it]?.stringValue) &&
389405
!removedFromSightVariables.contains(it)
390406
}
391407
log.debug("Variables state as is: $variablesState")
@@ -645,28 +661,6 @@ class VariablesSerializer(
645661
instancesPerState[descriptor[name]!!] = value.objectInstance
646662
}
647663

648-
/* if (!seenObjectsPerCell!!.containsKey(value)) {
649-
val simpleType = if (elem is Field) getSimpleTypeNameFrom(elem, value.objectInstance) ?: "null"
650-
else {
651-
elem as KProperty1<Any, *>
652-
getSimpleTypeNameFrom(elem, value.objectInstance) ?: "null"
653-
}
654-
serializedIteration[name] = if (standardContainersUtilizer.isStandardType(simpleType)) {
655-
standardContainersUtilizer.serializeContainer(simpleType, value.objectInstance, true)
656-
} else {
657-
createSerializeVariableState(name, simpleType, value)
658-
}
659-
descriptor[name] = serializedIteration[name]!!.serializedVariablesState
660-
661-
if (descriptor[name] != null) {
662-
instancesPerState[descriptor[name]!!] = value.objectInstance
663-
}
664-
}*/
665-
// else {
666-
// val descriptorsState = seenObjectsPerCell[value]
667-
// descriptor.putAll(descriptorsState?.fieldDescriptor ?: emptyMap())
668-
// }
669-
670664
if (seenObjectsPerCell?.containsKey(value) == false) {
671665
if (descriptor[name] != null) {
672666
seenObjectsPerCell[value] = descriptor[name]!!
@@ -801,7 +795,7 @@ fun getProperString(value: Any?): String {
801795
if (index != containerSize - 1) {
802796
if (mapMode) {
803797
value as Map.Entry<*, *>
804-
builder.append(value.key, '=', value.value, "\n")
798+
builder.append(value.key, '=', value.value, ", ")
805799
} else {
806800
builder.append(value, ", ")
807801
}

0 commit comments

Comments
 (0)