Skip to content

Commit 2f3132f

Browse files
authored
Add option to return err when values don't exist in multiGet (#94)
1 parent 736990c commit 2f3132f

File tree

4 files changed

+46
-33
lines changed

4 files changed

+46
-33
lines changed

rocksdb/columnfamily.nim

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,9 +82,10 @@ template multiGet*(
8282
cf: ColFamilyReadOnly | ColFamilyReadWrite,
8383
keys: openArray[seq[byte]],
8484
sortedInput = false,
85+
errorOnValueNotExists = true,
8586
): RocksDBResult[seq[seq[byte]]] =
8687
## Get a batch of values for the given set of keys.
87-
cf.db.multiGet(keys, sortedInput, cf.handle)
88+
cf.db.multiGet(keys, sortedInput, errorOnValueNotExists, cf.handle)
8889

8990
template put*(cf: ColFamilyReadWrite, key, val: openArray[byte]): RocksDBResult[void] =
9091
## Puts a value for the given key into the column family.

rocksdb/rocksdb.nim

Lines changed: 22 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -269,23 +269,24 @@ proc get*(
269269
db: RocksDbRef, key: openArray[byte], cfHandle = db.defaultCfHandle
270270
): RocksDBResult[seq[byte]] =
271271
## Get the value for the given key from the specified column family.
272-
## If the value does not exist, an empty error will be returned in the result.
272+
## If the value does not exist, an error will be returned in the result.
273273
## If the value does exist, the value will be returned in the result.
274274

275-
var dataRes: RocksDBResult[seq[byte]]
275+
var value: seq[byte]
276276
proc onData(data: openArray[byte]) =
277-
dataRes.ok(@data)
277+
value = @data
278278

279-
let res = db.get(key, onData, cfHandle)
280-
if res.isOk():
281-
return dataRes
282-
283-
dataRes.err(res.error())
279+
let valueExists = ?db.get(key, onData, cfHandle)
280+
if valueExists:
281+
ok(value)
282+
else:
283+
err("rocksdb: value does not exist")
284284

285285
proc multiGet*(
286286
db: RocksDbRef,
287287
keys: openArray[seq[byte]],
288288
sortedInput = false,
289+
errorOnValueNotExists = true,
289290
cfHandle = db.defaultCfHandle,
290291
): RocksDBResult[seq[seq[byte]]] =
291292
## Get a batch of values for the given set of keys.
@@ -304,11 +305,11 @@ proc multiGet*(
304305
assert keys.len() > 0
305306

306307
var
307-
keysList = keys.mapIt(cast[cstring](it[0].addr))
308+
keysList = keys.mapIt(cast[cstring](it.unsafeAddrOrNil()))
308309
keysListSizes = keys.mapIt(csize_t(it.len))
309310
errors = newSeq[cstring](keys.len())
310311

311-
var values =
312+
var valuesPtrs =
312313
when NimMajor >= 2 and NimMinor >= 2:
313314
newSeqUninit[ptr rocksdb_pinnableslice_t](keys.len)
314315
else:
@@ -321,7 +322,7 @@ proc multiGet*(
321322
csize_t(keys.len),
322323
cast[cstringArray](keysList[0].addr),
323324
keysListSizes[0].addr,
324-
values[0].addr,
325+
valuesPtrs[0].addr,
325326
cast[cstringArray](errors[0].addr),
326327
sortedInput,
327328
)
@@ -332,8 +333,14 @@ proc multiGet*(
332333
rocksdb_free(e)
333334
return res
334335

335-
var data = newSeq[seq[byte]](keys.len())
336-
for i, v in values:
336+
var values = newSeq[seq[byte]](keys.len())
337+
for i, v in valuesPtrs:
338+
if v.isNil():
339+
if errorOnValueNotExists:
340+
return err("rocksdb: value does not exist at index " & $i)
341+
else:
342+
continue
343+
337344
var vLen: csize_t
338345
let src = rocksdb_pinnableslice_value(v, vLen.addr)
339346

@@ -344,11 +351,11 @@ proc multiGet*(
344351
else:
345352
newSeq[byte](vLen.int)
346353
copyMem(dest[0].addr, src, vLen)
347-
data[i] = dest
354+
values[i] = dest
348355

349356
rocksdb_pinnableslice_destroy(v)
350357

351-
ok(data)
358+
ok(values)
352359

353360
proc put*(
354361
db: RocksDbReadWriteRef, key, val: openArray[byte], cfHandle = db.defaultCfHandle

tests/test_columnfamily.nim

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,7 @@ suite "ColFamily Tests":
5353
check r1.isOk() and r1.value == val
5454

5555
var r2 = cf.get(otherKey)
56-
# there's no error string for missing keys
57-
check r2.isOk() == false and r2.error.len == 0
56+
check r2.isErr() and r2.error.len > 0
5857

5958
var e1 = cf.keyExists(key)
6059
check e1.isOk() and e1.value == true
@@ -132,14 +131,15 @@ suite "ColFamily Tests":
132131
let
133132
keyValue1 = @[100.byte]
134133
keyValue2 = @[300.byte]
135-
keyValue3 = @[200.byte]
134+
keyValue3 = default(seq[byte])
136135

137136
check:
138137
cf.put(keyValue1, keyValue1).isOk()
139138
cf.put(keyValue2, keyValue2).isOk()
139+
cf.put(keyValue3, keyValue3).isOk()
140140
cf.keyExists(keyValue1).get() == true
141141
cf.keyExists(keyValue2).get() == true
142-
cf.keyExists(keyValue3).get() == false
142+
cf.keyExists(keyValue3).get() == true
143143

144144
let dataRes = cf.multiGet(@[keyValue1, keyValue2, keyValue3]).expect("ok")
145145
check:

tests/test_rocksdb.nim

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,7 @@ suite "RocksDbRef Tests":
5252
check r1.isOk() and r1.value == val
5353

5454
var r2 = db.get(otherKey)
55-
# there's no error string for missing keys
56-
check r2.isOk() == false and r2.error.len == 0
55+
check r2.isErr() and r2.error.len > 0
5756

5857
var e1 = db.keyExists(key)
5958
check e1.isOk() and e1.value == true
@@ -109,8 +108,7 @@ suite "RocksDbRef Tests":
109108
check r1.isOk() and r1.value == val
110109

111110
var r2 = db.get(otherKey)
112-
# there's no error string for missing keys
113-
check r2.isOk() == false and r2.error.len == 0
111+
check r2.isErr() and r2.error.len > 0
114112

115113
var e1 = db.keyExists(key, defaultCfHandle)
116114
check e1.isOk() and e1.value == true
@@ -586,23 +584,30 @@ suite "RocksDbRef Tests":
586584
dataRes[1] == keyValue2
587585

588586
block:
589-
let dataRes = db.multiGet(@[keyValue2, keyValue3]).expect("ok")
587+
let dataRes =
588+
db.multiGet(@[keyValue2, keyValue3], errorOnValueNotExists = false).expect("ok")
590589
check:
591590
dataRes.len() == 2
592591
dataRes[0] == keyValue2
593592
dataRes[1] == default(seq[byte])
594593

595594
block:
596-
let dataRes = db.multiGet(@[keyValue1, keyValue2, keyValue3]).expect("ok")
595+
let
596+
res1 = db.multiGet(@[keyValue1, keyValue2, keyValue3])
597+
res2 =
598+
db.multiGet(@[keyValue1, keyValue2, keyValue3], errorOnValueNotExists = true)
597599
check:
598-
dataRes.len() == 3
599-
dataRes[0] == keyValue1
600-
dataRes[1] == keyValue2
601-
dataRes[2] == default(seq[byte])
600+
res1.isErr()
601+
res2.isErr()
602602

603603
block:
604-
let dataRes =
605-
db.multiGet(@[keyValue1, keyValue2, keyValue3], sortedInput = true).expect("ok")
604+
let dataRes = db
605+
.multiGet(
606+
@[keyValue1, keyValue2, keyValue3],
607+
sortedInput = true,
608+
errorOnValueNotExists = false,
609+
)
610+
.expect("ok")
606611
check:
607612
dataRes.len() == 3
608613
dataRes[0] == keyValue1
@@ -616,7 +621,7 @@ suite "RocksDbRef Tests":
616621
keyValue1, keyValue2, keyValue3, keyValue4, keyValue5, keyValue6, keyValue7,
617622
keyValue8, keyValue9,
618623
]
619-
dataRes = db.multiGet(keys).expect("ok")
624+
dataRes = db.multiGet(keys, errorOnValueNotExists = false).expect("ok")
620625
check:
621626
dataRes.len() == 9
622627
dataRes[0] == keyValue1

0 commit comments

Comments
 (0)