Skip to content

Commit 830602d

Browse files
Add support for set container; make standard Arrays have values descriptors right away, not through 'size' and 'data' fields
1 parent 9c7c59e commit 830602d

File tree

3 files changed

+132
-25
lines changed

3 files changed

+132
-25
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -426,7 +426,7 @@ class ReplForJupyterImpl(
426426
notebook.updateVariablesState(internalEvaluator)
427427
// printVars()
428428
// printUsagesInfo(jupyterId, cellVariables[jupyterId - 1])
429-
val serializedData = variablesSerializer.serializeVariables(jupyterId - 1, notebook.variablesState)
429+
val serializedData = variablesSerializer.serializeVariables(jupyterId - 1, notebook.variablesState, notebook.unchangedVariables())
430430

431431

432432
val variablesStateUpdate = notebook.variablesState.mapValues { "" }

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

Lines changed: 49 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,17 @@ class VariablesSerializer(private val serializationDepth: Int = 2, private val s
117117
} catch (ex: Exception) {null}
118118
val serializedVersion = SerializedVariablesState(simpleTypeName, getProperString(value), true)
119119
val descriptors = serializedVersion.fieldDescriptor
120+
121+
// only for set case
122+
if (simpleTypeName == "Set" && kProperties == null) {
123+
value as Set<*>
124+
val size = value.size
125+
descriptors["size"] = createSerializeVariableState(
126+
"size", "Int", size
127+
).serializedVariablesState
128+
descriptors.addDescriptor(value, "data")
129+
}
130+
120131
if (isDescriptorsNeeded) {
121132
kProperties?.forEach { prop ->
122133
val name = prop.name
@@ -206,7 +217,8 @@ class VariablesSerializer(private val serializationDepth: Int = 2, private val s
206217
Float::class.java,
207218
Double::class.java,
208219
Char::class.java,
209-
Boolean::class.java
220+
Boolean::class.java,
221+
String::class.java
210222
)
211223

212224
/**
@@ -219,9 +231,9 @@ class VariablesSerializer(private val serializationDepth: Int = 2, private val s
219231
/**
220232
* Cache for not recomputing unchanged variables
221233
*/
222-
val serializedVariablesCache: MutableMap<String, SerializedVariablesState> = mutableMapOf()
234+
private val serializedVariablesCache: MutableMap<String, SerializedVariablesState> = mutableMapOf()
223235

224-
fun serializeVariables(cellId: Int, variablesState: Map<String, VariableState>): Map<String, SerializedVariablesState> {
236+
fun serializeVariables(cellId: Int, variablesState: Map<String, VariableState>, unchangedVariables: Set<String>): Map<String, SerializedVariablesState> {
225237
if (!isSerializationActive) return emptyMap()
226238

227239
if (seenObjectsPerCell.containsKey(cellId)) {
@@ -231,7 +243,12 @@ class VariablesSerializer(private val serializationDepth: Int = 2, private val s
231243
return emptyMap()
232244
}
233245
currentSerializeCount = 0
234-
return variablesState.mapValues { serializeVariableState(cellId, it.key, it.value) }
246+
247+
val neededEntries = variablesState.filterKeys { unchangedVariables.contains(it) }
248+
249+
val serializedData = neededEntries.mapValues { serializeVariableState(cellId, it.key, it.value) }
250+
serializedVariablesCache.putAll(serializedData)
251+
return serializedVariablesCache
235252
}
236253

237254
fun doIncrementalSerialization(cellId: Int, propertyName: String, serializedVariablesState: SerializedVariablesState): SerializedVariablesState {
@@ -307,6 +324,7 @@ class VariablesSerializer(private val serializationDepth: Int = 2, private val s
307324
}
308325
iterateThroughContainerMembers(cellId, value.objectInstance, serializedVersion.fieldDescriptor, currentCellDescriptors.processedSerializedVarsToJavaProperties[serializedVersion])
309326
}
327+
310328
return processedData.serializedVariablesState
311329
}
312330

@@ -318,7 +336,19 @@ class VariablesSerializer(private val serializationDepth: Int = 2, private val s
318336
kProperties: KPropertiesData? = null,
319337
currentDepth: Int = 0
320338
) {
321-
if ((properties == null && kProperties == null) || callInstance == null || currentDepth >= serializationDepth) return
339+
fun iterateAndStoreValues(callInstance: Any, descriptorsState: MutableMap<String, SerializedVariablesState?>) {
340+
if (callInstance is Collection<*>) {
341+
callInstance.forEach {
342+
descriptorsState.addDescriptor(it)
343+
}
344+
} else if (callInstance is Array<*>) {
345+
callInstance.forEach {
346+
descriptorsState.addDescriptor(it)
347+
}
348+
}
349+
}
350+
351+
if ((properties == null && kProperties == null && callInstance !is Set<*>) || callInstance == null || currentDepth >= serializationDepth) return
322352

323353
val serializedIteration = mutableMapOf<String, ProcessedSerializedVarsState>()
324354

@@ -353,6 +383,17 @@ class VariablesSerializer(private val serializationDepth: Int = 2, private val s
353383
val isArrayType = checkForPossibleArray(callInstance)
354384
computedDescriptorsPerCell[cellId]!!.instancesPerState += instancesPerState
355385

386+
if (descriptor.size == 2 && descriptor.containsKey("data")) {
387+
val listData = descriptor["data"]?.fieldDescriptor ?: return
388+
if (descriptor.containsKey("size") && descriptor["size"]?.value == "null") {
389+
descriptor.remove("size")
390+
descriptor.remove("data")
391+
iterateAndStoreValues(callInstance, descriptor)
392+
} else {
393+
iterateAndStoreValues(callInstance, listData)
394+
}
395+
}
396+
356397
serializedIteration.forEach {
357398
val serializedVariablesState = it.value.serializedVariablesState
358399
val name = it.key
@@ -379,7 +420,7 @@ class VariablesSerializer(private val serializationDepth: Int = 2, private val s
379420
)
380421
}
381422
}
382-
423+
/*
383424
if (descriptor.size == 2 && descriptor.containsKey("data")) {
384425
val listData = descriptor["data"]?.fieldDescriptor ?: return
385426
if (callInstance is Collection<*>) {
@@ -391,7 +432,7 @@ class VariablesSerializer(private val serializationDepth: Int = 2, private val s
391432
listData.addDescriptor(it)
392433
}
393434
}
394-
}
435+
}*/
395436
}
396437

397438
/**
@@ -480,7 +521,7 @@ class VariablesSerializer(private val serializationDepth: Int = 2, private val s
480521
}
481522

482523
val isContainer = if (membersProperties != null) (
483-
!primitiveWrappersSet.contains(javaClass) && membersProperties.isNotEmpty() || value::class.java.isArray || (javaClass.isMemberClass)
524+
!primitiveWrappersSet.contains(javaClass) && membersProperties.isNotEmpty() || value is Set<*> || value::class.java.isArray || javaClass.isMemberClass
484525
) else false
485526
val type = if (value != null && value::class.java.isArray) {
486527
"Array"

src/test/kotlin/org/jetbrains/kotlinx/jupyter/test/repl/ReplTests.kt

Lines changed: 82 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -663,18 +663,23 @@ class ReplVarsTest : AbstractSingleReplTest() {
663663
"""
664664
val x = 124
665665
private var f = "abcd"
666-
""".trimIndent()
666+
""".trimIndent(),
667+
jupyterId = 1
667668
)
668669
val state = repl.notebook.cellVariables
669670
assertTrue(state.isNotEmpty())
671+
672+
// f is not accessible from here
670673
eval(
671674
"""
672675
private var z = 1
673676
z += x
674-
""".trimIndent()
677+
""".trimIndent(),
678+
jupyterId = 1
675679
)
676680
assertTrue(state.isNotEmpty())
677681

682+
// TODO discuss if we really want this
678683
val setOfCell = setOf("z", "f", "x")
679684
assertTrue(state.containsValue(setOfCell))
680685
}
@@ -827,6 +832,7 @@ class ReplVarsSerializationTest : AbstractSingleReplTest() {
827832

828833
val serializer = repl.variablesSerializer
829834
val newData = serializer.doIncrementalSerialization(0, "data", actualContainer)
835+
val a = 1
830836
}
831837

832838
@Test
@@ -910,13 +916,7 @@ class ReplVarsSerializationTest : AbstractSingleReplTest() {
910916
val serializer = repl.variablesSerializer
911917

912918
val newData = serializer.doIncrementalSerialization(0, listData.fieldDescriptor.entries.first().key, actualContainer)
913-
var receivedDescriptor = newData.fieldDescriptor
914-
assertEquals(2, receivedDescriptor.size)
915-
assertTrue(receivedDescriptor.containsKey("size"))
916-
917-
val innerList = receivedDescriptor.entries.last().value!!
918-
assertTrue(innerList.isContainer)
919-
receivedDescriptor = innerList.fieldDescriptor
919+
val receivedDescriptor = newData.fieldDescriptor
920920
assertEquals(4, receivedDescriptor.size)
921921

922922
var values = 1
@@ -964,13 +964,61 @@ class ReplVarsSerializationTest : AbstractSingleReplTest() {
964964
assertEquals(3, newDescriptor["data"]!!.fieldDescriptor.size)
965965
val ansSet = mutableSetOf("a", "b", "c")
966966
newDescriptor["data"]!!.fieldDescriptor.forEach { (_, state) ->
967-
assertTrue(state!!.isContainer)
967+
assertFalse(state!!.isContainer)
968968
assertTrue(ansSet.contains(state.value))
969969
ansSet.remove(state.value)
970970
}
971971
assertTrue(ansSet.isEmpty())
972972
}
973973

974+
975+
@Test
976+
fun testSetContainer() {
977+
var res = eval(
978+
"""
979+
val x = setOf("a", "b", "cc", "c")
980+
""".trimIndent(),
981+
jupyterId = 1
982+
)
983+
var varsData = res.metadata.evaluatedVariablesState
984+
assertEquals(1, varsData.size)
985+
assertTrue(varsData.containsKey("x"))
986+
987+
var setData = varsData["x"]!!
988+
assertTrue(setData.isContainer)
989+
assertEquals(2, setData.fieldDescriptor.size)
990+
var setDescriptors = setData.fieldDescriptor
991+
assertEquals("4", setDescriptors["size"]!!.value)
992+
assertTrue(setDescriptors["data"]!!.isContainer)
993+
assertEquals(4, setDescriptors["data"]!!.fieldDescriptor.size)
994+
assertEquals("a", setDescriptors["data"]!!.fieldDescriptor["a"]!!.value)
995+
assertTrue(setDescriptors["data"]!!.fieldDescriptor.containsKey("b"))
996+
assertTrue(setDescriptors["data"]!!.fieldDescriptor.containsKey("cc"))
997+
assertTrue(setDescriptors["data"]!!.fieldDescriptor.containsKey("c"))
998+
999+
res = eval(
1000+
"""
1001+
val c = mutableSetOf("a", "b", "cc", "c")
1002+
""".trimIndent(),
1003+
jupyterId = 2
1004+
)
1005+
varsData = res.metadata.evaluatedVariablesState
1006+
assertEquals(2, varsData.size)
1007+
assertTrue(varsData.containsKey("c"))
1008+
1009+
setData = varsData["c"]!!
1010+
assertTrue(setData.isContainer)
1011+
assertEquals(2, setData.fieldDescriptor.size)
1012+
setDescriptors = setData.fieldDescriptor
1013+
assertEquals("4", setDescriptors["size"]!!.value)
1014+
assertTrue(setDescriptors["data"]!!.isContainer)
1015+
assertEquals(4, setDescriptors["data"]!!.fieldDescriptor.size)
1016+
assertEquals("a", setDescriptors["data"]!!.fieldDescriptor["a"]!!.value)
1017+
assertTrue(setDescriptors["data"]!!.fieldDescriptor.containsKey("b"))
1018+
assertTrue(setDescriptors["data"]!!.fieldDescriptor.containsKey("cc"))
1019+
assertTrue(setDescriptors["data"]!!.fieldDescriptor.containsKey("c"))
1020+
}
1021+
9741022
@Test
9751023
fun testSerializationMessage() {
9761024
val res = eval(
@@ -993,9 +1041,7 @@ class ReplVarsSerializationTest : AbstractSingleReplTest() {
9931041

9941042
val innerList = data.entries.last().value
9951043
assertTrue(innerList.isContainer)
996-
var receivedDescriptor = innerList.fieldDescriptor
997-
assertEquals(2, receivedDescriptor.size)
998-
receivedDescriptor = receivedDescriptor.entries.last().value!!.fieldDescriptor
1044+
val receivedDescriptor = innerList.fieldDescriptor
9991045

10001046
assertEquals(4, receivedDescriptor.size)
10011047
var values = 1
@@ -1015,9 +1061,8 @@ class ReplVarsSerializationTest : AbstractSingleReplTest() {
10151061

10161062
val innerList = data.entries.last().value
10171063
assertTrue(innerList.isContainer)
1018-
var receivedDescriptor = innerList.fieldDescriptor
1019-
assertEquals(2, receivedDescriptor.size)
1020-
receivedDescriptor = receivedDescriptor.entries.last().value!!.fieldDescriptor
1064+
val receivedDescriptor = innerList.fieldDescriptor
1065+
10211066

10221067
assertEquals(4, receivedDescriptor.size)
10231068
var values = 1
@@ -1068,5 +1113,26 @@ class ReplVarsSerializationTest : AbstractSingleReplTest() {
10681113
)
10691114
assertTrue(state.isNotEmpty())
10701115
assertEquals(state, setOfPrevCell)
1116+
1117+
1118+
eval(
1119+
"""
1120+
private val x = 341
1121+
protected val z = "abcd"
1122+
""".trimIndent(),
1123+
jupyterId = 1
1124+
)
1125+
assertTrue(state.isEmpty())
1126+
1127+
eval(
1128+
"""
1129+
private val x = "abcd"
1130+
var f = 47
1131+
internal val z = 47
1132+
""".trimIndent(),
1133+
jupyterId = 1
1134+
)
1135+
assertTrue(state.isNotEmpty())
1136+
assertEquals(setOfPrevCell, state)
10711137
}
10721138
}

0 commit comments

Comments
 (0)