From e9062ab21cfa6ad9fcd6c45a99fb926f88d04e8d Mon Sep 17 00:00:00 2001 From: DBotThePony Date: Sat, 24 Feb 2024 22:57:42 +0700 Subject: [PATCH] Actually sync delegates --- gradle.properties | 2 +- .../dbotthepony/kommons/io/DelegateSyncher.kt | 10 +- .../dbotthepony/kommons/test/BTreeDB6Tests.kt | 8 +- .../kommons/test/DelegateSyncherTests.kt | 117 ++++++++++++++++++ 4 files changed, 131 insertions(+), 6 deletions(-) create mode 100644 src/test/kotlin/ru/dbotthepony/kommons/test/DelegateSyncherTests.kt diff --git a/gradle.properties b/gradle.properties index e195eff..3501c24 100644 --- a/gradle.properties +++ b/gradle.properties @@ -4,7 +4,7 @@ kotlin.code.style=official specifyKotlinAsDependency=false projectGroup=ru.dbotthepony.kommons -projectVersion=2.8.0 +projectVersion=2.8.1 guavaDepVersion=33.0.0 gsonDepVersion=2.8.9 diff --git a/src/main/kotlin/ru/dbotthepony/kommons/io/DelegateSyncher.kt b/src/main/kotlin/ru/dbotthepony/kommons/io/DelegateSyncher.kt index 83b5525..ef4be86 100644 --- a/src/main/kotlin/ru/dbotthepony/kommons/io/DelegateSyncher.kt +++ b/src/main/kotlin/ru/dbotthepony/kommons/io/DelegateSyncher.kt @@ -58,6 +58,14 @@ class DelegateSyncher : Observer { fun read(stream: DataInputStream) { isRemote = true + + var readID = stream.readVarInt() + + while (readID > 0) { + val slot = slots.getOrNull(readID - 1) ?: throw IndexOutOfBoundsException("Unknown networked slot ${readID - 1}!") + slot.read(stream) + readID = stream.readVarInt() + } } fun read(stream: InputStream) { @@ -682,7 +690,7 @@ class DelegateSyncher : Observer { } for (v in sorted) { - stream.writeVarInt(v.parent.id) + stream.writeVarInt(v.parent.id + 1) v.write(stream) } diff --git a/src/test/kotlin/ru/dbotthepony/kommons/test/BTreeDB6Tests.kt b/src/test/kotlin/ru/dbotthepony/kommons/test/BTreeDB6Tests.kt index 7370513..77f31fd 100644 --- a/src/test/kotlin/ru/dbotthepony/kommons/test/BTreeDB6Tests.kt +++ b/src/test/kotlin/ru/dbotthepony/kommons/test/BTreeDB6Tests.kt @@ -16,20 +16,20 @@ object BTreeDB6Tests { if (file.exists()) file.delete() val create = BTreeDB6.create(file, 4096, sync = false) - for (i in 0 .. 8000) { + for (i in 0 .. 800) { val s = "This is key $i" val k = ByteKey("This is key $i") create.write(k, s.toByteArray()) assertEquals(s, String(create.read(k).get())) } - for (i in 0 .. 8000) { + for (i in 0 .. 800) { val s = "This is key $i" val k = ByteKey("This is key $i") assertEquals(s, String(create.read(k).get())) } - for (i in 0 .. 8000) { + for (i in 0 .. 800) { val s = "This is key $i" val k = ByteKey("This is key $i") create.write(k, s.toByteArray()) @@ -40,7 +40,7 @@ object BTreeDB6Tests { val create2 = BTreeDB6(file) - for (i in 0 .. 8000) { + for (i in 0 .. 800) { val s = "This is key $i" val k = ByteKey("This is key $i") assertEquals(s, String(create2.read(k).get())) diff --git a/src/test/kotlin/ru/dbotthepony/kommons/test/DelegateSyncherTests.kt b/src/test/kotlin/ru/dbotthepony/kommons/test/DelegateSyncherTests.kt new file mode 100644 index 0000000..db3e662 --- /dev/null +++ b/src/test/kotlin/ru/dbotthepony/kommons/test/DelegateSyncherTests.kt @@ -0,0 +1,117 @@ +package ru.dbotthepony.kommons.test + +import it.unimi.dsi.fastutil.io.FastByteArrayInputStream +import org.junit.jupiter.api.DisplayName +import org.junit.jupiter.api.Test +import ru.dbotthepony.kommons.io.DelegateSyncher +import ru.dbotthepony.kommons.util.Delegate +import kotlin.test.assertEquals + +object DelegateSyncherTests { + @Test + @DisplayName("Delegate Syncher basic test") + fun test() { + val a = DelegateSyncher() + val b = DelegateSyncher() + + a.int(0).delegate.accept(4) + val remote = a.Remote() + val payload = remote.write()!! + + val v = b.int(0) + b.read(FastByteArrayInputStream(payload.array, 0, payload.length)) + + assertEquals(4, v.delegate.get()) + } + + @Test + @DisplayName("Delegate Syncher multiple delegates") + fun multiple() { + val a = DelegateSyncher() + val b = DelegateSyncher() + val ints = ArrayList>() + val longs = ArrayList>() + + for (i in 0 .. 10) { + a.int().delegate.accept(i) + a.long().delegate.accept(i.toLong()) + + ints.add(b.int()) + longs.add(b.long()) + } + + val remote = a.Remote() + val payload = remote.write()!! + + b.read(FastByteArrayInputStream(payload.array, 0, payload.length)) + + for (i in 0 .. 10) { + assertEquals(i, ints[i].get()) + assertEquals(i.toLong(), longs[i].get()) + } + } + + @Test + @DisplayName("Delegate Syncher network half of delegates") + fun half() { + val a = DelegateSyncher() + val b = DelegateSyncher() + val ints = ArrayList>() + val longs = ArrayList>() + + for (i in 0 .. 10) { + if (i % 2 == 0) { + a.int() + a.long() + } else { + a.int().delegate.accept(i) + a.long().delegate.accept(i.toLong()) + } + + ints.add(b.int()) + longs.add(b.long()) + } + + val remote = a.Remote() + val payload = remote.write()!! + + b.read(FastByteArrayInputStream(payload.array, 0, payload.length)) + + for (i in 0 .. 10) { + if (i % 2 == 0) { + assertEquals(0, ints[i].get()) + assertEquals(0L, longs[i].get()) + } else { + assertEquals(i, ints[i].get()) + assertEquals(i.toLong(), longs[i].get()) + } + } + } + + @Test + @DisplayName("Delegate Syncher >127 delegates") + fun moreThanByte() { + val a = DelegateSyncher() + val b = DelegateSyncher() + val ints = ArrayList>() + val longs = ArrayList>() + + for (i in 0 .. 400) { + a.int().delegate.accept(i) + a.long().delegate.accept(i.toLong()) + + ints.add(b.int()) + longs.add(b.long()) + } + + val remote = a.Remote() + val payload = remote.write()!! + + b.read(FastByteArrayInputStream(payload.array, 0, payload.length)) + + for (i in 0 .. 400) { + assertEquals(i, ints[i].get()) + assertEquals(i.toLong(), longs[i].get()) + } + } +} \ No newline at end of file