Support deleteRange, compactRange and multiGet on column families (#93)

This commit is contained in:
Ben Hartnett
2025-11-10 13:54:18 +08:00
committed by GitHub
parent 1e724b9c1b
commit 736990c12b
26 changed files with 416 additions and 63 deletions
+1 -1
View File
@@ -1,5 +1,5 @@
packageName = "rocksdb"
version = "10.4.2.0"
version = "10.4.2.1"
author = "Status Research & Development GmbH"
description =
"A wrapper for Facebook's RocksDB, an embeddable, persistent key-value store for fast storage"
+1 -1
View File
@@ -50,7 +50,7 @@ proc openBackupEngine*(
BackupEngineRef(cPtr: backupEnginePtr, path: path, backupOpts: backupOpts)
ok(engine)
proc isClosed*(backupEngine: BackupEngineRef): bool {.inline.} =
template isClosed*(backupEngine: BackupEngineRef): bool =
## Returns `true` if the `BackupEngineRef` has been closed.
backupEngine.cPtr.isNil()
+45 -24
View File
@@ -53,70 +53,91 @@ proc getColFamily*(
ok(ColFamilyReadWrite(db: db, name: name, handle: ?db.getColFamilyHandle(name)))
proc db*(cf: ColFamilyReadOnly | ColFamilyReadWrite): auto {.inline.} =
template db*(cf: ColFamilyReadOnly | ColFamilyReadWrite): auto =
## Returns the underlying `RocksDbReadOnlyRef` or `RocksDbReadWriteRef`.
cf.db
proc name*(cf: ColFamilyReadOnly | ColFamilyReadWrite): string {.inline.} =
template name*(cf: ColFamilyReadOnly | ColFamilyReadWrite): string =
## Returns the name of the column family.
cf.name
proc handle*(
cf: ColFamilyReadOnly | ColFamilyReadWrite
): ColFamilyHandleRef {.inline.} =
template handle*(cf: ColFamilyReadOnly | ColFamilyReadWrite): ColFamilyHandleRef =
## Returns the name of the column family.
cf.handle
proc get*(
template get*(
cf: ColFamilyReadOnly | ColFamilyReadWrite, key: openArray[byte], onData: DataProc
): RocksDBResult[bool] {.inline.} =
): RocksDBResult[bool] =
## Gets the value of the given key from the column family using the `onData`
## callback.
cf.db.get(key, onData, cf.handle)
proc get*(
template get*(
cf: ColFamilyReadOnly | ColFamilyReadWrite, key: openArray[byte]
): RocksDBResult[seq[byte]] {.inline.} =
): RocksDBResult[seq[byte]] =
## Gets the value of the given key from the column family.
cf.db.get(key, cf.handle)
proc put*(
cf: ColFamilyReadWrite, key, val: openArray[byte]
): RocksDBResult[void] {.inline.} =
template multiGet*(
cf: ColFamilyReadOnly | ColFamilyReadWrite,
keys: openArray[seq[byte]],
sortedInput = false,
): RocksDBResult[seq[seq[byte]]] =
## Get a batch of values for the given set of keys.
cf.db.multiGet(keys, sortedInput, cf.handle)
template put*(cf: ColFamilyReadWrite, key, val: openArray[byte]): RocksDBResult[void] =
## Puts a value for the given key into the column family.
cf.db.put(key, val, cf.handle)
proc keyExists*(
template keyExists*(
cf: ColFamilyReadOnly | ColFamilyReadWrite, key: openArray[byte]
): RocksDBResult[bool] {.inline.} =
): RocksDBResult[bool] =
## Checks if the given key exists in the column family.
cf.db.keyExists(key, cf.handle)
proc delete*(
cf: ColFamilyReadWrite, key: openArray[byte]
): RocksDBResult[void] {.inline.} =
template delete*(cf: ColFamilyReadWrite, key: openArray[byte]): RocksDBResult[void] =
## Deletes the given key from the column family.
cf.db.delete(key, cf.handle)
proc openIterator*(
template deleteRange*(
cf: ColFamilyReadWrite, startKey, endKey: openArray[byte]
): RocksDBResult[void] =
## Deletes the given key range from the column family including startKey and
## excluding endKey.
cf.db.deleteRange(startKey, endKey, cf.handle)
template compactRange*(
cf: ColFamilyReadWrite, startKey, endKey: openArray[byte]
): RocksDBResult[void] =
## Trigger range compaction for the given key range.
cf.db.compactRange(startKey, endKey, cf.handle)
template suggestCompactRange*(
cf: ColFamilyReadWrite, startKey, endKey: openArray[byte]
): RocksDBResult[void] =
## Suggest the range to compact.
cf.db.suggestCompactRange(startKey, endKey, cf.handle)
template openIterator*(
cf: ColFamilyReadOnly | ColFamilyReadWrite,
readOpts = defaultReadOptions(autoClose = true),
): RocksDBResult[RocksIteratorRef] {.inline.} =
): RocksDBResult[RocksIteratorRef] =
## Opens an `RocksIteratorRef` for the given column family.
cf.db.openIterator(readOpts, cf.handle)
proc openWriteBatch*(cf: ColFamilyReadWrite): WriteBatchRef {.inline.} =
template openWriteBatch*(cf: ColFamilyReadWrite): WriteBatchRef =
## Opens a `WriteBatchRef` for the given column family.
cf.db.openWriteBatch(cf.handle)
proc openWriteBatchWithIndex*(
template openWriteBatchWithIndex*(
cf: ColFamilyReadWrite, reservedBytes = 0, overwriteKey = false
): WriteBatchWIRef {.inline.} =
): WriteBatchWIRef =
## Opens a `WriteBatchRef` for the given column family.
cf.db.openWriteBatchWithIndex(reservedBytes, overwriteKey, cf.handle)
proc write*(
template write*(
cf: ColFamilyReadWrite, updates: WriteBatchRef | WriteBatchWIRef
): RocksDBResult[void] {.inline.} =
): RocksDBResult[void] =
## Writes the updates in the `WriteBatchRef` to the column family.
cf.db.write(updates)
+7 -7
View File
@@ -24,25 +24,25 @@ proc initColFamilyDescriptor*(
): ColFamilyDescriptor =
ColFamilyDescriptor(name: name, options: options)
proc name*(descriptor: ColFamilyDescriptor): string {.inline.} =
template name*(descriptor: ColFamilyDescriptor): string =
descriptor.name
proc options*(descriptor: ColFamilyDescriptor): ColFamilyOptionsRef {.inline.} =
template options*(descriptor: ColFamilyDescriptor): ColFamilyOptionsRef =
descriptor.options
proc autoClose*(descriptor: ColFamilyDescriptor): bool {.inline.} =
template autoClose*(descriptor: ColFamilyDescriptor): bool =
descriptor.options.autoClose
proc isDefault*(descriptor: ColFamilyDescriptor): bool {.inline.} =
template isDefault*(descriptor: ColFamilyDescriptor): bool =
descriptor.name == DEFAULT_COLUMN_FAMILY_NAME
proc defaultColFamilyDescriptor*(autoClose = false): ColFamilyDescriptor {.inline.} =
proc defaultColFamilyDescriptor*(autoClose = false): ColFamilyDescriptor =
initColFamilyDescriptor(
DEFAULT_COLUMN_FAMILY_NAME, defaultColFamilyOptions(autoClose = autoClose)
)
proc isClosed*(descriptor: ColFamilyDescriptor): bool {.inline.} =
template isClosed*(descriptor: ColFamilyDescriptor): bool =
descriptor.options.isClosed()
proc close*(descriptor: ColFamilyDescriptor) {.inline.} =
template close*(descriptor: ColFamilyDescriptor) =
descriptor.options.close()
+1 -1
View File
@@ -20,7 +20,7 @@ type
proc newColFamilyHandle*(cPtr: ColFamilyHandlePtr): ColFamilyHandleRef =
ColFamilyHandleRef(cPtr: cPtr)
proc isClosed*(handle: ColFamilyHandleRef): bool {.inline.} =
template isClosed*(handle: ColFamilyHandleRef): bool =
handle.cPtr.isNil()
proc cPtr*(handle: ColFamilyHandleRef): ColFamilyHandlePtr =
+2 -2
View File
@@ -43,7 +43,7 @@ type
proc createFixedPrefix*(value: int): SlicetransformRef =
SlicetransformRef(cPtr: rocksdb_slicetransform_create_fixed_prefix(value.csize_t))
proc isClosed*(s: SlicetransformRef): bool {.inline.} =
template isClosed*(s: SlicetransformRef): bool =
s.cPtr.isNil()
proc cPtr*(s: SlicetransformRef): SlicetransformPtr =
@@ -58,7 +58,7 @@ proc close*(s: SlicetransformRef) =
proc createColFamilyOptions*(autoClose = false): ColFamilyOptionsRef =
ColFamilyOptionsRef(cPtr: rocksdb_options_create(), autoClose: autoClose)
proc isClosed*(cfOpts: ColFamilyOptionsRef): bool {.inline.} =
template isClosed*(cfOpts: ColFamilyOptionsRef): bool =
cfOpts.cPtr.isNil()
proc cPtr*(cfOpts: ColFamilyOptionsRef): ColFamilyOptionsPtr =
+2 -2
View File
@@ -27,10 +27,10 @@ proc newColFamilyTable*(
ColFamilyTableRef(columnFamilies: cfTable)
proc isClosed*(table: ColFamilyTableRef): bool {.inline.} =
template isClosed*(table: ColFamilyTableRef): bool =
table.columnFamilies.isNil()
proc get*(table: ColFamilyTableRef, name: string): ColFamilyHandleRef {.inline.} =
template get*(table: ColFamilyTableRef, name: string): ColFamilyHandleRef =
table.columnFamilies.getOrDefault(name)
proc close*(table: ColFamilyTableRef) =
+1 -1
View File
@@ -94,7 +94,7 @@ proc getColFamilyHandle*(
else:
ok(cfHandle)
proc isClosed*(db: OptimisticTxDbRef): bool {.inline.} =
template isClosed*(db: OptimisticTxDbRef): bool =
## Returns `true` if the `OptimisticTxDbRef` has been closed.
db.cPtr.isNil()
+2 -2
View File
@@ -25,7 +25,7 @@ proc createBackupEngineOptions*(
cPtr: rocksdb_backup_engine_options_create(backupDir.cstring), autoClose: autoClose
)
proc isClosed*(backupOpts: BackupEngineOptionsRef): bool {.inline.} =
template isClosed*(backupOpts: BackupEngineOptionsRef): bool =
backupOpts.cPtr.isNil()
proc cPtr*(backupOpts: BackupEngineOptionsRef): BackupEngineOptionsPtr =
@@ -53,7 +53,7 @@ opt callbackTriggerIntervalSize, int, uint64
proc defaultBackupEngineOptions*(
backupDir: string, autoClose = false
): BackupEngineOptionsRef {.inline.} =
): BackupEngineOptionsRef =
let backupOpts = createBackupEngineOptions(backupDir, autoClose)
# TODO: set defaults here
+1 -1
View File
@@ -24,7 +24,7 @@ type
proc createDbOptions*(autoClose = false): DbOptionsRef =
DbOptionsRef(cPtr: rocksdb_options_create(), autoClose: autoClose)
proc isClosed*(dbOpts: DbOptionsRef): bool {.inline.} =
template isClosed*(dbOpts: DbOptionsRef): bool =
dbOpts.cPtr.isNil()
proc cPtr*(dbOpts: DbOptionsRef): DbOptionsPtr =
+3 -2
View File
@@ -23,7 +23,7 @@ type
proc createReadOptions*(autoClose = false): ReadOptionsRef =
ReadOptionsRef(cPtr: rocksdb_readoptions_create(), autoClose: autoClose)
proc isClosed*(readOpts: ReadOptionsRef): bool {.inline.} =
template isClosed*(readOpts: ReadOptionsRef): bool =
readOpts.cPtr.isNil()
proc cPtr*(readOpts: ReadOptionsRef): ReadOptionsPtr =
@@ -52,12 +52,13 @@ opt maxSkippableInternalKeys, int, csize_t
opt ignoreRangeDeletions, bool, uint8
opt deadline, int, uint64
opt ioTimeout, int, uint64
opt asyncIo, bool, uint8
proc setSnapshot*(readOpts: ReadOptionsRef, snapshot: SnapshotRef) =
doAssert not readOpts.isClosed()
rocksdb_readoptions_set_snapshot(readOpts.cPtr, snapshot.cPtr)
proc defaultReadOptions*(autoClose = false): ReadOptionsRef {.inline.} =
proc defaultReadOptions*(autoClose = false): ReadOptionsRef =
let readOpts = createReadOptions(autoClose)
# TODO: set prefered defaults
+2 -2
View File
@@ -21,7 +21,7 @@ type
proc createWriteOptions*(autoClose = false): WriteOptionsRef =
WriteOptionsRef(cPtr: rocksdb_writeoptions_create(), autoClose: autoClose)
proc isClosed*(writeOpts: WriteOptionsRef): bool {.inline.} =
template isClosed*(writeOpts: WriteOptionsRef): bool =
writeOpts.cPtr.isNil()
proc cPtr*(writeOpts: WriteOptionsRef): WriteOptionsPtr =
@@ -51,7 +51,7 @@ proc disableWAL*(writeOpts: WriteOptionsRef): bool =
doAssert not writeOpts.isClosed()
rocksdb_writeoptions_get_disable_WAL(writeOpts.cPtr).bool
proc defaultWriteOptions*(autoClose = false): WriteOptionsRef {.inline.} =
proc defaultWriteOptions*(autoClose = false): WriteOptionsRef =
let writeOpts = createWriteOptions(autoClose)
# TODO: set prefered defaults
+133 -2
View File
@@ -221,11 +221,11 @@ proc getColFamilyHandle*(
else:
ok(cfHandle)
proc isClosed*(db: RocksDbRef): bool {.inline.} =
template isClosed*(db: RocksDbRef): bool =
## Returns `true` if the database has been closed and `false` otherwise.
db.cPtr.isNil()
proc cPtr*(db: RocksDbRef): RocksDbPtr {.inline.} =
proc cPtr*(db: RocksDbRef): RocksDbPtr =
## Get the underlying database pointer.
doAssert not db.isClosed()
db.cPtr
@@ -282,6 +282,74 @@ proc get*(
dataRes.err(res.error())
proc multiGet*(
db: RocksDbRef,
keys: openArray[seq[byte]],
sortedInput = false,
cfHandle = db.defaultCfHandle,
): RocksDBResult[seq[seq[byte]]] =
## Get a batch of values for the given set of keys.
##
## The multiGet API improves performance by batching operations
## in the read path for greater efficiency. Currently, only the block based
## table format with full filters are supported. Other table formats such
## as plain table, block based table with block based filters and
## partitioned indexes will still work, but will not get any performance
## benefits.
##
## sortedInput - If true, it means the input keys are already sorted by key
## order, so the MultiGet() API doesn't have to sort them again. If false,
## the keys will be copied and sorted internally by the API - the input
## array will not be modified.
assert keys.len() > 0
var
keysList = keys.mapIt(cast[cstring](it[0].addr))
keysListSizes = keys.mapIt(csize_t(it.len))
errors = newSeq[cstring](keys.len())
var values =
when NimMajor >= 2 and NimMinor >= 2:
newSeqUninit[ptr rocksdb_pinnableslice_t](keys.len)
else:
newSeq[ptr rocksdb_pinnableslice_t](keys.len)
rocksdb_batched_multi_get_cf(
db.cPtr,
db.readOpts.cPtr,
cfHandle.cPtr,
csize_t(keys.len),
cast[cstringArray](keysList[0].addr),
keysListSizes[0].addr,
values[0].addr,
cast[cstringArray](errors[0].addr),
sortedInput,
)
for e in errors:
if not e.isNil:
let res = err($(e))
rocksdb_free(e)
return res
var data = newSeq[seq[byte]](keys.len())
for i, v in values:
var vLen: csize_t
let src = rocksdb_pinnableslice_value(v, vLen.addr)
if vLen > 0:
var dest =
when NimMajor >= 2 and NimMinor >= 2:
newSeqUninit[byte](vLen.int)
else:
newSeq[byte](vLen.int)
copyMem(dest[0].addr, src, vLen)
data[i] = dest
rocksdb_pinnableslice_destroy(v)
ok(data)
proc put*(
db: RocksDbReadWriteRef, key, val: openArray[byte], cfHandle = db.defaultCfHandle
): RocksDBResult[void] =
@@ -360,6 +428,69 @@ proc delete*(
ok()
proc deleteRange*(
db: RocksDbReadWriteRef,
startKey, endKey: openArray[byte],
cfHandle = db.defaultCfHandle,
): RocksDBResult[void] =
## Removes the database entries in the range [startKey, endKey), i.e. including
## startKey and excluding endKey. It is not an error if no keys exist in the
## range ["beginKey", "endKey").
var errors: cstring
rocksdb_delete_range_cf(
db.cPtr,
db.writeOpts.cPtr,
cfHandle.cPtr,
cast[cstring](startKey.unsafeAddrOrNil()),
csize_t(startKey.len),
cast[cstring](endKey.unsafeAddrOrNil()),
csize_t(endKey.len),
cast[cstringArray](errors.addr),
)
bailOnErrors(errors)
ok()
proc compactRange*(
db: RocksDbReadWriteRef,
startKey, endKey: openArray[byte],
cfHandle = db.defaultCfHandle,
): RocksDBResult[void] =
## Trigger range compaction for the given key range.
rocksdb_compact_range_cf(
db.cPtr,
cfHandle.cPtr,
cast[cstring](startKey.unsafeAddrOrNil()),
csize_t(startKey.len),
cast[cstring](endKey.unsafeAddrOrNil()),
csize_t(endKey.len),
)
ok()
proc suggestCompactRange*(
db: RocksDbReadWriteRef,
startKey, endKey: openArray[byte],
cfHandle = db.defaultCfHandle,
): RocksDBResult[void] =
## Suggest the range to compact.
var errors: cstring
rocksdb_suggest_compact_range_cf(
db.cPtr,
cfHandle.cPtr,
cast[cstring](startKey.unsafeAddrOrNil()),
csize_t(startKey.len),
cast[cstring](endKey.unsafeAddrOrNil()),
csize_t(endKey.len),
cast[cstringArray](errors.addr),
)
bailOnErrors(errors)
ok()
proc openIterator*(
db: RocksDbRef,
readOpts = defaultReadOptions(autoClose = true),
+1 -1
View File
@@ -29,7 +29,7 @@ proc newRocksIterator*(
doAssert not cPtr.isNil()
RocksIteratorRef(cPtr: cPtr, readOpts: readOpts)
proc isClosed*(iter: RocksIteratorRef): bool {.inline.} =
template isClosed*(iter: RocksIteratorRef): bool =
## Returns `true` if the iterator is closed and `false` otherwise.
iter.cPtr.isNil()
+1 -1
View File
@@ -28,7 +28,7 @@ proc newSnapshot*(cPtr: SnapshotPtr, kind: SnapshotType): SnapshotRef =
doAssert not cPtr.isNil()
SnapshotRef(cPtr: cPtr, kind: kind)
proc isClosed*(snapshot: SnapshotRef): bool {.inline.} =
template isClosed*(snapshot: SnapshotRef): bool =
## Returns `true` if the `SnapshotRef` has been closed and `false` otherwise.
snapshot.cPtr.isNil()
+1 -1
View File
@@ -49,7 +49,7 @@ proc openSstFileWriter*(
ok(writer)
proc isClosed*(writer: SstFileWriterRef): bool {.inline.} =
template isClosed*(writer: SstFileWriterRef): bool =
## Returns `true` if the `SstFileWriterRef` is closed and `false` otherwise.
writer.cPtr.isNil()
+1 -1
View File
@@ -102,7 +102,7 @@ proc getColFamilyHandle*(
else:
ok(cfHandle)
proc isClosed*(db: TransactionDbRef): bool {.inline.} =
template isClosed*(db: TransactionDbRef): bool =
## Returns `true` if the `TransactionDbRef` has been closed.
db.cPtr.isNil()
+2 -2
View File
@@ -23,7 +23,7 @@ proc createOptimisticTxOptions*(autoClose = false): OptimisticTxOptionsRef =
cPtr: rocksdb_optimistictransaction_options_create(), autoClose: autoClose
)
proc isClosed*(txOpts: OptimisticTxOptionsRef): bool {.inline.} =
template isClosed*(txOpts: OptimisticTxOptionsRef): bool =
txOpts.cPtr.isNil()
proc cPtr*(txOpts: OptimisticTxOptionsRef): OptimisticTxOptionsPtr =
@@ -37,7 +37,7 @@ template setOpt(nname, ntyp, ctyp: untyped) =
setOpt setSnapshot, bool, uint8
proc defaultOptimisticTxOptions*(autoClose = false): OptimisticTxOptionsRef {.inline.} =
proc defaultOptimisticTxOptions*(autoClose = false): OptimisticTxOptionsRef =
let txOpts = createOptimisticTxOptions(autoClose)
# TODO: set prefered defaults
+1 -1
View File
@@ -56,7 +56,7 @@ proc newTransaction*(
defaultCfHandle: defaultCfHandle,
)
proc isClosed*(tx: TransactionRef): bool {.inline.} =
template isClosed*(tx: TransactionRef): bool =
## Returns `true` if the `TransactionRef` has been closed.
tx.cPtr.isNil()
+2 -4
View File
@@ -23,7 +23,7 @@ proc createTransactionDbOptions*(autoClose = false): TransactionDbOptionsRef =
cPtr: rocksdb_transactiondb_options_create(), autoClose: autoClose
)
proc isClosed*(txDbOpts: TransactionDbOptionsRef): bool {.inline.} =
template isClosed*(txDbOpts: TransactionDbOptionsRef): bool =
txDbOpts.cPtr.isNil()
proc cPtr*(txDbOpts: TransactionDbOptionsRef): TransactionDbOptionsPtr =
@@ -40,9 +40,7 @@ setOpt numStripes, int, csize_t
setOpt transactionLockTimeout, int, int64
setOpt defaultLockTimeout, int, int64
proc defaultTransactionDbOptions*(
autoClose = false
): TransactionDbOptionsRef {.inline.} =
proc defaultTransactionDbOptions*(autoClose = false): TransactionDbOptionsRef =
let txDbOpts = createTransactionDbOptions(autoClose)
# TODO: set prefered defaults
+2 -2
View File
@@ -23,7 +23,7 @@ proc createTransactionOptions*(autoClose = false): TransactionOptionsRef =
cPtr: rocksdb_transaction_options_create(), autoClose: autoClose
)
proc isClosed*(txOpts: TransactionOptionsRef): bool {.inline.} =
template isClosed*(txOpts: TransactionOptionsRef): bool =
txOpts.cPtr.isNil()
proc cPtr*(txOpts: TransactionOptionsRef): TransactionOptionsPtr =
@@ -42,7 +42,7 @@ setOpt deadlockDetectDepth, int, int64
setOpt maxWriteBatchSize, int, csize_t
setOpt skipPrepare, bool, uint8
proc defaultTransactionOptions*(autoClose = false): TransactionOptionsRef {.inline.} =
proc defaultTransactionOptions*(autoClose = false): TransactionOptionsRef =
let txOpts = createTransactionOptions(autoClose)
# TODO: set prefered defaults
+19 -1
View File
@@ -27,7 +27,7 @@ type
proc createWriteBatch*(defaultCfHandle: ColFamilyHandleRef): WriteBatchRef =
WriteBatchRef(cPtr: rocksdb_writebatch_create(), defaultCfHandle: defaultCfHandle)
proc isClosed*(batch: WriteBatchRef): bool {.inline.} =
template isClosed*(batch: WriteBatchRef): bool =
## Returns `true` if the `WriteBatchRef` has been closed and `false` otherwise.
batch.cPtr.isNil()
@@ -73,6 +73,24 @@ proc delete*(
ok()
proc deleteRange*(
batch: WriteBatchRef,
startKey, endKey: openArray[byte],
cfHandle = batch.defaultCfHandle,
): RocksDBResult[void] =
## Add a delete range operation to the write batch.
rocksdb_writebatch_delete_range_cf(
batch.cPtr,
cfHandle.cPtr,
cast[cstring](startKey.unsafeAddrOrNil()),
csize_t(startKey.len),
cast[cstring](endKey.unsafeAddrOrNil()),
csize_t(endKey.len),
)
ok()
proc close*(batch: WriteBatchRef) =
## Close the `WriteBatchRef`.
if not batch.isClosed():
+1 -1
View File
@@ -41,7 +41,7 @@ proc createWriteBatch*(
defaultCfHandle: defaultCfHandle,
)
proc isClosed*(batch: WriteBatchWIRef): bool {.inline.} =
template isClosed*(batch: WriteBatchWIRef): bool =
## Returns `true` if the `WriteBatchWIRef` has been closed and `false` otherwise.
batch.cPtr.isNil()
+46
View File
@@ -101,3 +101,49 @@ suite "ColFamily Tests":
iter.value() == val
iter.seekToKey(otherKey)
check iter.isValid() == false
test "Test deleteRange":
let cf = db.getColFamily(CF_OTHER).get()
let
keyValue1 = @[1.byte]
keyValue2 = @[2.byte]
keyValue3 = @[3.byte]
check:
cf.put(keyValue1, keyValue1).isOk()
cf.put(keyValue2, keyValue2).isOk()
cf.put(keyValue3, keyValue3).isOk()
cf.keyExists(keyValue1).get() == true
cf.keyExists(keyValue2).get() == true
cf.keyExists(keyValue3).get() == true
cf.suggestCompactRange(keyValue1, keyValue3).isOk()
cf.deleteRange(keyValue1, keyValue3).isOk()
cf.compactRange(keyValue1, keyValue3).isOk()
cf.keyExists(keyValue1).get() == false
cf.keyExists(keyValue2).get() == false
cf.keyExists(keyValue3).get() == true
test "Test multiget":
let cf = db.getColFamily(CF_OTHER).get()
let
keyValue1 = @[100.byte]
keyValue2 = @[300.byte]
keyValue3 = @[200.byte]
check:
cf.put(keyValue1, keyValue1).isOk()
cf.put(keyValue2, keyValue2).isOk()
cf.keyExists(keyValue1).get() == true
cf.keyExists(keyValue2).get() == true
cf.keyExists(keyValue3).get() == false
let dataRes = cf.multiGet(@[keyValue1, keyValue2, keyValue3]).expect("ok")
check:
dataRes.len() == 3
dataRes[0] == keyValue1
dataRes[1] == keyValue2
dataRes[2] == default(seq[byte])
+114
View File
@@ -514,3 +514,117 @@ suite "RocksDbRef Tests":
db.put(otherKey, val, defaultCfHandle).isOk()
db.put(key, val, otherCfHandle).isOk()
db.flush(cfHandles).isOk()
test "Test deleteRange":
let
keyValue1 = @[1.byte]
keyValue2 = @[2.byte]
keyValue3 = @[3.byte]
check:
db.put(keyValue1, keyValue1).isOk()
db.put(keyValue2, keyValue2).isOk()
db.put(keyValue3, keyValue3).isOk()
db.keyExists(keyValue1).get() == true
db.keyExists(keyValue2).get() == true
db.keyExists(keyValue3).get() == true
db.deleteRange(keyValue1, keyValue3).isOk()
db.compactRange(keyValue1, keyValue3).isOk()
db.keyExists(keyValue1).get() == false
db.keyExists(keyValue2).get() == false
db.keyExists(keyValue3).get() == true
check:
db.put(keyValue1, keyValue1, otherCfHandle).isOk()
db.put(keyValue2, keyValue2, otherCfHandle).isOk()
db.keyExists(keyValue1, otherCfHandle).get() == true
db.keyExists(keyValue2, otherCfHandle).get() == true
db.keyExists(keyValue3, otherCfHandle).get() == false
db.deleteRange(keyValue1, keyValue2, otherCfHandle).isOk()
db.suggestCompactRange(keyValue1, keyValue3, otherCfHandle).isOk()
db.keyExists(keyValue1, otherCfHandle).get() == false
db.keyExists(keyValue2, otherCfHandle).get() == true
db.keyExists(keyValue3, otherCfHandle).get() == false
test "Test multiget":
let
keyValue1 = @[1.byte]
keyValue2 = @[2.byte]
keyValue3 = @[3.byte]
keyValue4 = @[4.byte]
keyValue5 = @[5.byte]
keyValue6 = @[6.byte]
keyValue7 = @[7.byte]
keyValue8 = @[8.byte]
keyValue9 = @[9.byte]
check:
db.put(keyValue1, keyValue1).isOk()
db.put(keyValue2, keyValue2).isOk()
db.put(keyValue5, keyValue5).isOk()
db.put(keyValue7, keyValue7).isOk()
db.put(keyValue9, keyValue9).isOk()
db.keyExists(keyValue1).get() == true
db.keyExists(keyValue2).get() == true
db.keyExists(keyValue3).get() == false
block:
let dataRes = db.multiGet(@[keyValue1]).expect("ok")
check:
dataRes.len() == 1
dataRes[0] == keyValue1
block:
let dataRes = db.multiGet(@[keyValue1, keyValue2]).expect("ok")
check:
dataRes.len() == 2
dataRes[0] == keyValue1
dataRes[1] == keyValue2
block:
let dataRes = db.multiGet(@[keyValue2, keyValue3]).expect("ok")
check:
dataRes.len() == 2
dataRes[0] == keyValue2
dataRes[1] == default(seq[byte])
block:
let dataRes = db.multiGet(@[keyValue1, keyValue2, keyValue3]).expect("ok")
check:
dataRes.len() == 3
dataRes[0] == keyValue1
dataRes[1] == keyValue2
dataRes[2] == default(seq[byte])
block:
let dataRes =
db.multiGet(@[keyValue1, keyValue2, keyValue3], sortedInput = true).expect("ok")
check:
dataRes.len() == 3
dataRes[0] == keyValue1
dataRes[1] == keyValue2
dataRes[2] == default(seq[byte])
block:
let
keys =
@[
keyValue1, keyValue2, keyValue3, keyValue4, keyValue5, keyValue6, keyValue7,
keyValue8, keyValue9,
]
dataRes = db.multiGet(keys).expect("ok")
check:
dataRes.len() == 9
dataRes[0] == keyValue1
dataRes[1] == keyValue2
dataRes[2] == default(seq[byte])
dataRes[3] == default(seq[byte])
dataRes[4] == keyValue5
dataRes[5] == default(seq[byte])
dataRes[6] == keyValue7
dataRes[7] == default(seq[byte])
dataRes[8] == keyValue9
+24
View File
@@ -195,3 +195,27 @@ suite "WriteBatchRef Tests":
check batch.isClosed()
batch.close()
check batch.isClosed()
test "Test deleteRange":
let batch = db.openWriteBatch()
defer:
batch.close()
let
keyValue1 = @[1.byte]
keyValue2 = @[2.byte]
keyValue3 = @[3.byte]
check:
batch.put(keyValue1, keyValue1).isOk()
batch.put(keyValue2, keyValue2).isOk()
batch.put(keyValue3, keyValue3).isOk()
batch.deleteRange(keyValue1, keyValue3).isOk()
batch.count() == 4
let res1 = db.write(batch)
check:
res1.isOk()
db.keyExists(keyValue1).get() == false
db.keyExists(keyValue2).get() == false
db.keyExists(keyValue3).get() == true