Skip to content

Commit dc305f7

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

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
@@ -457,7 +457,7 @@ class ReplForJupyterImpl(
457457
notebook.updateVariablesState(internalEvaluator)
458458
// printVars()
459459
// printUsagesInfo(jupyterId, cellVariables[jupyterId - 1])
460-
val serializedData = variablesSerializer.serializeVariables(jupyterId - 1, notebook.variablesState)
460+
val serializedData = variablesSerializer.serializeVariables(jupyterId - 1, notebook.variablesState, notebook.unchangedVariables())
461461

462462

463463
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
@@ -639,18 +639,23 @@ class ReplVarsTest : AbstractSingleReplTest() {
639639
"""
640640
val x = 124
641641
private var f = "abcd"
642-
""".trimIndent()
642+
""".trimIndent(),
643+
jupyterId = 1
643644
)
644645
val state = repl.notebook.cellVariables
645646
assertTrue(state.isNotEmpty())
647+
648+
// f is not accessible from here
646649
eval(
647650
"""
648651
private var z = 1
649652
z += x
650-
""".trimIndent()
653+
""".trimIndent(),
654+
jupyterId = 1
651655
)
652656
assertTrue(state.isNotEmpty())
653657

658+
// TODO discuss if we really want this
654659
val setOfCell = setOf("z", "f", "x")
655660
assertTrue(state.containsValue(setOfCell))
656661
}
@@ -830,6 +835,7 @@ class ReplVarsSerializationTest : AbstractSingleReplTest() {
830835

831836
val serializer = repl.variablesSerializer
832837
val newData = serializer.doIncrementalSerialization(0, "data", actualContainer)
838+
val a = 1
833839
}
834840

835841
@Test
@@ -913,13 +919,7 @@ class ReplVarsSerializationTest : AbstractSingleReplTest() {
913919
val serializer = repl.variablesSerializer
914920

915921
val newData = serializer.doIncrementalSerialization(0, listData.fieldDescriptor.entries.first().key, actualContainer)
916-
var receivedDescriptor = newData.fieldDescriptor
917-
assertEquals(2, receivedDescriptor.size)
918-
assertTrue(receivedDescriptor.containsKey("size"))
919-
920-
val innerList = receivedDescriptor.entries.last().value!!
921-
assertTrue(innerList.isContainer)
922-
receivedDescriptor = innerList.fieldDescriptor
922+
val receivedDescriptor = newData.fieldDescriptor
923923
assertEquals(4, receivedDescriptor.size)
924924

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

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

9971045
val innerList = data.entries.last().value
9981046
assertTrue(innerList.isContainer)
999-
var receivedDescriptor = innerList.fieldDescriptor
1000-
assertEquals(2, receivedDescriptor.size)
1001-
receivedDescriptor = receivedDescriptor.entries.last().value!!.fieldDescriptor
1047+
val receivedDescriptor = innerList.fieldDescriptor
10021048

10031049
assertEquals(4, receivedDescriptor.size)
10041050
var values = 1
@@ -1018,9 +1064,8 @@ class ReplVarsSerializationTest : AbstractSingleReplTest() {
10181064

10191065
val innerList = data.entries.last().value
10201066
assertTrue(innerList.isContainer)
1021-
var receivedDescriptor = innerList.fieldDescriptor
1022-
assertEquals(2, receivedDescriptor.size)
1023-
receivedDescriptor = receivedDescriptor.entries.last().value!!.fieldDescriptor
1067+
val receivedDescriptor = innerList.fieldDescriptor
1068+
10241069

10251070
assertEquals(4, receivedDescriptor.size)
10261071
var values = 1
@@ -1071,5 +1116,26 @@ class ReplVarsSerializationTest : AbstractSingleReplTest() {
10711116
)
10721117
assertTrue(state.isNotEmpty())
10731118
assertEquals(state, setOfPrevCell)
1119+
1120+
1121+
eval(
1122+
"""
1123+
private val x = 341
1124+
protected val z = "abcd"
1125+
""".trimIndent(),
1126+
jupyterId = 1
1127+
)
1128+
assertTrue(state.isEmpty())
1129+
1130+
eval(
1131+
"""
1132+
private val x = "abcd"
1133+
var f = 47
1134+
internal val z = 47
1135+
""".trimIndent(),
1136+
jupyterId = 1
1137+
)
1138+
assertTrue(state.isNotEmpty())
1139+
assertEquals(setOfPrevCell, state)
10741140
}
10751141
}

0 commit comments

Comments
 (0)