BTreeDB.hasKey

This commit is contained in:
DBotThePony 2024-02-15 14:15:56 +07:00
parent 0f91102e6b
commit a0c63d3aaf
Signed by: DBot
GPG Key ID: DCC23B5715498507
3 changed files with 71 additions and 1 deletions

View File

@ -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

View File

@ -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())

View File

@ -162,6 +162,74 @@ class BTreeDB5(override val file: File) : ByteDataBTreeDB<ByteKey>() {
}, 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<Boolean> {
return CompletableFuture.supplyAsync(Supplier {
doHasKey(key)
}, carrier)
}
private fun doRead(key: ByteKey): KOptional<ByteArray> {
seekBlock(rootNodeIndex)
var blockStream = BlockInputStream()