nimbus-eth1/nimbus/db/kvt/kvt_api.nim

259 lines
7.7 KiB
Nim

# nimbus-eth1
# Copyright (c) 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.
## Stackable API for `Kvt`
## =======================
import
std/times,
eth/common,
results,
../aristo/aristo_profile,
"."/[kvt_desc, kvt_desc/desc_backend, kvt_init, kvt_tx, kvt_utils]
# Annotation helper(s)
{.pragma: noRaise, gcsafe, raises: [].}
type
KvtDbProfListRef* = AristoDbProfListRef
## Borrowed from `aristo_profile`
KvtDbProfData* = AristoDbProfData
## Borrowed from `aristo_profile`
KvtApiCommitFn* = proc(tx: KvtTxRef): Result[void,KvtError] {.noRaise.}
KvtApiDelFn* = proc(db: KvtDbRef,
key: openArray[byte]): Result[void,KvtError] {.noRaise.}
KvtApiFinishFn* = proc(db: KvtDbRef, flush = false) {.noRaise.}
KvtApiForgetFn* = proc(db: KvtDbRef): Result[void,KvtError] {.noRaise.}
KvtApiForkFn* = proc(db: KvtDbRef): Result[KvtDbRef,KvtError] {.noRaise.}
KvtApiForkTopFn* = proc(db: KvtDbRef): Result[KvtDbRef,KvtError] {.noRaise.}
KvtApiGetFn* = proc(db: KvtDbRef,
key: openArray[byte]): Result[Blob,KvtError] {.noRaise.}
KvtApiHasKeyFn* = proc(db: KvtDbRef,
key: openArray[byte]): Result[bool,KvtError] {.noRaise.}
KvtApiIsTopFn* = proc(tx: KvtTxRef): bool {.noRaise.}
KvtApiLevelFn* = proc(db: KvtDbRef): int {.noRaise.}
KvtApiNForkedFn* = proc(db: KvtDbRef): int {.noRaise.}
KvtApiPutFn* = proc(db: KvtDbRef,
key, data: openArray[byte]): Result[void,KvtError] {.noRaise.}
KvtApiRollbackFn* = proc(tx: KvtTxRef): Result[void,KvtError] {.noRaise.}
KvtApiStowFn* = proc(db: KvtDbRef): Result[void,KvtError] {.noRaise.}
KvtApiTxBeginFn* = proc(db: KvtDbRef): Result[KvtTxRef,KvtError] {.noRaise.}
KvtApiTxTopFn* =
proc(db: KvtDbRef): Result[KvtTxRef,KvtError] {.noRaise.}
KvtApiRef* = ref KvtApiObj
KvtApiObj* = object of RootObj
## Useful set of `Kvt` fuctions that can be filtered, stacked etc. Note
## that this API is modelled after a subset of the `Aristo` API.
commit*: KvtApiCommitFn
del*: KvtApiDelFn
finish*: KvtApiFinishFn
forget*: KvtApiForgetFn
fork*: KvtApiForkFn
forkTop*: KvtApiForkTopFn
get*: KvtApiGetFn
hasKey*: KvtApiHasKeyFn
isTop*: KvtApiIsTopFn
level*: KvtApiLevelFn
nForked*: KvtApiNForkedFn
put*: KvtApiPutFn
rollback*: KvtApiRollbackFn
stow*: KvtApiStowFn
txBegin*: KvtApiTxBeginFn
txTop*: KvtApiTxTopFn
KvtApiProfNames* = enum
## index/name mapping for profile slots
KvtApiProfTotal = "total"
KvtApiProfCommitFn = "commit"
KvtApiProfDelFn = "del"
KvtApiProfFinishFn = "finish"
KvtApiProfForgetFn = "forget"
KvtApiProfForkFn = "fork"
KvtApiProfForkTopFn = "forkTop"
KvtApiProfGetFn = "get"
KvtApiProfHasKeyFn = "hasKey"
KvtApiProfIsTopFn = "isTop"
KvtApiProfLevelFn = "level"
KvtApiProfNForkedFn = "nForked"
KvtApiProfPutFn = "put"
KvtApiProfRollbackFn = "rollback"
KvtApiProfStowFn = "stow"
KvtApiProfTxBeginFn = "txBegin"
KvtApiProfTxTopFn = "txTop"
KvtApiProfBeGetKvpFn = "be/getKvp"
KvtApiProfBePutEndFn = "be/putEnd"
KvtApiProfRef* = ref object of KvtApiRef
## Profiling API extension of `KvtApiObj`
data*: KvtDbProfListRef
be*: BackendRef
# ------------------------------------------------------------------------------
# Public API constuctors
# ------------------------------------------------------------------------------
func init*(api: var KvtApiObj) =
api.commit = commit
api.del = del
api.finish = finish
api.forget = forget
api.fork = fork
api.forkTop = forkTop
api.get = get
api.hasKey = hasKey
api.isTop = isTop
api.level = level
api.nForked = nForked
api.put = put
api.rollback = rollback
api.stow = stow
api.txBegin = txBegin
api.txTop = txTop
func init*(T: type KvtApiRef): T =
result = new T
result[].init()
func dup*(api: KvtApiRef): KvtApiRef =
new result
result[] = api[]
# ------------------------------------------------------------------------------
# Public profile API constuctor
# ------------------------------------------------------------------------------
func init*(
T: type KvtApiProfRef;
api: KvtApiRef;
be = BackendRef(nil);
): T =
## This constructor creates a profiling API descriptor to be derived from
## an initialised `api` argument descriptor. For profiling the DB backend,
## the field `.be` of the result descriptor must be assigned to the
## `.backend` field of the `KvtDbRef` descriptor.
##
## The argument desctiptors `api` and `be` will not be modified and can be
## used to restore the previous set up.
##
let
data = KvtDbProfListRef(
list: newSeq[KvtDbProfData](1 + high(KvtApiProfNames).ord))
profApi = T(data: data)
template profileRunner(n: KvtApiProfNames, code: untyped): untyped =
let start = getTime()
code
data.update(n.ord, getTime() - start)
profApi.commit =
proc(a: KvtTxRef): auto =
KvtApiProfCommitFn.profileRunner:
result = api.commit(a)
profApi.del =
proc(a: KvtDbRef; b: openArray[byte]): auto =
KvtApiProfDelFn.profileRunner:
result = api.del(a, b)
profApi.finish =
proc(a: KvtDbRef; b = false) =
KvtApiProfFinishFn.profileRunner:
api.finish(a, b)
profApi.forget =
proc(a: KvtDbRef): auto =
KvtApiProfForgetFn.profileRunner:
result = api.forget(a)
profApi.fork =
proc(a: KvtDbRef): auto =
KvtApiProfForkFn.profileRunner:
result = api.fork(a)
profApi.forkTop =
proc(a: KvtDbRef): auto =
KvtApiProfForkTopFn.profileRunner:
result = api.forkTop(a)
profApi.get =
proc(a: KvtDbRef, b: openArray[byte]): auto =
KvtApiProfGetFn.profileRunner:
result = api.get(a, b)
profApi.hasKey =
proc(a: KvtDbRef, b: openArray[byte]): auto =
KvtApiProfHasKeyFn.profileRunner:
result = api.hasKey(a, b)
profApi.isTop =
proc(a: KvtTxRef): auto =
KvtApiProfIsTopFn.profileRunner:
result = api.isTop(a)
profApi.level =
proc(a: KvtDbRef): auto =
KvtApiProfLevelFn.profileRunner:
result = api.level(a)
profApi.nForked =
proc(a: KvtDbRef): auto =
KvtApiProfNForkedFn.profileRunner:
result = api.nForked(a)
profApi.put =
proc(a: KvtDbRef; b, c: openArray[byte]): auto =
KvtApiProfPutFn.profileRunner:
result = api.put(a, b, c)
profApi.rollback =
proc(a: KvtTxRef): auto =
KvtApiProfRollbackFn.profileRunner:
result = api.rollback(a)
profApi.stow =
proc(a: KvtDbRef): auto =
KvtApiProfStowFn.profileRunner:
result = api.stow(a)
profApi.txBegin =
proc(a: KvtDbRef): auto =
KvtApiProfTxBeginFn.profileRunner:
result = api.txBegin(a)
profApi.txTop =
proc(a: KvtDbRef): auto =
KvtApiProfTxTopFn.profileRunner:
result = api.txTop(a)
if not be.isNil:
profApi.be = be.dup
profApi.be.getKvpFn =
proc(a: openArray[byte]): auto =
KvtApiProfBeGetKvpFn.profileRunner:
result = be.getKvpFn(a)
profApi.be.putEndFn =
proc(a: PutHdlRef): auto =
KvtApiProfBePutEndFn.profileRunner:
result = be.putEndFn(a)
profApi
# ------------------------------------------------------------------------------
# End
# ------------------------------------------------------------------------------