diff --git a/gradle.properties b/gradle.properties index ab38e97..68fc37d 100644 --- a/gradle.properties +++ b/gradle.properties @@ -4,7 +4,7 @@ kotlin.code.style=official specifyKotlinAsDependency=false projectGroup=ru.dbotthepony.kommons -projectVersion=2.3.1 +projectVersion=2.3.2 guavaDepVersion=33.0.0 gsonDepVersion=2.8.9 diff --git a/src/main/kotlin/ru/dbotthepony/kommons/io/BTreeDB.kt b/src/main/kotlin/ru/dbotthepony/kommons/io/BTreeDB.kt index dd2c442..f87245d 100644 --- a/src/main/kotlin/ru/dbotthepony/kommons/io/BTreeDB.kt +++ b/src/main/kotlin/ru/dbotthepony/kommons/io/BTreeDB.kt @@ -14,6 +14,12 @@ abstract class BTreeDB : Closeable { abstract val file: File abstract val blockSize: Int + open operator fun contains(key: K): Boolean { + return hasKey(key).get() + } + + abstract fun hasKey(key: K): CompletableFuture + /** * Reads data at specified [key] */ diff --git a/src/main/kotlin/ru/dbotthepony/kommons/io/BTreeDB6.kt b/src/main/kotlin/ru/dbotthepony/kommons/io/BTreeDB6.kt index fe900a6..519accb 100644 --- a/src/main/kotlin/ru/dbotthepony/kommons/io/BTreeDB6.kt +++ b/src/main/kotlin/ru/dbotthepony/kommons/io/BTreeDB6.kt @@ -127,9 +127,9 @@ class BTreeDB6 private constructor(override val file: File, private val reader: reader.write(headerBuf) } - private fun doRead(key: ByteKey): KOptional { + private fun searchForBlock(key: ByteKey): Block? { if (rootBlockIndex == INVALID_BLOCK_INDEX) { - return KOptional.empty() + return null } var block = readBlock(rootBlockIndex) @@ -141,23 +141,35 @@ class BTreeDB6 private constructor(override val file: File, private val reader: if (block.type == BlockType.LEAF) { val leaf = LeafData(block) - val data = leaf.get(key) - - if (data != null) { - val stream = DataInputStream(BlockInputStream(data)) - val output = ByteArray(stream.readInt()) - stream.readFully(output) - return KOptional(output) - } + return leaf.get(key) } else if (block.type == BlockType.DATA) { throw IllegalStateException("Hit data block when scanning index") } else if (block.type == BlockType.FREE) { throw IllegalStateException("Hit free block when scanning index") } + return null + } + + private fun doRead(key: ByteKey): KOptional { + val data = searchForBlock(key) + + if (data != null) { + val stream = DataInputStream(BlockInputStream(data)) + val output = ByteArray(stream.readInt()) + stream.readFully(output) + return KOptional(output) + } + return KOptional.empty() } + override fun hasKey(key: ByteKey): CompletableFuture { + return CompletableFuture.supplyAsync(Supplier { + searchForBlock(key) != null + }, carrier) + } + override fun read(key: ByteKey): CompletableFuture> { return CompletableFuture.supplyAsync(Supplier { doRead(key)