Skip to content

Commit 2252f47

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

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
@@ -424,7 +424,7 @@ class ReplForJupyterImpl(
424424
notebook.updateVariablesState(internalEvaluator)
425425
// printVars()
426426
// printUsagesInfo(jupyterId, cellVariables[jupyterId - 1])
427-
val serializedData = variablesSerializer.serializeVariables(jupyterId - 1, notebook.variablesState)
427+
val serializedData = variablesSerializer.serializeVariables(jupyterId - 1, notebook.variablesState, notebook.unchangedVariables())
428428

429429
EvalResult(
430430
result.result.value,

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
@@ -668,18 +668,23 @@ class ReplVarsTest : AbstractSingleReplTest() {
668668
"""
669669
val x = 124
670670
private var f = "abcd"
671-
""".trimIndent()
671+
""".trimIndent(),
672+
jupyterId = 1
672673
)
673674
val state = repl.notebook.cellVariables
674675
assertTrue(state.isNotEmpty())
676+
677+
// f is not accessible from here
675678
eval(
676679
"""
677680
private var z = 1
678681
z += x
679-
""".trimIndent()
682+
""".trimIndent(),
683+
jupyterId = 1
680684
)
681685
assertTrue(state.isNotEmpty())
682686

687+
// TODO discuss if we really want this
683688
val setOfCell = setOf("z", "f", "x")
684689
assertTrue(state.containsValue(setOfCell))
685690
}
@@ -809,6 +814,7 @@ class ReplVarsSerializationTest : AbstractSingleReplTest() {
809814

810815
val serializer = repl.variablesSerializer
811816
val newData = serializer.doIncrementalSerialization(0, "data", actualContainer)
817+
val a = 1
812818
}
813819

814820
@Test
@@ -892,13 +898,7 @@ class ReplVarsSerializationTest : AbstractSingleReplTest() {
892898
val serializer = repl.variablesSerializer
893899

894900
val newData = serializer.doIncrementalSerialization(0, listData.fieldDescriptor.entries.first().key, actualContainer)
895-
var receivedDescriptor = newData.fieldDescriptor
896-
assertEquals(2, receivedDescriptor.size)
897-
assertTrue(receivedDescriptor.containsKey("size"))
898-
899-
val innerList = receivedDescriptor.entries.last().value!!
900-
assertTrue(innerList.isContainer)
901-
receivedDescriptor = innerList.fieldDescriptor
901+
val receivedDescriptor = newData.fieldDescriptor
902902
assertEquals(4, receivedDescriptor.size)
903903

904904
var values = 1
@@ -946,13 +946,61 @@ class ReplVarsSerializationTest : AbstractSingleReplTest() {
946946
assertEquals(3, newDescriptor["data"]!!.fieldDescriptor.size)
947947
val ansSet = mutableSetOf("a", "b", "c")
948948
newDescriptor["data"]!!.fieldDescriptor.forEach { (_, state) ->
949-
assertTrue(state!!.isContainer)
949+
assertFalse(state!!.isContainer)
950950
assertTrue(ansSet.contains(state.value))
951951
ansSet.remove(state.value)
952952
}
953953
assertTrue(ansSet.isEmpty())
954954
}
955955

956+
957+
@Test
958+
fun testSetContainer() {
959+
var res = eval(
960+
"""
961+
val x = setOf("a", "b", "cc", "c")
962+
""".trimIndent(),
963+
jupyterId = 1
964+
)
965+
var varsData = res.metadata.evaluatedVariablesState
966+
assertEquals(1, varsData.size)
967+
assertTrue(varsData.containsKey("x"))
968+
969+
var setData = varsData["x"]!!
970+
assertTrue(setData.isContainer)
971+
assertEquals(2, setData.fieldDescriptor.size)
972+
var setDescriptors = setData.fieldDescriptor
973+
assertEquals("4", setDescriptors["size"]!!.value)
974+
assertTrue(setDescriptors["data"]!!.isContainer)
975+
assertEquals(4, setDescriptors["data"]!!.fieldDescriptor.size)
976+
assertEquals("a", setDescriptors["data"]!!.fieldDescriptor["a"]!!.value)
977+
assertTrue(setDescriptors["data"]!!.fieldDescriptor.containsKey("b"))
978+
assertTrue(setDescriptors["data"]!!.fieldDescriptor.containsKey("cc"))
979+
assertTrue(setDescriptors["data"]!!.fieldDescriptor.containsKey("c"))
980+
981+
res = eval(
982+
"""
983+
val c = mutableSetOf("a", "b", "cc", "c")
984+
""".trimIndent(),
985+
jupyterId = 2
986+
)
987+
varsData = res.metadata.evaluatedVariablesState
988+
assertEquals(2, varsData.size)
989+
assertTrue(varsData.containsKey("c"))
990+
991+
setData = varsData["c"]!!
992+
assertTrue(setData.isContainer)
993+
assertEquals(2, setData.fieldDescriptor.size)
994+
setDescriptors = setData.fieldDescriptor
995+
assertEquals("4", setDescriptors["size"]!!.value)
996+
assertTrue(setDescriptors["data"]!!.isContainer)
997+
assertEquals(4, setDescriptors["data"]!!.fieldDescriptor.size)
998+
assertEquals("a", setDescriptors["data"]!!.fieldDescriptor["a"]!!.value)
999+
assertTrue(setDescriptors["data"]!!.fieldDescriptor.containsKey("b"))
1000+
assertTrue(setDescriptors["data"]!!.fieldDescriptor.containsKey("cc"))
1001+
assertTrue(setDescriptors["data"]!!.fieldDescriptor.containsKey("c"))
1002+
}
1003+
9561004
@Test
9571005
fun testSerializationMessage() {
9581006
val res = eval(
@@ -975,9 +1023,7 @@ class ReplVarsSerializationTest : AbstractSingleReplTest() {
9751023

9761024
val innerList = data.entries.last().value
9771025
assertTrue(innerList.isContainer)
978-
var receivedDescriptor = innerList.fieldDescriptor
979-
assertEquals(2, receivedDescriptor.size)
980-
receivedDescriptor = receivedDescriptor.entries.last().value!!.fieldDescriptor
1026+
val receivedDescriptor = innerList.fieldDescriptor
9811027

9821028
assertEquals(4, receivedDescriptor.size)
9831029
var values = 1
@@ -997,9 +1043,8 @@ class ReplVarsSerializationTest : AbstractSingleReplTest() {
9971043

9981044
val innerList = data.entries.last().value
9991045
assertTrue(innerList.isContainer)
1000-
var receivedDescriptor = innerList.fieldDescriptor
1001-
assertEquals(2, receivedDescriptor.size)
1002-
receivedDescriptor = receivedDescriptor.entries.last().value!!.fieldDescriptor
1046+
val receivedDescriptor = innerList.fieldDescriptor
1047+
10031048

10041049
assertEquals(4, receivedDescriptor.size)
10051050
var values = 1
@@ -1050,5 +1095,26 @@ class ReplVarsSerializationTest : AbstractSingleReplTest() {
10501095
)
10511096
assertTrue(state.isNotEmpty())
10521097
assertEquals(state, setOfPrevCell)
1098+
1099+
1100+
eval(
1101+
"""
1102+
private val x = 341
1103+
protected val z = "abcd"
1104+
""".trimIndent(),
1105+
jupyterId = 1
1106+
)
1107+
assertTrue(state.isEmpty())
1108+
1109+
eval(
1110+
"""
1111+
private val x = "abcd"
1112+
var f = 47
1113+
internal val z = 47
1114+
""".trimIndent(),
1115+
jupyterId = 1
1116+
)
1117+
assertTrue(state.isNotEmpty())
1118+
assertEquals(setOfPrevCell, state)
10531119
}
10541120
}

0 commit comments

Comments
 (0)