refs #35 refac to get caching out of Obj; it is decoder/encoder matter now

This commit is contained in:
Sergey Chernov 2025-07-19 14:19:50 +03:00
parent 405ff2ec2b
commit 20181c63a1
4 changed files with 70 additions and 68 deletions

View File

@ -84,9 +84,9 @@ data class ObjString(val value: String) : Obj() {
override suspend fun lynonType(): LynonType = LynonType.String
override suspend fun serialize(scope: Scope, encoder: LynonEncoder, lynonType: LynonType?) {
if( lynonType == null )
encoder.encodeCached(this) { encoder.encodeBinaryData(value.encodeToByteArray()) }
else
// if( lynonType == null )
// encoder.encodeCached(this) { encoder.encodeBinaryData(value.encodeToByteArray()) }
// else
encoder.encodeBinaryData(value.encodeToByteArray())
}
@ -94,11 +94,12 @@ data class ObjString(val value: String) : Obj() {
companion object {
val type = object : ObjClass("String") {
override suspend fun deserialize(scope: Scope, decoder: LynonDecoder, lynonType: LynonType?): Obj =
if( lynonType == null )
decoder.decodeCached {
ObjString(decoder.unpackBinaryData().decodeToString())
}
else ObjString(decoder.unpackBinaryData().decodeToString())
// if( lynonType == null )
// decoder.decodeCached {
// ObjString(decoder.unpackBinaryData().decodeToString())
// }
// else
ObjString(decoder.unpackBinaryData().decodeToString())
}.apply {
addFn("toInt") {
ObjInt(thisAs<ObjString>().value.toLong())

View File

@ -39,9 +39,8 @@ open class LynonDecoder(val bin: BitInput, val settings: LynonSettings = LynonSe
type.objClass.deserialize(scope, this, type)
}
// todo: rewrite/remove?
suspend fun unpackObject(scope: Scope, type: ObjClass): Obj {
return type.deserialize(scope, this, null)
suspend fun decodeObject(scope: Scope, type: ObjClass): Obj {
return decodeCached { type.deserialize(scope, this, null) }
}
fun unpackBinaryData(): ByteArray = bin.decompress()

View File

@ -65,8 +65,10 @@ open class LynonEncoder(val bout: BitOutput, val settings: LynonSettings = Lynon
bout.putBits(type.ordinal.toULong(), 4)
}
suspend fun encodeObj(scope: Scope, obj: Obj) {
suspend fun encodeObject(scope: Scope, obj: Obj) {
encodeCached(obj) {
obj.serialize(scope, this, null)
}
}
fun encodeBinaryData(data: ByteArray) {

View File

@ -150,28 +150,28 @@ class LynonTests {
val encoder = LynonEncoder(bout)
val s = "Hello, World!".toObj()
val scope = Scope()
encoder.encodeObj(scope, s) // 1
encoder.encodeObj(scope, s)
encoder.encodeObj(scope, s)
encoder.encodeObj(scope, s)
encoder.encodeObj(scope, s)
encoder.encodeObj(scope, s)
encoder.encodeObj(scope, s)
encoder.encodeObj(scope, s) // 8
encoder.encodeObject(scope, s) // 1
encoder.encodeObject(scope, s)
encoder.encodeObject(scope, s)
encoder.encodeObject(scope, s)
encoder.encodeObject(scope, s)
encoder.encodeObject(scope, s)
encoder.encodeObject(scope, s)
encoder.encodeObject(scope, s) // 8
val decoder = LynonDecoder(MemoryBitInput(bout))
val s1 = decoder.unpackObject(scope, ObjString.type) // 1
val s1 = decoder.decodeObject(scope, ObjString.type) // 1
assertEquals(s, s1)
assertNotSame(s, s1)
val s2 = decoder.unpackObject(scope, ObjString.type)
val s2 = decoder.decodeObject(scope, ObjString.type)
assertEquals(s, s2)
assertSame(s1, s2)
assertSame(s1, decoder.unpackObject(scope, ObjString.type))
assertSame(s1, decoder.unpackObject(scope, ObjString.type))
assertSame(s1, decoder.unpackObject(scope, ObjString.type))
assertSame(s1, decoder.unpackObject(scope, ObjString.type))
assertSame(s1, decoder.unpackObject(scope, ObjString.type))
assertSame(s1, decoder.unpackObject(scope, ObjString.type)) // 8
assertSame(s1, decoder.decodeObject(scope, ObjString.type))
assertSame(s1, decoder.decodeObject(scope, ObjString.type))
assertSame(s1, decoder.decodeObject(scope, ObjString.type))
assertSame(s1, decoder.decodeObject(scope, ObjString.type))
assertSame(s1, decoder.decodeObject(scope, ObjString.type))
assertSame(s1, decoder.decodeObject(scope, ObjString.type)) // 8
}
@Test
@ -182,12 +182,12 @@ class LynonTests {
val encoder = LynonPacker()
val scope = Scope()
for (s in source) {
encoder.encodeObj(scope, s)
encoder.encodeObject(scope, s)
}
val decoder = LynonUnpacker(encoder)
val restored = mutableListOf<Obj>()
for (i in source.indices) {
restored.add(decoder.unpackObject(scope, ObjString.type))
restored.add(decoder.decodeObject(scope, ObjString.type))
}
assertEquals(restored, source)
}
@ -196,58 +196,58 @@ class LynonTests {
fun testUnpackBoolean() = runTest {
val scope = Scope()
val decoder = LynonUnpacker(LynonPacker().apply {
encodeObj(scope, ObjBool(true))
encodeObj(scope, ObjBool(false))
encodeObj(scope, ObjBool(true))
encodeObj(scope, ObjBool(true))
encodeObject(scope, ObjBool(true))
encodeObject(scope, ObjBool(false))
encodeObject(scope, ObjBool(true))
encodeObject(scope, ObjBool(true))
})
assertEquals(ObjTrue, decoder.unpackObject(scope, ObjBool.type))
assertEquals(ObjFalse, decoder.unpackObject(scope, ObjBool.type))
assertEquals(ObjTrue, decoder.unpackObject(scope, ObjBool.type))
assertEquals(ObjTrue, decoder.unpackObject(scope, ObjBool.type))
assertEquals(ObjTrue, decoder.decodeObject(scope, ObjBool.type))
assertEquals(ObjFalse, decoder.decodeObject(scope, ObjBool.type))
assertEquals(ObjTrue, decoder.decodeObject(scope, ObjBool.type))
assertEquals(ObjTrue, decoder.decodeObject(scope, ObjBool.type))
}
@Test
fun testUnpackReal() = runTest {
val scope = Scope()
val decoder = LynonUnpacker(LynonPacker().apply {
encodeObj(scope, ObjReal(-Math.PI))
encodeObj(scope, ObjReal(Math.PI))
encodeObj(scope, ObjReal(-Math.PI))
encodeObj(scope, ObjReal(Math.PI))
encodeObj(scope, ObjReal(Double.NaN))
encodeObj(scope, ObjReal(Double.NEGATIVE_INFINITY))
encodeObj(scope, ObjReal(Double.POSITIVE_INFINITY))
encodeObj(scope, ObjReal(Double.MIN_VALUE))
encodeObj(scope, ObjReal(Double.MAX_VALUE))
encodeObject(scope, ObjReal(-Math.PI))
encodeObject(scope, ObjReal(Math.PI))
encodeObject(scope, ObjReal(-Math.PI))
encodeObject(scope, ObjReal(Math.PI))
encodeObject(scope, ObjReal(Double.NaN))
encodeObject(scope, ObjReal(Double.NEGATIVE_INFINITY))
encodeObject(scope, ObjReal(Double.POSITIVE_INFINITY))
encodeObject(scope, ObjReal(Double.MIN_VALUE))
encodeObject(scope, ObjReal(Double.MAX_VALUE))
})
assertEquals(ObjReal(-Math.PI), decoder.unpackObject(scope, ObjReal.type))
assertEquals(ObjReal(Math.PI), decoder.unpackObject(scope, ObjReal.type))
assertEquals(ObjReal(-Math.PI), decoder.unpackObject(scope, ObjReal.type))
assertEquals(ObjReal(Math.PI), decoder.unpackObject(scope, ObjReal.type))
assert((decoder.unpackObject(scope, ObjReal.type)).toDouble().isNaN())
assertEquals(ObjReal(Double.NEGATIVE_INFINITY), decoder.unpackObject(scope, ObjReal.type))
assertEquals(ObjReal(Double.POSITIVE_INFINITY), decoder.unpackObject(scope, ObjReal.type))
assertEquals(ObjReal(Double.MIN_VALUE), decoder.unpackObject(scope, ObjReal.type))
assertEquals(ObjReal(Double.MAX_VALUE), decoder.unpackObject(scope, ObjReal.type))
assertEquals(ObjReal(-Math.PI), decoder.decodeObject(scope, ObjReal.type))
assertEquals(ObjReal(Math.PI), decoder.decodeObject(scope, ObjReal.type))
assertEquals(ObjReal(-Math.PI), decoder.decodeObject(scope, ObjReal.type))
assertEquals(ObjReal(Math.PI), decoder.decodeObject(scope, ObjReal.type))
assert((decoder.decodeObject(scope, ObjReal.type)).toDouble().isNaN())
assertEquals(ObjReal(Double.NEGATIVE_INFINITY), decoder.decodeObject(scope, ObjReal.type))
assertEquals(ObjReal(Double.POSITIVE_INFINITY), decoder.decodeObject(scope, ObjReal.type))
assertEquals(ObjReal(Double.MIN_VALUE), decoder.decodeObject(scope, ObjReal.type))
assertEquals(ObjReal(Double.MAX_VALUE), decoder.decodeObject(scope, ObjReal.type))
}
@Test
fun testUnpackInt() = runTest {
val scope = Scope()
val decoder = LynonUnpacker(LynonPacker().apply {
encodeObj(scope, ObjInt(0))
encodeObj(scope, ObjInt(-1))
encodeObj(scope, ObjInt(23))
encodeObj(scope, ObjInt(Long.MIN_VALUE))
encodeObj(scope, ObjInt(Long.MAX_VALUE))
encodeObj(scope, ObjInt(Long.MAX_VALUE))
encodeObject(scope, ObjInt(0))
encodeObject(scope, ObjInt(-1))
encodeObject(scope, ObjInt(23))
encodeObject(scope, ObjInt(Long.MIN_VALUE))
encodeObject(scope, ObjInt(Long.MAX_VALUE))
encodeObject(scope, ObjInt(Long.MAX_VALUE))
})
assertEquals(ObjInt(0), decoder.unpackObject(scope, ObjInt.type))
assertEquals(ObjInt(-1), decoder.unpackObject(scope, ObjInt.type))
assertEquals(ObjInt(23), decoder.unpackObject(scope, ObjInt.type))
assertEquals(ObjInt(Long.MIN_VALUE), decoder.unpackObject(scope, ObjInt.type))
assertEquals(ObjInt(Long.MAX_VALUE), decoder.unpackObject(scope, ObjInt.type))
assertEquals(ObjInt(Long.MAX_VALUE), decoder.unpackObject(scope, ObjInt.type))
assertEquals(ObjInt(0), decoder.decodeObject(scope, ObjInt.type))
assertEquals(ObjInt(-1), decoder.decodeObject(scope, ObjInt.type))
assertEquals(ObjInt(23), decoder.decodeObject(scope, ObjInt.type))
assertEquals(ObjInt(Long.MIN_VALUE), decoder.decodeObject(scope, ObjInt.type))
assertEquals(ObjInt(Long.MAX_VALUE), decoder.decodeObject(scope, ObjInt.type))
assertEquals(ObjInt(Long.MAX_VALUE), decoder.decodeObject(scope, ObjInt.type))
}
@Test