mirror of
https://github.com/status-im/nimbus-eth1.git
synced 2025-02-10 19:17:16 +00:00
why: For the main tree with root vertex ID 1, the leaf nodes hold the account data. These accounts may link to sub trees the storage root node ID of which must be registered here. There is no reverse key lookup on the backend. note: These definitions are experimental. Also, there are some tests missing for validating Payload data conversions.
588 lines
17 KiB
Nim
588 lines
17 KiB
Nim
# nimbus-eth1
|
|
# Copyright (c) 2021 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/[algorithm, sequtils, sets, strutils, tables],
|
|
eth/[common, trie/nibbles],
|
|
stew/byteutils,
|
|
"."/[aristo_constants, aristo_desc, aristo_hike, aristo_init, aristo_vid],
|
|
./aristo_init/[aristo_memory, aristo_rocksdb]
|
|
|
|
# ------------------------------------------------------------------------------
|
|
# Ptivate functions
|
|
# ------------------------------------------------------------------------------
|
|
|
|
proc sortedKeys(lTab: Table[LeafTie,VertexID]): seq[LeafTie] =
|
|
lTab.keys.toSeq.sorted(cmp = proc(a,b: LeafTie): int = cmp(a,b))
|
|
|
|
proc sortedKeys(kMap: Table[VertexID,HashLabel]): seq[VertexID] =
|
|
kMap.keys.toSeq.mapIt(it.uint64).sorted.mapIt(it.VertexID)
|
|
|
|
proc sortedKeys(sTab: Table[VertexID,VertexRef]): seq[VertexID] =
|
|
sTab.keys.toSeq.mapIt(it.uint64).sorted.mapIt(it.VertexID)
|
|
|
|
proc sortedKeys(pPrf: HashSet[VertexID]): seq[VertexID] =
|
|
pPrf.toSeq.mapIt(it.uint64).sorted.mapIt(it.VertexID)
|
|
|
|
proc toPfx(indent: int; offset = 0): string =
|
|
if 0 < indent+offset: "\n" & " ".repeat(indent+offset) else: ""
|
|
|
|
proc labelVidUpdate(db: AristoDbRef, lbl: HashLabel, vid: VertexID): string =
|
|
if lbl.key.isValid and vid.isValid:
|
|
if not db.top.isNil:
|
|
let lblVid = db.top.pAmk.getOrVoid lbl
|
|
if lblVid.isValid:
|
|
if lblVid != vid:
|
|
result = "(!)"
|
|
return
|
|
block:
|
|
let lblVid = db.xMap.getOrVoid lbl
|
|
if lblVid.isValid:
|
|
if lblVid != vid:
|
|
result = "(!)"
|
|
return
|
|
db.xMap[lbl] = vid
|
|
|
|
proc squeeze(s: string; hex = false; ignLen = false): string =
|
|
## For long strings print `begin..end` only
|
|
if hex:
|
|
let n = (s.len + 1) div 2
|
|
result = if s.len < 20: s else: s[0 .. 5] & ".." & s[s.len-8 .. ^1]
|
|
if not ignLen:
|
|
result &= "[" & (if 0 < n: "#" & $n else: "") & "]"
|
|
elif s.len <= 30:
|
|
result = s
|
|
else:
|
|
result = if (s.len and 1) == 0: s[0 ..< 8] else: "0" & s[0 ..< 7]
|
|
if not ignLen:
|
|
result &= "..(" & $s.len & ")"
|
|
result &= ".." & s[s.len-16 .. ^1]
|
|
|
|
proc stripZeros(a: string): string =
|
|
a.strip(leading=true, trailing=false, chars={'0'}).toLowerAscii
|
|
|
|
proc ppVid(vid: VertexID; pfx = true): string =
|
|
if pfx:
|
|
result = "$"
|
|
if vid.isValid:
|
|
result &= vid.uint64.toHex.stripZeros.toLowerAscii
|
|
else:
|
|
result &= "ø"
|
|
|
|
proc ppVidList(vGen: openArray[VertexID]): string =
|
|
"[" & vGen.mapIt(it.ppVid).join(",") & "]"
|
|
|
|
proc vidCode(lbl: HashLabel, db: AristoDbRef): uint64 =
|
|
if lbl.isValid:
|
|
if not db.top.isNil:
|
|
let vid = db.top.pAmk.getOrVoid lbl
|
|
if vid.isValid:
|
|
return vid.uint64
|
|
block:
|
|
let vid = db.xMap.getOrVoid lbl
|
|
if vid.isValid:
|
|
return vid.uint64
|
|
|
|
proc ppKey(key: HashKey): string =
|
|
if key == HashKey.default:
|
|
return "£ø"
|
|
if key == VOID_HASH_KEY:
|
|
return "£r"
|
|
|
|
"%" & key.ByteArray32
|
|
.mapIt(it.toHex(2)).join.tolowerAscii
|
|
.squeeze(hex=true,ignLen=true)
|
|
|
|
proc ppLabel(lbl: HashLabel; db: AristoDbRef): string =
|
|
if lbl.key == HashKey.default:
|
|
return "£ø"
|
|
if lbl.key == VOID_HASH_KEY:
|
|
return "£r"
|
|
|
|
let rid = if not lbl.root.isValid: "ø:"
|
|
else: ($lbl.root.uint64.toHex).stripZeros & ":"
|
|
if not db.top.isNil:
|
|
let vid = db.top.pAmk.getOrVoid lbl
|
|
if vid.isValid:
|
|
return "£" & rid & vid.ppVid(pfx=false)
|
|
block:
|
|
let vid = db.xMap.getOrVoid lbl
|
|
if vid.isValid:
|
|
return "£" & rid & vid.ppVid(pfx=false)
|
|
|
|
"%" & rid & lbl.key.ByteArray32
|
|
.mapIt(it.toHex(2)).join.tolowerAscii
|
|
.squeeze(hex=true,ignLen=true)
|
|
|
|
proc ppRootKey(a: HashKey): string =
|
|
if a.isValid:
|
|
return a.ppKey
|
|
|
|
proc ppCodeKey(a: HashKey): string =
|
|
a.ppKey
|
|
|
|
proc ppLeafTie(lty: LeafTie, db: AristoDbRef): string =
|
|
if not db.top.isNil:
|
|
let vid = db.top.lTab.getOrVoid lty
|
|
if vid.isValid:
|
|
return "@" & vid.ppVid
|
|
|
|
"@" & ($lty.root.uint64.toHex).stripZeros & ":" &
|
|
lty.path.to(HashKey).ByteArray32
|
|
.mapIt(it.toHex(2)).join.squeeze(hex=true,ignLen=true)
|
|
|
|
proc ppPathPfx(pfx: NibblesSeq): string =
|
|
let s = $pfx
|
|
if s.len < 20: s else: s[0 .. 5] & ".." & s[s.len-8 .. ^1] & ":" & $s.len
|
|
|
|
proc ppNibble(n: int8): string =
|
|
if n < 0: "ø" elif n < 10: $n else: n.toHex(1).toLowerAscii
|
|
|
|
proc ppPayload(p: PayloadRef, db: AristoDbRef): string =
|
|
if p.isNil:
|
|
result = "n/a"
|
|
else:
|
|
case p.pType:
|
|
of RawData:
|
|
result &= p.rawBlob.toHex.squeeze(hex=true)
|
|
of RlpData:
|
|
result &= "(" & p.rlpBlob.toHex.squeeze(hex=true) & ")"
|
|
of AccountData:
|
|
result = "("
|
|
result &= $p.account.nonce & ","
|
|
result &= $p.account.balance & ","
|
|
result &= p.account.storageID.ppVid & ","
|
|
result &= p.account.codeHash.to(HashKey).ppCodeKey() & ")"
|
|
of LegacyAccount:
|
|
result = "("
|
|
result &= $p.legaAcc.nonce & ","
|
|
result &= $p.legaAcc.balance & ","
|
|
result &= p.legaAcc.storageRoot.to(HashKey).ppRootKey() & ","
|
|
result &= p.legaAcc.codeHash.to(HashKey).ppCodeKey() & ")"
|
|
|
|
proc ppVtx(nd: VertexRef, db: AristoDbRef, vid: VertexID): string =
|
|
if not nd.isValid:
|
|
result = "ø"
|
|
else:
|
|
if db.top.isNil or not vid.isValid or vid in db.top.pPrf:
|
|
result = ["L(", "X(", "B("][nd.vType.ord]
|
|
elif vid in db.top.kMap:
|
|
result = ["l(", "x(", "b("][nd.vType.ord]
|
|
else:
|
|
result = ["ł(", "€(", "þ("][nd.vType.ord]
|
|
case nd.vType:
|
|
of Leaf:
|
|
result &= nd.lPfx.ppPathPfx & "," & nd.lData.ppPayload(db)
|
|
of Extension:
|
|
result &= nd.ePfx.ppPathPfx & "," & nd.eVid.ppVid
|
|
of Branch:
|
|
for n in 0..15:
|
|
if nd.bVid[n].isValid:
|
|
result &= nd.bVid[n].ppVid
|
|
if n < 15:
|
|
result &= ","
|
|
result &= ")"
|
|
|
|
proc ppSTab(
|
|
sTab: Table[VertexID,VertexRef];
|
|
db = AristoDbRef();
|
|
indent = 4;
|
|
): string =
|
|
"{" & sTab.sortedKeys
|
|
.mapIt((it, sTab.getOrVoid it))
|
|
.mapIt("(" & it[0].ppVid & "," & it[1].ppVtx(db,it[0]) & ")")
|
|
.join("," & indent.toPfx(1)) & "}"
|
|
|
|
proc ppLTab(
|
|
lTab: Table[LeafTie,VertexID];
|
|
indent = 4;
|
|
): string =
|
|
let db = AristoDbRef()
|
|
"{" & lTab.sortedKeys
|
|
.mapIt((it, lTab.getOrVoid it))
|
|
.mapIt("(" & it[0].ppLeafTie(db) & "," & it[1].ppVid & ")")
|
|
.join("," & indent.toPfx(1)) & "}"
|
|
|
|
proc ppPPrf(pPrf: HashSet[VertexID]): string =
|
|
"{" & pPrf.sortedKeys.mapIt(it.ppVid).join(",") & "}"
|
|
|
|
proc ppXMap*(
|
|
db: AristoDbRef;
|
|
kMap: Table[VertexID,HashLabel];
|
|
pAmk: Table[HashLabel,VertexID];
|
|
indent: int;
|
|
): string =
|
|
|
|
let
|
|
pfx = indent.toPfx(1)
|
|
dups = pAmk.values.toSeq.toCountTable.pairs.toSeq
|
|
.filterIt(1 < it[1]).toTable
|
|
revOnly = pAmk.pairs.toSeq.filterIt(not kMap.hasKey it[1])
|
|
.mapIt((it[1],it[0])).toTable
|
|
|
|
proc ppNtry(n: uint64): string =
|
|
var s = VertexID(n).ppVid
|
|
let lbl = kMap.getOrVoid VertexID(n)
|
|
if lbl.isValid:
|
|
let vid = pAmk.getOrVoid lbl
|
|
if not vid.isValid:
|
|
s = "(" & s & "," & lbl.ppLabel(db) & ",ø"
|
|
elif vid != VertexID(n):
|
|
s = "(" & s & "," & lbl.ppLabel(db) & "," & vid.ppVid
|
|
let count = dups.getOrDefault(VertexID(n), 0)
|
|
if 0 < count:
|
|
if s[0] != '(':
|
|
s &= "(" & s
|
|
s &= ",*" & $count
|
|
else:
|
|
s &= "£ø"
|
|
if s[0] == '(':
|
|
s &= ")"
|
|
s & ","
|
|
|
|
result = "{"
|
|
# Extra reverse lookups
|
|
let revKeys = revOnly.keys.toSeq.mapIt(it.uint64).sorted.mapIt(it.VertexID)
|
|
if 0 < revKeys.len:
|
|
proc ppRevlabel(vid: VertexID): string =
|
|
"(ø," & revOnly.getOrVoid(vid).ppLabel(db) & ")"
|
|
var (i, r) = (0, revKeys[0])
|
|
result &= revKeys[0].ppRevlabel
|
|
for n in 1 ..< revKeys.len:
|
|
let vid = revKeys[n]
|
|
r.inc
|
|
if r != vid:
|
|
if i+1 != n:
|
|
if i+1 == n-1:
|
|
result &= pfx
|
|
else:
|
|
result &= ".. "
|
|
result &= revKeys[n-1].ppRevlabel
|
|
result &= pfx & vid.ppRevlabel
|
|
(i, r) = (n, vid)
|
|
if i < revKeys.len - 1:
|
|
if i+1 != revKeys.len - 1:
|
|
result &= ".. "
|
|
else:
|
|
result &= pfx
|
|
result &= revKeys[^1].ppRevlabel
|
|
|
|
# Forward lookups
|
|
var cache: seq[(uint64,uint64,bool)]
|
|
for vid in kMap.sortedKeys:
|
|
let lbl = kMap.getOrVoid vid
|
|
if lbl.isValid:
|
|
cache.add (vid.uint64, lbl.vidCode(db), 0 < dups.getOrDefault(vid, 0))
|
|
let lblVid = pAmk.getOrDefault(lbl, VertexID(0))
|
|
if lblVid != VertexID(0) and lblVid != vid:
|
|
cache[^1][2] = true
|
|
else:
|
|
cache.add (vid.uint64, 0u64, true)
|
|
|
|
if 0 < cache.len:
|
|
var (i, r) = (0, cache[0])
|
|
if 0 < revKeys.len:
|
|
result &= pfx
|
|
result &= cache[i][0].ppNtry
|
|
for n in 1 ..< cache.len:
|
|
let
|
|
m = cache[n-1]
|
|
w = cache[n]
|
|
r = (r[0]+1, r[1]+1, r[2])
|
|
if r != w or w[2]:
|
|
if i+1 != n:
|
|
if i+1 == n-1:
|
|
result &= pfx
|
|
else:
|
|
result &= ".. "
|
|
result &= m[0].ppNtry
|
|
result &= pfx & w[0].ppNtry
|
|
(i, r) = (n, w)
|
|
if i < cache.len - 1:
|
|
if i+1 != cache.len - 1:
|
|
result &= ".. "
|
|
else:
|
|
result &= pfx
|
|
result &= cache[^1][0].ppNtry
|
|
result[^1] = '}'
|
|
else:
|
|
result &= "}"
|
|
|
|
proc ppBe[T](be: T; db: AristoDbRef; indent: int): string =
|
|
## Walk over backend tables
|
|
let
|
|
pfx = indent.toPfx
|
|
pfx1 = indent.toPfx(1)
|
|
pfx2 = indent.toPfx(2)
|
|
result = "<" & $be.kind & ">"
|
|
result &= pfx & "vGen" & pfx1 & "[" & be.walkIdg.toSeq.mapIt(
|
|
it[2].mapIt(it.ppVid).join(",")
|
|
).join(",") & "]"
|
|
result &= pfx & "sTab" & pfx1 & "{" & be.walkVtx.toSeq.mapIt(
|
|
$(1+it[0]) & "(" & it[1].ppVid & "," & it[2].ppVtx(db,it[1]) & ")"
|
|
).join(pfx2) & "}"
|
|
result &= pfx & "kMap" & pfx1 & "{" & be.walkKey.toSeq.mapIt(
|
|
$(1+it[0]) & "(" & it[1].ppVid & "," & it[2].ppKey & ")"
|
|
).join(pfx2) & "}"
|
|
|
|
|
|
proc ppCache(
|
|
db: AristoDbRef;
|
|
vGenOk: bool;
|
|
sTabOk: bool;
|
|
lTabOk: bool;
|
|
kMapOk: bool;
|
|
pPrfOk: bool;
|
|
indent = 4;
|
|
): string =
|
|
let
|
|
pfx1 = indent.toPfx
|
|
pfx2 = indent.toPfx(1)
|
|
tagOk = 1 < sTabOk.ord + lTabOk.ord + kMapOk.ord + pPrfOk.ord + vGenOk.ord
|
|
var
|
|
pfy = ""
|
|
|
|
proc doPrefix(s: string; dataOk: bool): string =
|
|
var rc: string
|
|
if tagOk:
|
|
rc = pfy & s & (if dataOk: pfx2 else: " ")
|
|
pfy = pfx1
|
|
else:
|
|
rc = pfy
|
|
pfy = pfx2
|
|
rc
|
|
|
|
if not db.top.isNil:
|
|
if vGenOk:
|
|
let
|
|
tLen = db.top.vGen.len
|
|
info = "vGen(" & $tLen & ")"
|
|
result &= info.doPrefix(0 < tLen) & db.top.vGen.ppVidList
|
|
if sTabOk:
|
|
let
|
|
tLen = db.top.sTab.len
|
|
info = "sTab(" & $tLen & ")"
|
|
result &= info.doPrefix(0 < tLen) & db.top.sTab.ppSTab(db,indent+1)
|
|
if lTabOk:
|
|
let
|
|
tlen = db.top.lTab.len
|
|
info = "lTab(" & $tLen & ")"
|
|
result &= info.doPrefix(0 < tLen) & db.top.lTab.ppLTab(indent+1)
|
|
if kMapOk:
|
|
let
|
|
tLen = db.top.kMap.len
|
|
ulen = db.top.pAmk.len
|
|
lInf = if tLen == uLen: $tLen else: $tLen & "," & $ulen
|
|
info = "kMap(" & lInf & ")"
|
|
result &= info.doPrefix(0 < tLen + uLen)
|
|
result &= db.ppXMap(db.top.kMap,db.top.pAmk,indent+1)
|
|
if pPrfOk:
|
|
let
|
|
tLen = db.top.pPrf.len
|
|
info = "pPrf(" & $tLen & ")"
|
|
result &= info.doPrefix(0 < tLen) & db.top.pPrf.ppPPrf
|
|
|
|
# ------------------------------------------------------------------------------
|
|
# Public functions
|
|
# ------------------------------------------------------------------------------
|
|
|
|
proc lblToVtxID*(db: AristoDbRef, lbl: HashLabel): VertexID =
|
|
## Associate a vertex ID with the argument `key` for pretty printing.
|
|
if lbl.isValid:
|
|
let vid = db.xMap.getOrVoid lbl
|
|
if vid.isValid:
|
|
result = vid
|
|
else:
|
|
result = db.vidFetch()
|
|
db.xMap[lbl] = result
|
|
|
|
proc hashToVtxID*(db: AristoDbRef; root: VertexID; hash: Hash256): VertexID =
|
|
db.lblToVtxID HashLabel(root: root, key: hash.to(HashKey))
|
|
|
|
proc pp*(key: HashKey): string =
|
|
key.ppKey
|
|
|
|
proc pp*(lbl: HashLabel, db = AristoDbRef()): string =
|
|
lbl.ppLabel(db)
|
|
|
|
proc pp*(lty: LeafTie, db = AristoDbRef()): string =
|
|
lty.ppLeafTie(db)
|
|
|
|
proc pp*(vid: VertexID): string =
|
|
vid.ppVid
|
|
|
|
proc pp*(vGen: openArray[VertexID]): string =
|
|
vGen.ppVidList
|
|
|
|
proc pp*(p: PayloadRef, db = AristoDbRef()): string =
|
|
p.ppPayload(db)
|
|
|
|
proc pp*(nd: VertexRef, db = AristoDbRef()): string =
|
|
nd.ppVtx(db, VertexID(0))
|
|
|
|
proc pp*(nd: NodeRef; root: VertexID; db: AristoDBRef): string =
|
|
if not nd.isValid:
|
|
result = "n/a"
|
|
elif nd.error != AristoError(0):
|
|
result = "(!" & $nd.error
|
|
else:
|
|
result = ["L(", "X(", "B("][nd.vType.ord]
|
|
case nd.vType:
|
|
of Leaf:
|
|
result &= $nd.lPfx.ppPathPfx & "," & nd.lData.pp(db)
|
|
|
|
of Extension:
|
|
let lbl = HashLabel(root: root, key: nd.key[0])
|
|
result &= $nd.ePfx.ppPathPfx & "," & nd.eVid.ppVid & ","
|
|
result &= lbl.ppLabel(db) & db.labelVidUpdate(lbl, nd.eVid)
|
|
|
|
of Branch:
|
|
result &= "["
|
|
for n in 0..15:
|
|
if nd.bVid[n].isValid or nd.key[n].isValid:
|
|
result &= nd.bVid[n].ppVid
|
|
let lbl = HashLabel(root: root, key: nd.key[n])
|
|
result &= db.labelVidUpdate(lbl, nd.bVid[n]) & ","
|
|
result[^1] = ']'
|
|
|
|
result &= ",["
|
|
for n in 0..15:
|
|
if nd.bVid[n].isValid or nd.key[n].isValid:
|
|
result &= HashLabel(root: root, key: nd.key[n]).ppLabel(db)
|
|
result &= ","
|
|
result[^1] = ']'
|
|
result &= ")"
|
|
|
|
proc pp*(nd: NodeRef): string =
|
|
var db = AristoDbRef()
|
|
nd.pp(db)
|
|
|
|
proc pp*(
|
|
sTab: Table[VertexID,VertexRef];
|
|
db = AristoDbRef();
|
|
indent = 4;
|
|
): string =
|
|
sTab.ppSTab
|
|
|
|
proc pp*(lTab: Table[LeafTie,VertexID]; indent = 4): string =
|
|
lTab.ppLTab
|
|
|
|
proc pp*(pPrf: HashSet[VertexID]): string =
|
|
pPrf.ppPPrf
|
|
|
|
proc pp*(leg: Leg; db = AristoDbRef()): string =
|
|
result = "(" & leg.wp.vid.ppVid & ","
|
|
if not db.top.isNil:
|
|
let lbl = db.top.kMap.getOrVoid leg.wp.vid
|
|
if not lbl.isValid:
|
|
result &= "ø"
|
|
elif leg.wp.vid != db.top.pAmk.getOrVoid lbl:
|
|
result &= lbl.ppLabel(db)
|
|
result &= ","
|
|
if leg.backend:
|
|
result &= "*"
|
|
result &= ","
|
|
if 0 <= leg.nibble:
|
|
result &= $leg.nibble.ppNibble
|
|
result &= "," & leg.wp.vtx.pp(db) & ")"
|
|
|
|
proc pp*(hike: Hike; db = AristoDbRef(); indent = 4): string =
|
|
let pfx = indent.toPfx(1)
|
|
result = "["
|
|
if hike.legs.len == 0:
|
|
result &= "(" & hike.root.ppVid & ")"
|
|
else:
|
|
if hike.legs[0].wp.vid != hike.root:
|
|
result &= "(" & hike.root.ppVid & ")" & pfx
|
|
result &= hike.legs.mapIt(it.pp(db)).join(pfx)
|
|
result &= pfx & "(" & hike.tail.ppPathPfx & ")"
|
|
if hike.error != AristoError(0):
|
|
result &= pfx & "(" & $hike.error & ")"
|
|
result &= "]"
|
|
|
|
proc pp*(kMap: Table[VertexID,Hashlabel]; indent = 4): string =
|
|
let db = AristoDbRef()
|
|
"{" & kMap.sortedKeys
|
|
.mapIt((it,kMap.getOrVoid it))
|
|
.filterIt(it[1].isValid)
|
|
.mapIt("(" & it[0].ppVid & "," & it[1].ppLabel(db) & ")")
|
|
.join("," & indent.toPfx(1)) & "}"
|
|
|
|
proc pp*(pAmk: Table[Hashlabel,VertexID]; indent = 4): string =
|
|
let db = AristoDbRef()
|
|
var rev = pAmk.pairs.toSeq.mapIt((it[1],it[0])).toTable
|
|
"{" & rev.sortedKeys
|
|
.mapIt((it,rev.getOrVoid it))
|
|
.filterIt(it[1].isValid)
|
|
.mapIt("(" & it[1].ppLabel(db) & "," & it[0].ppVid & ")")
|
|
.join("," & indent.toPfx(1)) & "}"
|
|
|
|
proc pp*(kMap: Table[VertexID,Hashlabel]; db: AristoDbRef; indent = 4): string =
|
|
db.ppXMap(kMap, db.top.pAmk, indent)
|
|
|
|
proc pp*(pAmk: Table[Hashlabel,VertexID]; db: AristoDbRef; indent = 4): string =
|
|
db.ppXMap(db.top.kMap, pAmk, indent)
|
|
|
|
proc pp*(
|
|
be: MemBackendRef|RdbBackendRef;
|
|
db: AristoDbRef;
|
|
indent = 4;
|
|
): string =
|
|
be.ppBe(db, indent)
|
|
|
|
# ---------------------
|
|
|
|
proc pp*(
|
|
db: AristoDbRef;
|
|
indent = 4;
|
|
): string =
|
|
db.ppCache(
|
|
vGenOk=true, sTabOk=true, lTabOk=true, kMapOk=true, pPrfOk=true)
|
|
|
|
proc pp*(
|
|
db: AristoDbRef;
|
|
xTabOk: bool;
|
|
indent = 4;
|
|
): string =
|
|
db.ppCache(
|
|
vGenOk=true, sTabOk=xTabOk, lTabOk=xTabOk, kMapOk=true, pPrfOk=true)
|
|
|
|
proc pp*(
|
|
db: AristoDbRef;
|
|
xTabOk: bool;
|
|
kMapOk: bool;
|
|
other = false;
|
|
indent = 4;
|
|
): string =
|
|
db.ppCache(
|
|
vGenOk=other, sTabOk=xTabOk, lTabOk=xTabOk, kMapOk=kMapOk, pPrfOk=other)
|
|
|
|
proc pp*(
|
|
be: TypedBackendRef;
|
|
db: AristoDbRef;
|
|
indent = 4;
|
|
): string =
|
|
|
|
case (if be.isNil: BackendNone else: be.kind)
|
|
of BackendMemory:
|
|
be.MemBackendRef.ppBe(db, indent)
|
|
|
|
of BackendRocksDB:
|
|
be.RdbBackendRef.ppBe(db, indent)
|
|
|
|
of BackendNone:
|
|
"n/a"
|
|
|
|
# ------------------------------------------------------------------------------
|
|
# End
|
|
# ------------------------------------------------------------------------------
|