nimbus-eth1/nimbus/db/kvstore_rocksdb.nim
Jacek Sieka 41cf81f80b
Fix dboptions init (#2391)
For the block cache to be shared between column families, the options
instance must be shared between the various column families being
created. This also ensures that there is only one source of truth for
configuration options instead of having two different sets depending on
how the tables were initialized.

This PR also removes the re-opening mechanism which can double startup
time - every time the database is opened, the log is replayed - a large
log file will take a long time to open.

Finally, several options got correclty implemented as column family
options, including an one that puts a hash index in the SST files.
2024-06-19 10:55:57 +02:00

142 lines
3.7 KiB
Nim

# Nimbus
# Copyright (c) 2023-2024 Status Research & Development GmbH
# Licensed under either of
# * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or
# http://www.apache.org/licenses/LICENSE-2.0)
# * MIT license ([LICENSE-MIT](LICENSE-MIT) or
# http://opensource.org/licenses/MIT)
# at your option. This file may not be copied, modified, or distributed except
# according to those terms.
{.push raises: [].}
import
std/[os, sequtils],
results,
rocksdb,
eth/db/kvstore
export kvstore
type
RocksStoreRef* = ref object of RootObj
db: RocksDbReadWriteRef
RocksNamespaceRef* = ref object of RootObj
colFamily: ColFamilyReadWrite
# ------------------------------------------------------------------------------
# RocksStoreRef procs
# ------------------------------------------------------------------------------
proc rocksDb*(store: RocksStoreRef): RocksDbReadWriteRef =
store.db
proc get*(
store: RocksStoreRef,
key: openArray[byte],
onData: kvstore.DataProc): KvResult[bool] =
store.db.get(key, onData)
proc find*(
store: RocksStoreRef,
prefix: openArray[byte],
onFind: kvstore.KeyValueProc): KvResult[int] =
raiseAssert "Unimplemented"
proc put*(store: RocksStoreRef, key, value: openArray[byte]): KvResult[void] =
store.db.put(key, value)
proc contains*(store: RocksStoreRef, key: openArray[byte]): KvResult[bool] =
store.db.keyExists(key)
proc del*(store: RocksStoreRef, key: openArray[byte]): KvResult[bool] =
let rc = store.db.keyExists(key)
if rc.isErr:
return rc
if not rc.value:
return ok(false)
let res = store.db.delete(key)
if res.isErr():
return err(res.error())
ok(true)
proc clear*(store: RocksStoreRef): KvResult[bool] =
raiseAssert "Unimplemented"
proc close*(store: RocksStoreRef) =
store.db.close()
proc init*(
T: type RocksStoreRef,
basePath: string,
name: string,
namespaces = @["default"]): KvResult[T] =
let dataDir = basePath / name / "data"
try:
createDir(dataDir)
except OSError, IOError:
return err("RocksStoreRef: cannot create database directory")
let dbOpts = defaultDbOptions()
let db = ? openRocksDb(dataDir, dbOpts,
columnFamilies = namespaces.mapIt(initColFamilyDescriptor(it)))
ok(T(db: db))
# ------------------------------------------------------------------------------
# RocksNamespaceRef procs
# ------------------------------------------------------------------------------
proc name*(store: RocksNamespaceRef): string =
store.colFamily.name
proc get*(
ns: RocksNamespaceRef,
key: openArray[byte],
onData: kvstore.DataProc): KvResult[bool] =
ns.colFamily.get(key, onData)
proc find*(
ns: RocksNamespaceRef,
prefix: openArray[byte],
onFind: kvstore.KeyValueProc): KvResult[int] =
raiseAssert "Unimplemented"
proc put*(ns: RocksNamespaceRef, key, value: openArray[byte]): KvResult[void] =
ns.colFamily.put(key, value)
proc contains*(ns: RocksNamespaceRef, key: openArray[byte]): KvResult[bool] =
ns.colFamily.keyExists(key)
proc del*(ns: RocksNamespaceRef, key: openArray[byte]): KvResult[bool] =
let exists = ? ns.colFamily.keyExists(key)
if not exists:
return ok(false)
let res = ns.colFamily.delete(key)
if res.isErr():
return err(res.error())
ok(true)
proc clear*(ns: RocksNamespaceRef): KvResult[bool] =
raiseAssert "Unimplemented"
proc close*(ns: RocksNamespaceRef) =
# To close the database, call close on RocksStoreRef.
raiseAssert "Unimplemented"
proc openNamespace*(
store: RocksStoreRef,
name: string): KvResult[RocksNamespaceRef] =
doAssert not store.db.isClosed()
let cf = ? store.db.withColFamily(name)
ok(RocksNamespaceRef(colFamily: cf))