diff --git a/gradle.properties b/gradle.properties index c9931d83..eeac6e31 100644 --- a/gradle.properties +++ b/gradle.properties @@ -2,7 +2,7 @@ kotlin.code.style=official org.gradle.jvmargs=-Xmx2g -XX:MaxMetaspaceSize=512m kotlinVersion=1.9.0 -kommonsVersion=2.3.1 +kommonsVersion=2.3.2 ffiVersion=2.2.13 lwjglVersion=3.3.0 diff --git a/src/main/kotlin/ru/dbotthepony/kstarbound/Main.kt b/src/main/kotlin/ru/dbotthepony/kstarbound/Main.kt index fece1c4c..9f740acf 100644 --- a/src/main/kotlin/ru/dbotthepony/kstarbound/Main.kt +++ b/src/main/kotlin/ru/dbotthepony/kstarbound/Main.kt @@ -33,7 +33,9 @@ fun main() { val db = BTreeDB6(File("testdb.bdb"), Starbound.BTREEDB_IO_POOL) //val db = BTreeDB(File("world.world")) + val t = System.nanoTime() val meta = DataInputStream(BufferedInputStream(InflaterInputStream(ByteArrayInputStream(db.read(ByteKey(0, 0, 0, 0, 0)).get().get()), Inflater()))) + println(System.nanoTime() - t) println(meta.readInt()) println(meta.readInt()) diff --git a/src/main/kotlin/ru/dbotthepony/kstarbound/io/BTreeDB5.kt b/src/main/kotlin/ru/dbotthepony/kstarbound/io/BTreeDB5.kt index 1fab8402..b9f07da2 100644 --- a/src/main/kotlin/ru/dbotthepony/kstarbound/io/BTreeDB5.kt +++ b/src/main/kotlin/ru/dbotthepony/kstarbound/io/BTreeDB5.kt @@ -162,6 +162,74 @@ class BTreeDB5(override val file: File) : ByteDataBTreeDB() { }, carrier) } + private fun doHasKey(key: ByteKey): Boolean { + seekBlock(rootNodeIndex) + var blockStream = BlockInputStream() + + while (blockStream.type != TreeBlockType.LEAF) { + if (blockStream.type == TreeBlockType.FREE) { + throw IllegalStateException("Hit free block while scanning index for $key") + } + + blockStream.skip(1) + val keyCount = blockStream.data.readInt() + + var found = false + + // B a + // B b + // B c + // B d + for (keyIndex in 0 until keyCount) { + // указатель на левый блок + val pointer = blockStream.data.readInt() + + // левый ключ, всё что меньше него находится в левом блоке + val seekKey = blockStream.data.readByteKeyRaw(keySize) + + // нужный ключ меньше самого первого ключа, поэтому он находится где то в левом блоке + if (key < seekKey) { + seekBlock(pointer) + blockStream = BlockInputStream() + found = true + break + } + } + + if (!found) { + // ... B + seekBlock(blockStream.data.readInt()) + blockStream = BlockInputStream() + } + } + + // мы пришли в лепесток, теперь прямолинейно ищем в linked list + val keyCount = blockStream.data.readInt() + + for (keyIndex in 0 until keyCount) { + // читаем ключ + val seekKey = blockStream.data.readByteKeyRaw(keySize) + + // читаем размер данных + val dataLength = blockStream.data.readVarInt() + + // это наш блок + if (seekKey == key) { + return true + } else { + blockStream.data.skipBytes(dataLength) + } + } + + return false + } + + override fun hasKey(key: ByteKey): CompletableFuture { + return CompletableFuture.supplyAsync(Supplier { + doHasKey(key) + }, carrier) + } + private fun doRead(key: ByteKey): KOptional { seekBlock(rootNodeIndex) var blockStream = BlockInputStream()