Aristo db remove over engineered object type (#2027)
* CoreDb: update test suite * Aristo: Simplify reverse key map why: The reverse key map `pAmk: (root,key) -> {vid,..}` as been simplified to `pAmk: key -> {vid,..}` as the state `root` domain argument is not used, anymore * Aristo: Remove `HashLabel` object type and replace it by `HashKey` why: The `HashLabel` object attaches a root hash to a hash key. This is nowhere used, anymore. * Fix copyright
This commit is contained in:
parent
d5a54f66ee
commit
1b4a43c140
|
@ -155,7 +155,7 @@ proc checkBE*[T: RdbBackendRef|MemBackendRef|VoidBackendRef](
|
||||||
|
|
||||||
# Check structural table
|
# Check structural table
|
||||||
for (vid,vtx) in db.layersWalkVtx:
|
for (vid,vtx) in db.layersWalkVtx:
|
||||||
let lbl = db.layersGetLabel(vid).valueOr:
|
let key = db.layersGetKey(vid).valueOr:
|
||||||
# A `kMap[]` entry must exist.
|
# A `kMap[]` entry must exist.
|
||||||
return err((vid,CheckBeCacheKeyMissing))
|
return err((vid,CheckBeCacheKeyMissing))
|
||||||
if vtx.isValid:
|
if vtx.isValid:
|
||||||
|
@ -163,7 +163,7 @@ proc checkBE*[T: RdbBackendRef|MemBackendRef|VoidBackendRef](
|
||||||
discard vids.reduce Interval[VertexID,uint64].new(vid,vid)
|
discard vids.reduce Interval[VertexID,uint64].new(vid,vid)
|
||||||
else:
|
else:
|
||||||
# Some vertex is to be deleted, the key must be empty
|
# Some vertex is to be deleted, the key must be empty
|
||||||
if lbl.isValid:
|
if key.isValid:
|
||||||
return err((vid,CheckBeCacheKeyNonEmpty))
|
return err((vid,CheckBeCacheKeyNonEmpty))
|
||||||
# There must be a representation on the backend DB unless in a TX
|
# There must be a representation on the backend DB unless in a TX
|
||||||
if db.getVtxBE(vid).isErr and db.stack.len == 0:
|
if db.getVtxBE(vid).isErr and db.stack.len == 0:
|
||||||
|
@ -186,19 +186,19 @@ proc checkBE*[T: RdbBackendRef|MemBackendRef|VoidBackendRef](
|
||||||
|
|
||||||
# Check key table
|
# Check key table
|
||||||
var list: seq[VertexID]
|
var list: seq[VertexID]
|
||||||
for (vid,lbl) in db.layersWalkLabel:
|
for (vid,key) in db.layersWalkKey:
|
||||||
list.add vid
|
list.add vid
|
||||||
let vtx = db.getVtx vid
|
let vtx = db.getVtx vid
|
||||||
if db.layersGetVtx(vid).isErr and not vtx.isValid:
|
if db.layersGetVtx(vid).isErr and not vtx.isValid:
|
||||||
return err((vid,CheckBeCacheKeyDangling))
|
return err((vid,CheckBeCacheKeyDangling))
|
||||||
if not lbl.isValid or relax:
|
if not key.isValid or relax:
|
||||||
continue
|
continue
|
||||||
if not vtx.isValid:
|
if not vtx.isValid:
|
||||||
return err((vid,CheckBeCacheVtxDangling))
|
return err((vid,CheckBeCacheVtxDangling))
|
||||||
let node = vtx.toNode(db).valueOr: # compile cache first
|
let node = vtx.toNode(db).valueOr: # compile cache first
|
||||||
return err((vid,CheckBeCacheKeyCantCompile))
|
return err((vid,CheckBeCacheKeyCantCompile))
|
||||||
let expected = node.digestTo(HashKey)
|
let expected = node.digestTo(HashKey)
|
||||||
if expected != lbl.key:
|
if expected != key:
|
||||||
return err((vid,CheckBeCacheKeyMismatch))
|
return err((vid,CheckBeCacheKeyMismatch))
|
||||||
|
|
||||||
# Check vGen
|
# Check vGen
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# nimbus-eth1
|
# nimbus-eth1
|
||||||
# Copyright (c) 2023 Status Research & Development GmbH
|
# Copyright (c) 2023-2024 Status Research & Development GmbH
|
||||||
# Licensed under either of
|
# Licensed under either of
|
||||||
# * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or
|
# * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or
|
||||||
# http://www.apache.org/licenses/LICENSE-2.0)
|
# http://www.apache.org/licenses/LICENSE-2.0)
|
||||||
|
@ -27,42 +27,42 @@ proc checkTopStrict*(
|
||||||
# vertex ID (i.e. not deleted).
|
# vertex ID (i.e. not deleted).
|
||||||
var zeroKeys: HashSet[VertexID]
|
var zeroKeys: HashSet[VertexID]
|
||||||
for (vid,vtx) in db.layersWalkVtx:
|
for (vid,vtx) in db.layersWalkVtx:
|
||||||
let lbl = db.layersGetLabelOrVoid vid
|
let key = db.layersGetKeyOrVoid vid
|
||||||
|
|
||||||
if not vtx.isValid:
|
if not vtx.isValid:
|
||||||
if lbl.isValid:
|
if key.isValid:
|
||||||
return err((vid,CheckStkVtxKeyMismatch))
|
return err((vid,CheckStkVtxKeyMismatch))
|
||||||
else: # Empty key flags key is for update
|
else: # Empty key flags key is for update
|
||||||
zeroKeys.incl vid
|
zeroKeys.incl vid
|
||||||
|
|
||||||
elif lbl.isValid:
|
elif key.isValid:
|
||||||
# So `vtx` and `lbl` exist
|
# So `vtx` and `key` exist
|
||||||
let node = vtx.toNode(db).valueOr:
|
let node = vtx.toNode(db).valueOr:
|
||||||
return err((vid,CheckStkVtxIncomplete))
|
return err((vid,CheckStkVtxIncomplete))
|
||||||
if lbl.key != node.digestTo(HashKey):
|
if key != node.digestTo(HashKey):
|
||||||
return err((vid,CheckStkVtxKeyMismatch))
|
return err((vid,CheckStkVtxKeyMismatch))
|
||||||
|
|
||||||
let revVids = db.layersGetLebalOrVoid lbl
|
let revVids = db.layersGetYekOrVoid key
|
||||||
if not revVids.isValid:
|
if not revVids.isValid:
|
||||||
return err((vid,CheckStkRevKeyMissing))
|
return err((vid,CheckStkRevKeyMissing))
|
||||||
if vid notin revVids:
|
if vid notin revVids:
|
||||||
return err((vid,CheckStkRevKeyMismatch))
|
return err((vid,CheckStkRevKeyMismatch))
|
||||||
|
|
||||||
elif not db.dirty or db.layersGetLabel(vid).isErr:
|
elif not db.dirty or db.layersGetKey(vid).isErr:
|
||||||
# So `vtx` exists but not `lbl`, so cache is supposed dirty and the
|
# So `vtx` exists but not `key`, so cache is supposed dirty and the
|
||||||
# vertex has a zero entry.
|
# vertex has a zero entry.
|
||||||
return err((vid,CheckStkVtxKeyMissing))
|
return err((vid,CheckStkVtxKeyMissing))
|
||||||
|
|
||||||
else: # Empty key flags key is for update
|
else: # Empty key flags key is for update
|
||||||
zeroKeys.incl vid
|
zeroKeys.incl vid
|
||||||
|
|
||||||
for (vid,key) in db.layersWalkLabel:
|
for (vid,key) in db.layersWalkKey:
|
||||||
if not key.isValid and vid notin zeroKeys:
|
if not key.isValid and vid notin zeroKeys:
|
||||||
if not db.getVtx(vid).isValid:
|
if not db.getVtx(vid).isValid:
|
||||||
return err((vid,CheckStkKeyStrayZeroEntry))
|
return err((vid,CheckStkKeyStrayZeroEntry))
|
||||||
|
|
||||||
let
|
let
|
||||||
pAmkVtxCount = db.layersWalkLebal.toSeq.mapIt(it[1]).foldl(a + b.len, 0)
|
pAmkVtxCount = db.layersWalkYek.toSeq.mapIt(it[1]).foldl(a + b.len, 0)
|
||||||
sTabVtxCount = db.layersWalkVtx.toSeq.mapIt(it[1]).filterIt(it.isValid).len
|
sTabVtxCount = db.layersWalkVtx.toSeq.mapIt(it[1]).filterIt(it.isValid).len
|
||||||
|
|
||||||
# Non-zero values mist sum up the same
|
# Non-zero values mist sum up the same
|
||||||
|
@ -73,7 +73,7 @@ proc checkTopStrict*(
|
||||||
|
|
||||||
|
|
||||||
proc checkTopProofMode*(
|
proc checkTopProofMode*(
|
||||||
db: AristoDbRef; # Database, top layer
|
db: AristoDbRef; # Database, top layer
|
||||||
): Result[void,(VertexID,AristoError)] =
|
): Result[void,(VertexID,AristoError)] =
|
||||||
if 0 < db.pPrf.len:
|
if 0 < db.pPrf.len:
|
||||||
for vid in db.pPrf:
|
for vid in db.pPrf:
|
||||||
|
@ -82,28 +82,28 @@ proc checkTopProofMode*(
|
||||||
let node = vtx.toNode(db).valueOr:
|
let node = vtx.toNode(db).valueOr:
|
||||||
return err((vid,CheckRlxVtxIncomplete))
|
return err((vid,CheckRlxVtxIncomplete))
|
||||||
|
|
||||||
let lbl = db.layersGetlabelOrVoid vid
|
let key = db.layersGetKeyOrVoid vid
|
||||||
if not lbl.isValid:
|
if not key.isValid:
|
||||||
return err((vid,CheckRlxVtxKeyMissing))
|
return err((vid,CheckRlxVtxKeyMissing))
|
||||||
if lbl.key != node.digestTo(HashKey):
|
if key != node.digestTo(HashKey):
|
||||||
return err((vid,CheckRlxVtxKeyMismatch))
|
return err((vid,CheckRlxVtxKeyMismatch))
|
||||||
|
|
||||||
let revVids = db.layersGetLebalOrVoid lbl
|
let revVids = db.layersGetYekOrVoid key
|
||||||
if not revVids.isValid:
|
if not revVids.isValid:
|
||||||
return err((vid,CheckRlxRevKeyMissing))
|
return err((vid,CheckRlxRevKeyMissing))
|
||||||
if vid notin revVids:
|
if vid notin revVids:
|
||||||
return err((vid,CheckRlxRevKeyMismatch))
|
return err((vid,CheckRlxRevKeyMismatch))
|
||||||
else:
|
else:
|
||||||
for (vid,lbl) in db.layersWalkLabel:
|
for (vid,key) in db.layersWalkKey:
|
||||||
if lbl.isValid: # Otherwise to be deleted
|
if key.isValid: # Otherwise to be deleted
|
||||||
let vtx = db.getVtx vid
|
let vtx = db.getVtx vid
|
||||||
if vtx.isValid:
|
if vtx.isValid:
|
||||||
let node = vtx.toNode(db).valueOr:
|
let node = vtx.toNode(db).valueOr:
|
||||||
continue
|
continue
|
||||||
if lbl.key != node.digestTo(HashKey):
|
if key != node.digestTo(HashKey):
|
||||||
return err((vid,CheckRlxVtxKeyMismatch))
|
return err((vid,CheckRlxVtxKeyMismatch))
|
||||||
|
|
||||||
let revVids = db.layersGetLebalOrVoid lbl
|
let revVids = db.layersGetYekOrVoid key
|
||||||
if not revVids.isValid:
|
if not revVids.isValid:
|
||||||
return err((vid,CheckRlxRevKeyMissing))
|
return err((vid,CheckRlxRevKeyMissing))
|
||||||
if vid notin revVids:
|
if vid notin revVids:
|
||||||
|
@ -115,8 +115,8 @@ proc checkTopCommon*(
|
||||||
): Result[void,(VertexID,AristoError)] =
|
): Result[void,(VertexID,AristoError)] =
|
||||||
# Some `kMap[]` entries may ne void indicating backend deletion
|
# Some `kMap[]` entries may ne void indicating backend deletion
|
||||||
let
|
let
|
||||||
kMapCount = db.layersWalkLabel.toSeq.mapIt(it[1]).filterIt(it.isValid).len
|
kMapCount = db.layersWalkKey.toSeq.mapIt(it[1]).filterIt(it.isValid).len
|
||||||
kMapNilCount = db.layersWalkLabel.toSeq.len - kMapCount
|
kMapNilCount = db.layersWalkKey.toSeq.len - kMapCount
|
||||||
|
|
||||||
# Collect leafs and check deleted entries
|
# Collect leafs and check deleted entries
|
||||||
var nNilVtx = 0
|
var nNilVtx = 0
|
||||||
|
@ -139,7 +139,7 @@ proc checkTopCommon*(
|
||||||
return err((vid,CheckAnyVtxExtPfxMissing))
|
return err((vid,CheckAnyVtxExtPfxMissing))
|
||||||
else:
|
else:
|
||||||
nNilVtx.inc
|
nNilVtx.inc
|
||||||
let rc = db.layersGetLabel vid
|
let rc = db.layersGetKey vid
|
||||||
if rc.isErr:
|
if rc.isErr:
|
||||||
return err((vid,CheckAnyVtxEmptyKeyMissing))
|
return err((vid,CheckAnyVtxEmptyKeyMissing))
|
||||||
if rc.value.isValid:
|
if rc.value.isValid:
|
||||||
|
@ -150,12 +150,12 @@ proc checkTopCommon*(
|
||||||
if kMapNilCount != 0 and kMapNilCount < nNilVtx:
|
if kMapNilCount != 0 and kMapNilCount < nNilVtx:
|
||||||
return err((VertexID(0),CheckAnyVtxEmptyKeyMismatch))
|
return err((VertexID(0),CheckAnyVtxEmptyKeyMismatch))
|
||||||
|
|
||||||
let pAmkVtxCount = db.layersWalkLebal.toSeq.mapIt(it[1]).foldl(a + b.len, 0)
|
let pAmkVtxCount = db.layersWalkYek.toSeq.mapIt(it[1]).foldl(a + b.len, 0)
|
||||||
if pAmkVtxCount != kMapCount:
|
if pAmkVtxCount != kMapCount:
|
||||||
var knownKeys: HashSet[VertexID]
|
var knownKeys: HashSet[VertexID]
|
||||||
for (key,vids) in db.layersWalkLebal:
|
for (key,vids) in db.layersWalkYek:
|
||||||
for vid in vids:
|
for vid in vids:
|
||||||
if db.layersGetLabel(vid).isErr:
|
if db.layersGetKey(vid).isErr:
|
||||||
return err((vid,CheckAnyRevVtxMissing))
|
return err((vid,CheckAnyRevVtxMissing))
|
||||||
if vid in knownKeys:
|
if vid in knownKeys:
|
||||||
return err((vid,CheckAnyRevVtxDup))
|
return err((vid,CheckAnyRevVtxDup))
|
||||||
|
@ -163,7 +163,7 @@ proc checkTopCommon*(
|
||||||
return err((VertexID(0),CheckAnyRevCountMismatch)) # should not apply(!)
|
return err((VertexID(0),CheckAnyRevCountMismatch)) # should not apply(!)
|
||||||
|
|
||||||
for vid in db.pPrf:
|
for vid in db.pPrf:
|
||||||
if db.layersGetLabel(vid).isErr:
|
if db.layersGetKey(vid).isErr:
|
||||||
return err((vid,CheckAnyVtxLockWithoutKey))
|
return err((vid,CheckAnyVtxLockWithoutKey))
|
||||||
ok()
|
ok()
|
||||||
|
|
||||||
|
|
|
@ -34,9 +34,6 @@ const
|
||||||
VOID_HASH_KEY* = HashKey()
|
VOID_HASH_KEY* = HashKey()
|
||||||
## Void equivalent for Merkle hash value
|
## Void equivalent for Merkle hash value
|
||||||
|
|
||||||
VOID_HASH_LABEL* = HashLabel(key: VOID_HASH_KEY)
|
|
||||||
## Void equivalent for Merkle hash value
|
|
||||||
|
|
||||||
VOID_PATH_ID* = PathID()
|
VOID_PATH_ID* = PathID()
|
||||||
## Void equivalent for Merkle hash value
|
## Void equivalent for Merkle hash value
|
||||||
|
|
||||||
|
|
|
@ -27,30 +27,24 @@ import
|
||||||
proc orDefault(db: AristoDbRef): AristoDbRef =
|
proc orDefault(db: AristoDbRef): AristoDbRef =
|
||||||
if db.isNil: AristoDbRef(top: LayerRef.init()) else: db
|
if db.isNil: AristoDbRef(top: LayerRef.init()) else: db
|
||||||
|
|
||||||
proc del(xMap: var VidsByLabelTab; lbl: HashLabel; vid: VertexID) =
|
proc del(xMap: var VidsByKeyTab; key: HashKey; vid: VertexID) =
|
||||||
# Update `xMap`
|
# Update `xMap`
|
||||||
var vidsLen = -1
|
var vidsLen = -1
|
||||||
xMap.withValue(lbl,value):
|
xMap.withValue(key,value):
|
||||||
value[].excl vid
|
value[].excl vid
|
||||||
vidsLen = value[].len
|
vidsLen = value[].len
|
||||||
if vidsLen == 0:
|
if vidsLen == 0:
|
||||||
xMap.del lbl
|
xMap.del key
|
||||||
|
|
||||||
proc del(xMap: var VidsByLabelTab; lbl: HashLabel; vids: HashSet[VertexID]) =
|
proc del(xMap: var VidsByKeyTab; key: HashKey; vids: HashSet[VertexID]) =
|
||||||
for vid in vids:
|
for vid in vids:
|
||||||
xMap.del(lbl, vid)
|
xMap.del(key, vid)
|
||||||
|
|
||||||
proc add(xMap: var VidsByLabelTab; lbl: HashLabel; vid: VertexID) =
|
proc add(xMap: var VidsByKeyTab; key: Hashkey; vid: VertexID) =
|
||||||
xMap.withValue(lbl,value):
|
xMap.withValue(key,value):
|
||||||
value[].incl vid
|
value[].incl vid
|
||||||
do: # else if not found
|
do: # else if not found
|
||||||
xMap[lbl] = @[vid].toHashSet
|
xMap[key] = @[vid].toHashSet
|
||||||
|
|
||||||
func cmp(a, b: HashLabel): int =
|
|
||||||
if a.root != b.root:
|
|
||||||
a.root.cmp b.root
|
|
||||||
else:
|
|
||||||
a.key.cmp b.key
|
|
||||||
|
|
||||||
# --------------------------
|
# --------------------------
|
||||||
|
|
||||||
|
@ -63,22 +57,13 @@ proc toHexLsb(w: int8): string =
|
||||||
proc sortedKeys(lTab: Table[LeafTie,VertexID]): seq[LeafTie] =
|
proc sortedKeys(lTab: Table[LeafTie,VertexID]): seq[LeafTie] =
|
||||||
lTab.keys.toSeq.sorted(cmp = proc(a,b: LeafTie): int = cmp(a,b))
|
lTab.keys.toSeq.sorted(cmp = proc(a,b: LeafTie): int = cmp(a,b))
|
||||||
|
|
||||||
proc sortedKeys(kMap: Table[VertexID,HashLabel]): seq[VertexID] =
|
proc sortedKeys[T](tab: Table[VertexID,T]): seq[VertexID] =
|
||||||
kMap.keys.toSeq.mapIt(it.uint64).sorted.mapIt(it.VertexID)
|
tab.keys.toSeq.mapIt(it.uint64).sorted.mapIt(it.VertexID)
|
||||||
|
|
||||||
proc sortedKeys(kMap: Table[VertexID,HashKey]): 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] =
|
proc sortedKeys(pPrf: HashSet[VertexID]): seq[VertexID] =
|
||||||
pPrf.toSeq.mapIt(it.uint64).sorted.mapIt(it.VertexID)
|
pPrf.toSeq.mapIt(it.uint64).sorted.mapIt(it.VertexID)
|
||||||
|
|
||||||
proc sortedKeys(pAmk: Table[HashLabel,VertexID]): seq[HashLabel] =
|
proc sortedKeys[T](pAmk: Table[HashKey,T]): seq[HashKey] =
|
||||||
pAmk.keys.toSeq.sorted cmp
|
|
||||||
|
|
||||||
proc sortedKeys(pAmk: VidsByLabelTab): seq[HashLabel] =
|
|
||||||
pAmk.keys.toSeq.sorted cmp
|
pAmk.keys.toSeq.sorted cmp
|
||||||
|
|
||||||
|
|
||||||
|
@ -118,42 +103,40 @@ proc stripZeros(a: string; toExp = false): string =
|
||||||
elif 2 < n:
|
elif 2 < n:
|
||||||
result &= "↑" & $n
|
result &= "↑" & $n
|
||||||
|
|
||||||
proc vidCode(lbl: HashLabel, db: AristoDbRef): uint64 =
|
proc vidCode(key: HashKey, db: AristoDbRef): uint64 =
|
||||||
if lbl.isValid:
|
if key.isValid:
|
||||||
block:
|
block:
|
||||||
let vids = db.layersGetLebalOrVoid lbl
|
let vids = db.layersGetYekOrVoid key
|
||||||
if vids.isValid:
|
if vids.isValid:
|
||||||
db.xMap.del(lbl, vids)
|
db.xMap.del(key, vids)
|
||||||
return vids.sortedKeys[0].uint64
|
return vids.sortedKeys[0].uint64
|
||||||
block:
|
block:
|
||||||
let vids = db.xMap.getOrVoid lbl
|
let vids = db.xMap.getOrVoid key
|
||||||
if vids.isValid:
|
if vids.isValid:
|
||||||
return vids.sortedKeys[0].uint64
|
return vids.sortedKeys[0].uint64
|
||||||
|
|
||||||
# ---------------------
|
# ---------------------
|
||||||
|
|
||||||
proc ppLabelOk(
|
proc ppKeyOk(
|
||||||
db: AristoDbRef;
|
db: AristoDbRef;
|
||||||
root: VertexID;
|
|
||||||
key: HashKey;
|
key: HashKey;
|
||||||
vid: VertexID;
|
vid: VertexID;
|
||||||
): string =
|
): string =
|
||||||
if key.isValid and vid.isValid:
|
if key.isValid and vid.isValid:
|
||||||
let
|
let
|
||||||
lbl = HashLabel(root: root, key: key)
|
vids = db.layersGetYekOrVoid key
|
||||||
vids = db.layersGetLebalOrVoid lbl
|
|
||||||
if vids.isValid:
|
if vids.isValid:
|
||||||
db.xMap.del(lbl, vids)
|
db.xMap.del(key, vids)
|
||||||
if vid notin vids:
|
if vid notin vids:
|
||||||
result = "(!)"
|
result = "(!)"
|
||||||
return
|
return
|
||||||
block:
|
block:
|
||||||
let vids = db.xMap.getOrVoid lbl
|
let vids = db.xMap.getOrVoid key
|
||||||
if vids.isValid:
|
if vids.isValid:
|
||||||
if vid notin vids:
|
if vid notin vids:
|
||||||
result = "(!)"
|
result = "(!)"
|
||||||
return
|
return
|
||||||
db.xMap.add(lbl,vid)
|
db.xMap.add(key,vid)
|
||||||
|
|
||||||
proc ppVid(vid: VertexID; pfx = true): string =
|
proc ppVid(vid: VertexID; pfx = true): string =
|
||||||
if pfx:
|
if pfx:
|
||||||
|
@ -215,16 +198,15 @@ proc ppVidList(vGen: openArray[VertexID]): string =
|
||||||
#proc ppVidList(vGen: HashSet[VertexID]): string =
|
#proc ppVidList(vGen: HashSet[VertexID]): string =
|
||||||
# "{" & vGen.sortedKeys.mapIt(it.ppVid).join(",") & "}"
|
# "{" & vGen.sortedKeys.mapIt(it.ppVid).join(",") & "}"
|
||||||
|
|
||||||
proc ppKey(key: HashKey; db: AristoDbRef; root: VertexID; pfx = true): string =
|
proc ppKey(key: HashKey; db: AristoDbRef; pfx = true): string =
|
||||||
proc getVids(): tuple[vids: HashSet[VertexID], xMapTag: string] =
|
proc getVids(): tuple[vids: HashSet[VertexID], xMapTag: string] =
|
||||||
let lbl = HashLabel(root: root, key: key)
|
|
||||||
block:
|
block:
|
||||||
let vids = db.layersGetLebalOrVoid lbl
|
let vids = db.layersGetYekOrVoid key
|
||||||
if vids.isValid:
|
if vids.isValid:
|
||||||
db.xMap.del(lbl, vids)
|
db.xMap.del(key, vids)
|
||||||
return (vids, "")
|
return (vids, "")
|
||||||
block:
|
block:
|
||||||
let vids = db.xMap.getOrVoid lbl
|
let vids = db.xMap.getOrVoid key
|
||||||
if vids.isValid:
|
if vids.isValid:
|
||||||
return (vids, "+")
|
return (vids, "+")
|
||||||
if pfx:
|
if pfx:
|
||||||
|
@ -247,13 +229,6 @@ proc ppKey(key: HashKey; db: AristoDbRef; root: VertexID; pfx = true): string =
|
||||||
return
|
return
|
||||||
result &= @key.toHex.squeeze(hex=true,ignLen=true) & tag
|
result &= @key.toHex.squeeze(hex=true,ignLen=true) & tag
|
||||||
|
|
||||||
proc ppLabel(lbl: HashLabel; db: AristoDbRef): string =
|
|
||||||
if lbl.isValid:
|
|
||||||
"%" & ($lbl.root.toHex).stripZeros &
|
|
||||||
":" & lbl.key.ppKey(db, lbl.root, pfx=false)
|
|
||||||
else:
|
|
||||||
"%ø"
|
|
||||||
|
|
||||||
proc ppLeafTie(lty: LeafTie, db: AristoDbRef): string =
|
proc ppLeafTie(lty: LeafTie, db: AristoDbRef): string =
|
||||||
let pfx = lty.path.to(NibblesSeq)
|
let pfx = lty.path.to(NibblesSeq)
|
||||||
"@" & lty.root.ppVid(pfx=false) & ":" &
|
"@" & lty.root.ppVid(pfx=false) & ":" &
|
||||||
|
@ -288,7 +263,7 @@ proc ppVtx(nd: VertexRef, db: AristoDbRef, vid: VertexID): string =
|
||||||
else:
|
else:
|
||||||
if not vid.isValid or vid in db.pPrf:
|
if not vid.isValid or vid in db.pPrf:
|
||||||
result = ["L(", "X(", "B("][nd.vType.ord]
|
result = ["L(", "X(", "B("][nd.vType.ord]
|
||||||
elif db.layersGetLabel(vid).isOk:
|
elif db.layersGetKey(vid).isOk:
|
||||||
result = ["l(", "x(", "b("][nd.vType.ord]
|
result = ["l(", "x(", "b("][nd.vType.ord]
|
||||||
else:
|
else:
|
||||||
result = ["ł(", "€(", "þ("][nd.vType.ord]
|
result = ["ł(", "€(", "þ("][nd.vType.ord]
|
||||||
|
@ -330,8 +305,8 @@ proc ppPPrf(pPrf: HashSet[VertexID]): string =
|
||||||
|
|
||||||
proc ppXMap*(
|
proc ppXMap*(
|
||||||
db: AristoDbRef;
|
db: AristoDbRef;
|
||||||
kMap: Table[VertexID,HashLabel];
|
kMap: Table[VertexID,HashKey];
|
||||||
pAmk: VidsByLabelTab;
|
pAmk: VidsByKeyTab;
|
||||||
indent: int;
|
indent: int;
|
||||||
): string =
|
): string =
|
||||||
|
|
||||||
|
@ -351,24 +326,24 @@ proc ppXMap*(
|
||||||
if 1 < w.len:
|
if 1 < w.len:
|
||||||
multi = multi + w
|
multi = multi + w
|
||||||
|
|
||||||
# Vertex IDs without forward mapping `kMap: VertexID -> HashLabel`
|
# Vertex IDs without forward mapping `kMap: VertexID -> HashKey`
|
||||||
var revOnly: Table[VertexID,HashLabel]
|
var revOnly: Table[VertexID,HashKey]
|
||||||
for (lbl,vids) in pAmk.pairs:
|
for (key,vids) in pAmk.pairs:
|
||||||
for vid in vids:
|
for vid in vids:
|
||||||
if not kMap.hasKey vid:
|
if not kMap.hasKey vid:
|
||||||
revOnly[vid] = lbl
|
revOnly[vid] = key
|
||||||
let revKeys =
|
let revKeys =
|
||||||
revOnly.keys.toSeq.mapIt(it.uint64).sorted.mapIt(it.VertexID)
|
revOnly.keys.toSeq.mapIt(it.uint64).sorted.mapIt(it.VertexID)
|
||||||
|
|
||||||
proc ppNtry(n: uint64): string =
|
proc ppNtry(n: uint64): string =
|
||||||
var s = VertexID(n).ppVid
|
var s = VertexID(n).ppVid
|
||||||
let lbl = kMap.getOrVoid VertexID(n)
|
let key = kMap.getOrVoid VertexID(n)
|
||||||
if lbl.isValid:
|
if key.isValid:
|
||||||
let vids = pAmk.getOrVoid lbl
|
let vids = pAmk.getOrVoid key
|
||||||
if VertexID(n) notin vids or 1 < vids.len:
|
if VertexID(n) notin vids or 1 < vids.len:
|
||||||
s = "(" & s & "," & lbl.key.ppKey(db,lbl.root)
|
s = "(" & s & "," & key.ppKey(db)
|
||||||
elif lbl.key.len < 32:
|
elif key.len < 32:
|
||||||
s &= "[#" & $lbl.key.len & "]"
|
s &= "[#" & $key.len & "]"
|
||||||
else:
|
else:
|
||||||
s &= "£ø"
|
s &= "£ø"
|
||||||
if s[0] == '(':
|
if s[0] == '(':
|
||||||
|
@ -378,10 +353,10 @@ proc ppXMap*(
|
||||||
result = "{"
|
result = "{"
|
||||||
# Extra reverse lookups
|
# Extra reverse lookups
|
||||||
if 0 < revKeys.len:
|
if 0 < revKeys.len:
|
||||||
proc ppRevlabel(vid: VertexID): string =
|
proc ppRevKey(vid: VertexID): string =
|
||||||
"(ø," & revOnly.getOrVoid(vid).ppLabel(db) & ")"
|
"(ø," & revOnly.getOrVoid(vid).ppkey(db) & ")"
|
||||||
var (i, r) = (0, revKeys[0])
|
var (i, r) = (0, revKeys[0])
|
||||||
result &= revKeys[0].ppRevlabel
|
result &= revKeys[0].ppRevKey
|
||||||
for n in 1 ..< revKeys.len:
|
for n in 1 ..< revKeys.len:
|
||||||
let vid = revKeys[n]
|
let vid = revKeys[n]
|
||||||
r.inc
|
r.inc
|
||||||
|
@ -391,24 +366,24 @@ proc ppXMap*(
|
||||||
result &= pfx
|
result &= pfx
|
||||||
else:
|
else:
|
||||||
result &= ".. "
|
result &= ".. "
|
||||||
result &= revKeys[n-1].ppRevlabel
|
result &= revKeys[n-1].ppRevKey
|
||||||
result &= pfx & vid.ppRevlabel
|
result &= pfx & vid.ppRevKey
|
||||||
(i, r) = (n, vid)
|
(i, r) = (n, vid)
|
||||||
if i < revKeys.len - 1:
|
if i < revKeys.len - 1:
|
||||||
if i+1 != revKeys.len - 1:
|
if i+1 != revKeys.len - 1:
|
||||||
result &= ".. "
|
result &= ".. "
|
||||||
else:
|
else:
|
||||||
result &= pfx
|
result &= pfx
|
||||||
result &= revKeys[^1].ppRevlabel
|
result &= revKeys[^1].ppRevKey
|
||||||
|
|
||||||
# Forward lookups
|
# Forward lookups
|
||||||
var cache: seq[(uint64,uint64,bool)]
|
var cache: seq[(uint64,uint64,bool)]
|
||||||
for vid in kMap.sortedKeys:
|
for vid in kMap.sortedKeys:
|
||||||
let lbl = kMap.getOrVoid vid
|
let key = kMap.getOrVoid vid
|
||||||
if lbl.isValid:
|
if key.isValid:
|
||||||
cache.add (vid.uint64, lbl.vidCode(db), vid in multi)
|
cache.add (vid.uint64, key.vidCode(db), vid in multi)
|
||||||
let vids = pAmk.getOrVoid lbl
|
let vids = pAmk.getOrVoid key
|
||||||
if (0 < vids.len and vid notin vids) or lbl.key.len < 32:
|
if (0 < vids.len and vid notin vids) or key.len < 32:
|
||||||
cache[^1][2] = true
|
cache[^1][2] = true
|
||||||
else:
|
else:
|
||||||
cache.add (vid.uint64, 0u64, true)
|
cache.add (vid.uint64, 0u64, true)
|
||||||
|
@ -445,7 +420,6 @@ proc ppXMap*(
|
||||||
proc ppFilter(
|
proc ppFilter(
|
||||||
fl: FilterRef;
|
fl: FilterRef;
|
||||||
db: AristoDbRef;
|
db: AristoDbRef;
|
||||||
root: VertexID;
|
|
||||||
indent: int;
|
indent: int;
|
||||||
): string =
|
): string =
|
||||||
## Walk over filter tables
|
## Walk over filter tables
|
||||||
|
@ -458,8 +432,8 @@ proc ppFilter(
|
||||||
result &= " n/a"
|
result &= " n/a"
|
||||||
return
|
return
|
||||||
result &= pfx & "fid=" & fl.fid.ppFid
|
result &= pfx & "fid=" & fl.fid.ppFid
|
||||||
result &= pfx & "src=" & fl.src.to(HashKey).ppKey(db,root)
|
result &= pfx & "src=" & fl.src.to(HashKey).ppKey(db)
|
||||||
result &= pfx & "trg=" & fl.trg.to(HashKey).ppKey(db,root)
|
result &= pfx & "trg=" & fl.trg.to(HashKey).ppKey(db)
|
||||||
result &= pfx & "vGen" & pfx1 & "[" &
|
result &= pfx & "vGen" & pfx1 & "[" &
|
||||||
fl.vGen.mapIt(it.ppVid).join(",") & "]"
|
fl.vGen.mapIt(it.ppVid).join(",") & "]"
|
||||||
result &= pfx & "sTab" & pfx1 & "{"
|
result &= pfx & "sTab" & pfx1 & "{"
|
||||||
|
@ -471,10 +445,10 @@ proc ppFilter(
|
||||||
for n,vid in fl.kMap.sortedKeys:
|
for n,vid in fl.kMap.sortedKeys:
|
||||||
let key = fl.kMap.getOrVoid vid
|
let key = fl.kMap.getOrVoid vid
|
||||||
if 0 < n: result &= pfx2
|
if 0 < n: result &= pfx2
|
||||||
result &= $(1+n) & "(" & vid.ppVid & "," & key.ppKey(db,root) & ")"
|
result &= $(1+n) & "(" & vid.ppVid & "," & key.ppKey(db) & ")"
|
||||||
result &= "}"
|
result &= "}"
|
||||||
|
|
||||||
proc ppBe[T](be: T; db: AristoDbRef; root: VertexID; indent: int): string =
|
proc ppBe[T](be: T; db: AristoDbRef; indent: int): string =
|
||||||
## Walk over backend tables
|
## Walk over backend tables
|
||||||
let
|
let
|
||||||
pfx = indent.toPfx
|
pfx = indent.toPfx
|
||||||
|
@ -497,7 +471,7 @@ proc ppBe[T](be: T; db: AristoDbRef; root: VertexID; indent: int): string =
|
||||||
for (vid,key) in be.walkKey:
|
for (vid,key) in be.walkKey:
|
||||||
if 0 < n: result &= pfx2
|
if 0 < n: result &= pfx2
|
||||||
n.inc
|
n.inc
|
||||||
result &= $n & "(" & vid.ppVid & "," & key.ppKey(db,root) & ")"
|
result &= $n & "(" & vid.ppVid & "," & key.ppKey(db) & ")"
|
||||||
result &= "}"
|
result &= "}"
|
||||||
|
|
||||||
proc ppLayer(
|
proc ppLayer(
|
||||||
|
@ -577,13 +551,10 @@ proc pp*(w: Hash256): string =
|
||||||
w.data.toHex.squeeze(hex=true,ignLen=true)
|
w.data.toHex.squeeze(hex=true,ignLen=true)
|
||||||
|
|
||||||
proc pp*(w: HashKey; sig: MerkleSignRef): string =
|
proc pp*(w: HashKey; sig: MerkleSignRef): string =
|
||||||
w.ppKey(sig.db, sig.root)
|
w.ppKey(sig.db)
|
||||||
|
|
||||||
proc pp*(w: HashKey; db = AristoDbRef(nil); root = VertexID(1)): string =
|
proc pp*(w: HashKey; db = AristoDbRef(nil)): string =
|
||||||
w.ppKey(db.orDefault, root)
|
w.ppKey(db.orDefault)
|
||||||
|
|
||||||
proc pp*(lbl: HashLabel, db = AristoDbRef(nil)): string =
|
|
||||||
lbl.ppLabel(db.orDefault)
|
|
||||||
|
|
||||||
proc pp*(lty: LeafTie, db = AristoDbRef(nil)): string =
|
proc pp*(lty: LeafTie, db = AristoDbRef(nil)): string =
|
||||||
lty.ppLeafTie(db.orDefault)
|
lty.ppLeafTie(db.orDefault)
|
||||||
|
@ -615,7 +586,7 @@ proc pp*(p: PayloadRef, db = AristoDbRef(nil)): string =
|
||||||
proc pp*(nd: VertexRef, db = AristoDbRef(nil)): string =
|
proc pp*(nd: VertexRef, db = AristoDbRef(nil)): string =
|
||||||
nd.ppVtx(db.orDefault, VertexID(0))
|
nd.ppVtx(db.orDefault, VertexID(0))
|
||||||
|
|
||||||
proc pp*(nd: NodeRef; root: VertexID; db: AristoDbRef): string =
|
proc pp*(nd: NodeRef; db: AristoDbRef): string =
|
||||||
if not nd.isValid:
|
if not nd.isValid:
|
||||||
result = "n/a"
|
result = "n/a"
|
||||||
elif nd.error != AristoError(0):
|
elif nd.error != AristoError(0):
|
||||||
|
@ -628,21 +599,21 @@ proc pp*(nd: NodeRef; root: VertexID; db: AristoDbRef): string =
|
||||||
|
|
||||||
of Extension:
|
of Extension:
|
||||||
result &= $nd.ePfx.ppPathPfx & "," & nd.eVid.ppVid & ","
|
result &= $nd.ePfx.ppPathPfx & "," & nd.eVid.ppVid & ","
|
||||||
result &= nd.key[0].ppKey(db,root)
|
result &= nd.key[0].ppKey(db)
|
||||||
result &= db.ppLabelOk(root, nd.key[0], nd.eVid)
|
result &= db.ppKeyOk(nd.key[0], nd.eVid)
|
||||||
|
|
||||||
of Branch:
|
of Branch:
|
||||||
result &= "["
|
result &= "["
|
||||||
for n in 0..15:
|
for n in 0..15:
|
||||||
if nd.bVid[n].isValid or nd.key[n].isValid:
|
if nd.bVid[n].isValid or nd.key[n].isValid:
|
||||||
result &= nd.bVid[n].ppVid
|
result &= nd.bVid[n].ppVid
|
||||||
result &= db.ppLabelOk(root, nd.key[n], nd.bVid[n]) & ","
|
result &= db.ppKeyOk(nd.key[n], nd.bVid[n]) & ","
|
||||||
result[^1] = ']'
|
result[^1] = ']'
|
||||||
|
|
||||||
result &= ",["
|
result &= ",["
|
||||||
for n in 0..15:
|
for n in 0..15:
|
||||||
if nd.bVid[n].isValid or nd.key[n].isValid:
|
if nd.bVid[n].isValid or nd.key[n].isValid:
|
||||||
result &= nd.key[n].ppKey(db,root)
|
result &= nd.key[n].ppKey(db)
|
||||||
result &= ","
|
result &= ","
|
||||||
result[^1] = ']'
|
result[^1] = ']'
|
||||||
result &= ")"
|
result &= ")"
|
||||||
|
@ -680,11 +651,11 @@ proc pp*(leg: Leg; db = AristoDbRef(nil)): string =
|
||||||
let db = db.orDefault()
|
let db = db.orDefault()
|
||||||
result = "(" & leg.wp.vid.ppVid & ","
|
result = "(" & leg.wp.vid.ppVid & ","
|
||||||
block:
|
block:
|
||||||
let lbl = db.layersGetLabelOrVoid leg.wp.vid
|
let key = db.layersGetKeyOrVoid leg.wp.vid
|
||||||
if not lbl.isValid:
|
if not key.isValid:
|
||||||
result &= "ø"
|
result &= "ø"
|
||||||
elif leg.wp.vid notin db.layersGetLebalOrVoid lbl:
|
elif leg.wp.vid notin db.layersGetYekOrVoid key:
|
||||||
result &= lbl.ppLabel(db)
|
result &= key.ppKey(db)
|
||||||
result &= ","
|
result &= ","
|
||||||
if 0 <= leg.nibble:
|
if 0 <= leg.nibble:
|
||||||
result &= $leg.nibble.ppNibble
|
result &= $leg.nibble.ppNibble
|
||||||
|
@ -704,32 +675,32 @@ proc pp*(hike: Hike; db = AristoDbRef(nil); indent = 4): string =
|
||||||
result &= pfx & "(" & hike.tail.ppPathPfx & ")"
|
result &= pfx & "(" & hike.tail.ppPathPfx & ")"
|
||||||
result &= "]"
|
result &= "]"
|
||||||
|
|
||||||
proc pp*(kMap: Table[VertexID,Hashlabel]; indent = 4): string =
|
proc pp*(kMap: Table[VertexID,HashKey]; indent = 4): string =
|
||||||
let db = AristoDbRef(nil).orDefault
|
let db = AristoDbRef(nil).orDefault
|
||||||
"{" & kMap.sortedKeys
|
"{" & kMap.sortedKeys
|
||||||
.mapIt((it, kMap.getOrVoid it))
|
.mapIt((it, kMap.getOrVoid it))
|
||||||
.mapIt("(" & it[0].ppVid & "," & it[1].ppLabel(db) & ")")
|
.mapIt("(" & it[0].ppVid & "," & it[1].ppKey(db) & ")")
|
||||||
.join("," & indent.toPfx(1)) & "}"
|
.join("," & indent.toPfx(1)) & "}"
|
||||||
|
|
||||||
proc pp*(kMap: Table[VertexID,Hashlabel]; db: AristoDbRef; indent = 4): string =
|
proc pp*(kMap: Table[VertexID,HashKey]; db: AristoDbRef; indent = 4): string =
|
||||||
db.ppXMap(kMap, db.layersCc.delta.pAmk, indent)
|
db.ppXMap(kMap, db.layersCc.delta.pAmk, indent)
|
||||||
|
|
||||||
proc pp*(
|
proc pp*(
|
||||||
pAmk: Table[HashLabel,VertexID];
|
pAmk: Table[HashKey,VertexID];
|
||||||
db = AristoDbRef(nil);
|
db = AristoDbRef(nil);
|
||||||
indent = 4;
|
indent = 4;
|
||||||
): string =
|
): string =
|
||||||
let db = db.orDefault
|
let db = db.orDefault
|
||||||
"{" & pAmk.sortedkeys
|
"{" & pAmk.sortedkeys
|
||||||
.mapIt((it, pAmk.getOrVoid it))
|
.mapIt((it, pAmk.getOrVoid it))
|
||||||
.mapIt("(" & it[0].ppLabel(db) & "," & it[1].ppVid & ")")
|
.mapIt("(" & it[0].ppKey(db) & "," & it[1].ppVid & ")")
|
||||||
.join("," & indent.toPfx(1)) & "}"
|
.join("," & indent.toPfx(1)) & "}"
|
||||||
|
|
||||||
proc pp*(pAmk: VidsByLabelTab; db = AristoDbRef(nil); indent = 4): string =
|
proc pp*(pAmk: VidsByKeyTab; db = AristoDbRef(nil); indent = 4): string =
|
||||||
let db = db.orDefault
|
let db = db.orDefault
|
||||||
"{" & pAmk.sortedkeys
|
"{" & pAmk.sortedkeys
|
||||||
.mapIt((it, pAmk.getOrVoid it))
|
.mapIt((it, pAmk.getOrVoid it))
|
||||||
.mapIt("(" & it[0].ppLabel(db) & "," & it[1].ppVids & ")")
|
.mapIt("(" & it[0].ppKey(db) & "," & it[1].ppVids & ")")
|
||||||
.join("," & indent.toPfx(1)) & "}"
|
.join("," & indent.toPfx(1)) & "}"
|
||||||
|
|
||||||
# ---------------------
|
# ---------------------
|
||||||
|
@ -792,29 +763,26 @@ proc pp*(
|
||||||
proc pp*(
|
proc pp*(
|
||||||
filter: FilterRef;
|
filter: FilterRef;
|
||||||
db = AristoDbRef(nil);
|
db = AristoDbRef(nil);
|
||||||
root = VertexID(1);
|
|
||||||
indent = 4;
|
indent = 4;
|
||||||
): string =
|
): string =
|
||||||
filter.ppFilter(db.orDefault(), root, indent)
|
filter.ppFilter(db.orDefault(), indent)
|
||||||
|
|
||||||
proc pp*(
|
proc pp*(
|
||||||
be: BackendRef;
|
be: BackendRef;
|
||||||
db: AristoDbRef;
|
db: AristoDbRef;
|
||||||
root = VertexID(1);
|
|
||||||
indent = 4;
|
indent = 4;
|
||||||
): string =
|
): string =
|
||||||
result = db.roFilter.ppFilter(db, root, indent+1) & indent.toPfx
|
result = db.roFilter.ppFilter(db, indent+1) & indent.toPfx
|
||||||
case be.kind:
|
case be.kind:
|
||||||
of BackendMemory:
|
of BackendMemory:
|
||||||
result &= be.MemBackendRef.ppBe(db, root, indent+1)
|
result &= be.MemBackendRef.ppBe(db, indent+1)
|
||||||
of BackendRocksDB:
|
of BackendRocksDB:
|
||||||
result &= be.RdbBackendRef.ppBe(db, root, indent+1)
|
result &= be.RdbBackendRef.ppBe(db, indent+1)
|
||||||
of BackendVoid:
|
of BackendVoid:
|
||||||
result &= "<NoBackend>"
|
result &= "<NoBackend>"
|
||||||
|
|
||||||
proc pp*(
|
proc pp*(
|
||||||
db: AristoDbRef;
|
db: AristoDbRef;
|
||||||
root = VertexID(1);
|
|
||||||
indent = 4;
|
indent = 4;
|
||||||
backendOk = false;
|
backendOk = false;
|
||||||
filterOk = true;
|
filterOk = true;
|
||||||
|
@ -842,13 +810,13 @@ proc pp*(
|
||||||
if backendOk:
|
if backendOk:
|
||||||
result &= db.backend.pp(db)
|
result &= db.backend.pp(db)
|
||||||
elif filterOk:
|
elif filterOk:
|
||||||
result &= db.roFilter.ppFilter(db, root, indent+1)
|
result &= db.roFilter.ppFilter(db, indent+1)
|
||||||
|
|
||||||
proc pp*(sdb: MerkleSignRef; indent = 4): string =
|
proc pp*(sdb: MerkleSignRef; indent = 4): string =
|
||||||
"count=" & $sdb.count &
|
"count=" & $sdb.count &
|
||||||
" root=" & sdb.root.pp &
|
" root=" & sdb.root.pp &
|
||||||
" error=" & $sdb.error &
|
" error=" & $sdb.error &
|
||||||
"\n db\n " & sdb.db.pp(root=sdb.root, indent=indent+1)
|
"\n db\n " & sdb.db.pp(indent=indent+1)
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
# End
|
# End
|
||||||
|
|
|
@ -67,7 +67,7 @@ proc nullifyKey(
|
||||||
vid: VertexID; # Vertex IDs to clear
|
vid: VertexID; # Vertex IDs to clear
|
||||||
) =
|
) =
|
||||||
# Register for void hash (to be recompiled)
|
# Register for void hash (to be recompiled)
|
||||||
db.layersResLabel vid
|
db.layersResKey vid
|
||||||
|
|
||||||
proc disposeOfVtx(
|
proc disposeOfVtx(
|
||||||
db: AristoDbRef; # Database, top layer
|
db: AristoDbRef; # Database, top layer
|
||||||
|
@ -75,7 +75,7 @@ proc disposeOfVtx(
|
||||||
) =
|
) =
|
||||||
# Remove entry
|
# Remove entry
|
||||||
db.layersResVtx vid
|
db.layersResVtx vid
|
||||||
db.layersResLabel vid
|
db.layersResKey vid
|
||||||
db.vidDispose vid # Recycle ID
|
db.vidDispose vid # Recycle ID
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
|
|
@ -78,7 +78,7 @@ type
|
||||||
dudes: DudesRef ## Related DB descriptors
|
dudes: DudesRef ## Related DB descriptors
|
||||||
|
|
||||||
# Debugging data below, might go away in future
|
# Debugging data below, might go away in future
|
||||||
xMap*: VidsByLabelTab ## For pretty printing, extends `pAmk`
|
xMap*: VidsByKeyTab ## For pretty printing, extends `pAmk`
|
||||||
|
|
||||||
AristoDbAction* = proc(db: AristoDbRef) {.gcsafe, raises: [].}
|
AristoDbAction* = proc(db: AristoDbRef) {.gcsafe, raises: [].}
|
||||||
## Generic call back function/closure.
|
## Generic call back function/closure.
|
||||||
|
@ -90,9 +90,6 @@ type
|
||||||
func getOrVoid*[W](tab: Table[W,VertexRef]; w: W): VertexRef =
|
func getOrVoid*[W](tab: Table[W,VertexRef]; w: W): VertexRef =
|
||||||
tab.getOrDefault(w, VertexRef(nil))
|
tab.getOrDefault(w, VertexRef(nil))
|
||||||
|
|
||||||
func getOrVoid*[W](tab: Table[W,HashLabel]; w: W): HashLabel =
|
|
||||||
tab.getOrDefault(w, VOID_HASH_LABEL)
|
|
||||||
|
|
||||||
func getOrVoid*[W](tab: Table[W,NodeRef]; w: W): NodeRef =
|
func getOrVoid*[W](tab: Table[W,NodeRef]; w: W): NodeRef =
|
||||||
tab.getOrDefault(w, NodeRef(nil))
|
tab.getOrDefault(w, NodeRef(nil))
|
||||||
|
|
||||||
|
@ -134,9 +131,6 @@ func isValid*(key: HashKey): bool =
|
||||||
func isValid*(vid: VertexID): bool =
|
func isValid*(vid: VertexID): bool =
|
||||||
vid != VertexID(0)
|
vid != VertexID(0)
|
||||||
|
|
||||||
func isValid*(lbl: HashLabel): bool =
|
|
||||||
lbl.key.isValid
|
|
||||||
|
|
||||||
func isValid*(sqv: HashSet[VertexID]): bool =
|
func isValid*(sqv: HashSet[VertexID]): bool =
|
||||||
sqv != EmptyVidSet
|
sqv != EmptyVidSet
|
||||||
|
|
||||||
|
|
|
@ -86,18 +86,6 @@ type
|
||||||
root*: VertexID ## Root ID for the sub-trie
|
root*: VertexID ## Root ID for the sub-trie
|
||||||
path*: PathID ## Path into the `Patricia Trie`
|
path*: PathID ## Path into the `Patricia Trie`
|
||||||
|
|
||||||
HashLabel* = object
|
|
||||||
## Merkle hash key uniquely associated with a vertex ID. As hashes in a
|
|
||||||
## `Merkle Patricia Tree` are unique only on a particular sub-trie, the
|
|
||||||
## hash key is paired with the top vertex of the relevant sub-trie. This
|
|
||||||
## construction is similar to the one of a `LeafTie` object.
|
|
||||||
##
|
|
||||||
## Note that `HashLabel` objects have no representation in the
|
|
||||||
## `Aristo Trie`. They are used temporarily and in caches or backlog
|
|
||||||
## tables.
|
|
||||||
root*: VertexID ## Root ID for the sub-trie.
|
|
||||||
key*: HashKey ## Merkle hash or encoded small node data
|
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
# Chronicles formatters
|
# Chronicles formatters
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
@ -382,13 +370,6 @@ func hash*(a: HashKey): Hash =
|
||||||
h = h !& a.blob.hash
|
h = h !& a.blob.hash
|
||||||
!$h
|
!$h
|
||||||
|
|
||||||
func hash*(lbl: HashLabel): Hash =
|
|
||||||
## Table/KeyedQueue/HashSet mixin
|
|
||||||
var h: Hash = 0
|
|
||||||
h = h !& lbl.root.hash
|
|
||||||
h = h !& lbl.key.hash
|
|
||||||
!$h
|
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
# Miscellaneous helpers
|
# Miscellaneous helpers
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
|
|
@ -76,8 +76,8 @@ type
|
||||||
kMap*: Table[VertexID,HashKey] ## Filter Merkle hash key mapping
|
kMap*: Table[VertexID,HashKey] ## Filter Merkle hash key mapping
|
||||||
vGen*: seq[VertexID] ## Filter unique vertex ID generator
|
vGen*: seq[VertexID] ## Filter unique vertex ID generator
|
||||||
|
|
||||||
VidsByLabelTab* = Table[HashLabel,HashSet[VertexID]]
|
VidsByKeyTab* = Table[HashKey,HashSet[VertexID]]
|
||||||
## Reverse lookup searching `VertexID` by the hash key/label.
|
## Reverse lookup searching `VertexID` by the hash key.
|
||||||
|
|
||||||
LayerDeltaRef* = ref object
|
LayerDeltaRef* = ref object
|
||||||
## Delta layers are stacked implying a tables hierarchy. Table entries on
|
## Delta layers are stacked implying a tables hierarchy. Table entries on
|
||||||
|
@ -103,8 +103,8 @@ type
|
||||||
## inconsistent state that must be resolved.
|
## inconsistent state that must be resolved.
|
||||||
##
|
##
|
||||||
sTab*: Table[VertexID,VertexRef] ## Structural vertex table
|
sTab*: Table[VertexID,VertexRef] ## Structural vertex table
|
||||||
kMap*: Table[VertexID,HashLabel] ## Merkle hash key mapping
|
kMap*: Table[VertexID,HashKey] ## Merkle hash key mapping
|
||||||
pAmk*: VidsByLabelTab ## Reverse `kMap` entries, hash key lookup
|
pAmk*: VidsByKeyTab ## Reverse `kMap` entries, hash key lookup
|
||||||
|
|
||||||
LayerFinalRef* = ref object
|
LayerFinalRef* = ref object
|
||||||
## Final tables fully supersede tables on lower layers when stacked as a
|
## Final tables fully supersede tables on lower layers when stacked as a
|
||||||
|
|
|
@ -56,7 +56,7 @@ proc fwdFilter*(
|
||||||
ok FilterRef(
|
ok FilterRef(
|
||||||
src: srcRoot,
|
src: srcRoot,
|
||||||
sTab: layer.delta.sTab,
|
sTab: layer.delta.sTab,
|
||||||
kMap: layer.delta.kMap.pairs.toSeq.mapIt((it[0],it[1].key)).toTable,
|
kMap: layer.delta.kMap,
|
||||||
vGen: layer.final.vGen.vidReorg, # Compact recycled IDs
|
vGen: layer.final.vGen.vidReorg, # Compact recycled IDs
|
||||||
trg: trgRoot)
|
trg: trgRoot)
|
||||||
|
|
||||||
|
|
|
@ -51,9 +51,9 @@ proc getLayerStateRoots*(
|
||||||
spr.be = sprBeKey.to(Hash256)
|
spr.be = sprBeKey.to(Hash256)
|
||||||
|
|
||||||
spr.fg = block:
|
spr.fg = block:
|
||||||
let lbl = delta.kMap.getOrVoid VertexID(1)
|
let key = delta.kMap.getOrVoid VertexID(1)
|
||||||
if lbl.isValid:
|
if key.isValid:
|
||||||
lbl.key.to(Hash256)
|
key.to(Hash256)
|
||||||
else:
|
else:
|
||||||
EMPTY_ROOT_HASH
|
EMPTY_ROOT_HASH
|
||||||
if spr.fg.isValid:
|
if spr.fg.isValid:
|
||||||
|
@ -68,8 +68,7 @@ proc getLayerStateRoots*(
|
||||||
return ok(spr)
|
return ok(spr)
|
||||||
|
|
||||||
if chunkedMpt:
|
if chunkedMpt:
|
||||||
let lbl = HashLabel(root: VertexID(1), key: sprBeKey)
|
if VertexID(1) in delta.pAmk.getOrVoid sprBeKey:
|
||||||
if VertexID(1) in delta.pAmk.getOrVoid lbl:
|
|
||||||
spr.fg = spr.be
|
spr.fg = spr.be
|
||||||
return ok(spr)
|
return ok(spr)
|
||||||
|
|
||||||
|
|
|
@ -166,12 +166,12 @@ proc getKeyRc*(db: AristoDbRef; vid: VertexID): Result[HashKey,AristoError] =
|
||||||
block body:
|
block body:
|
||||||
let key = db.layersGetKey(vid).valueOr:
|
let key = db.layersGetKey(vid).valueOr:
|
||||||
break body
|
break body
|
||||||
# If there is a zero value label, the entry is either marked for being
|
# If there is a zero key value, the entry is either marked for being
|
||||||
# updated or for deletion on the database. So check below.
|
# updated or for deletion on the database. So check below.
|
||||||
if key.isValid:
|
if key.isValid:
|
||||||
return ok key
|
return ok key
|
||||||
|
|
||||||
# The zero value label does not refer to an update mark if there is no
|
# The zero key value does not refer to an update mark if there is no
|
||||||
# valid vertex (either on the cache or the backend whatever comes first.)
|
# valid vertex (either on the cache or the backend whatever comes first.)
|
||||||
let vtx = db.layersGetVtx(vid).valueOr:
|
let vtx = db.layersGetVtx(vid).valueOr:
|
||||||
# There was no vertex on the cache. So there must be one the backend (the
|
# There was no vertex on the cache. So there must be one the backend (the
|
||||||
|
@ -180,7 +180,7 @@ proc getKeyRc*(db: AristoDbRef; vid: VertexID): Result[HashKey,AristoError] =
|
||||||
if vtx.isValid:
|
if vtx.isValid:
|
||||||
return err(GetKeyUpdateNeeded)
|
return err(GetKeyUpdateNeeded)
|
||||||
else:
|
else:
|
||||||
# The vertex is to be deleted. So is the value label.
|
# The vertex is to be deleted. So is the value key.
|
||||||
return err(GetKeyNotFound)
|
return err(GetKeyNotFound)
|
||||||
|
|
||||||
db.getKeyBE vid
|
db.getKeyBE vid
|
||||||
|
|
|
@ -25,7 +25,7 @@
|
||||||
## `lTab[]` entry with `(root-vertex,path,VertexID(0))`.
|
## `lTab[]` entry with `(root-vertex,path,VertexID(0))`.
|
||||||
##
|
##
|
||||||
## * All vertices where the key (aka Merkle hash) has changed must have a
|
## * All vertices where the key (aka Merkle hash) has changed must have a
|
||||||
## top layer cache `kMap[]` entry `(vertex-ID,VOID_HASH_LABEL)` indicating
|
## top layer cache `kMap[]` entry `(vertex-ID,VOID_HASH_KEY)` indicating
|
||||||
## that there is no key available for this vertex. This also applies for
|
## that there is no key available for this vertex. This also applies for
|
||||||
## backend verices where the key has changed while the structural logic
|
## backend verices where the key has changed while the structural logic
|
||||||
## did not change.
|
## did not change.
|
||||||
|
@ -333,8 +333,8 @@ proc hashify*(
|
||||||
# is the task to search for unresolved node keys and add glue paths to
|
# is the task to search for unresolved node keys and add glue paths to
|
||||||
# the width-first schedule.
|
# the width-first schedule.
|
||||||
var unresolved: HashSet[VertexID]
|
var unresolved: HashSet[VertexID]
|
||||||
for (vid,lbl) in db.layersWalkLabel:
|
for (vid,key) in db.layersWalkKey:
|
||||||
if not lbl.isValid and
|
if not key.isValid and
|
||||||
vid notin wff:
|
vid notin wff:
|
||||||
let rc = db.layersGetVtx vid
|
let rc = db.layersGetVtx vid
|
||||||
if rc.isErr or rc.value.isValid:
|
if rc.isErr or rc.value.isValid:
|
||||||
|
@ -390,8 +390,7 @@ proc hashify*(
|
||||||
# End `valueOr` terminates error clause
|
# End `valueOr` terminates error clause
|
||||||
|
|
||||||
# Could resolve => update Merkle hash
|
# Could resolve => update Merkle hash
|
||||||
let key = node.digestTo(HashKey)
|
db.layersPutKey(vid, node.digestTo HashKey)
|
||||||
db.layersPutLabel(vid, HashLabel(root: val.root, key: key))
|
|
||||||
|
|
||||||
# Set follow up link for next round
|
# Set follow up link for next round
|
||||||
wff.setNextLink(redo, val)
|
wff.setNextLink(redo, val)
|
||||||
|
@ -410,7 +409,7 @@ proc hashify*(
|
||||||
# Convert root vertex to a node.
|
# Convert root vertex to a node.
|
||||||
let node = db.getVtx(vid).toNode(db,stopEarly=false).valueOr:
|
let node = db.getVtx(vid).toNode(db,stopEarly=false).valueOr:
|
||||||
return err((vid,HashifyRootNodeUnresolved))
|
return err((vid,HashifyRootNodeUnresolved))
|
||||||
db.layersPutLabel(vid, HashLabel(root: vid, key: node.digestTo(HashKey)))
|
db.layersPutKey(vid, node.digestTo(HashKey))
|
||||||
wff.completed.incl vid
|
wff.completed.incl vid
|
||||||
|
|
||||||
db.top.final.dirty = false # Mark top layer clean
|
db.top.final.dirty = false # Mark top layer clean
|
||||||
|
|
|
@ -25,21 +25,21 @@ func dup(sTab: Table[VertexID,VertexRef]): Table[VertexID,VertexRef] =
|
||||||
for (k,v) in sTab.pairs:
|
for (k,v) in sTab.pairs:
|
||||||
result[k] = v.dup
|
result[k] = v.dup
|
||||||
|
|
||||||
func getLebalOrVoid(stack: seq[LayerRef]; lbl: HashLabel): HashSet[VertexID] =
|
func getLebalOrVoid(stack: seq[LayerRef]; key: HashKey): HashSet[VertexID] =
|
||||||
# Helper: get next set of vertex IDs from stack.
|
# Helper: get next set of vertex IDs from stack.
|
||||||
for w in stack.reversed:
|
for w in stack.reversed:
|
||||||
w.delta.pAmk.withValue(lbl,value):
|
w.delta.pAmk.withValue(key,value):
|
||||||
return value[]
|
return value[]
|
||||||
|
|
||||||
proc recalcLebal(layer: var LayerObj) =
|
proc recalcLebal(layer: var LayerObj) =
|
||||||
## Calculate reverse `kMap[]` for final (aka zero) layer
|
## Calculate reverse `kMap[]` for final (aka zero) layer
|
||||||
layer.delta.pAmk.clear
|
layer.delta.pAmk.clear
|
||||||
for (vid,lbl) in layer.delta.kMap.pairs:
|
for (vid,key) in layer.delta.kMap.pairs:
|
||||||
if lbl.isValid:
|
if key.isValid:
|
||||||
layer.delta.pAmk.withValue(lbl, value):
|
layer.delta.pAmk.withValue(key, value):
|
||||||
value[].incl vid
|
value[].incl vid
|
||||||
do:
|
do:
|
||||||
layer.delta.pAmk[lbl] = @[vid].toHashSet
|
layer.delta.pAmk[key] = @[vid].toHashSet
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
# Public getters: lazy value lookup for read only versions
|
# Public getters: lazy value lookup for read only versions
|
||||||
|
@ -62,24 +62,25 @@ func dirty*(db: AristoDbRef): bool =
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
func nLayersVtx*(db: AristoDbRef): int =
|
func nLayersVtx*(db: AristoDbRef): int =
|
||||||
## Number of vertex ID/vertex entries on the cache layers. This is an upper
|
## Number of vertex ID/vertex entries on the cache layers. This is an upper bound
|
||||||
## bound for the number of effective vertex ID mappings held on the cache
|
## for the number of effective vertex ID mappings held on the cache layers as
|
||||||
## layers as there might be duplicate entries for the same vertex ID on
|
## there might be duplicate entries for the same vertex ID on different layers.
|
||||||
## different layers.
|
##
|
||||||
db.stack.mapIt(it.delta.sTab.len).foldl(a + b, db.top.delta.sTab.len)
|
db.stack.mapIt(it.delta.sTab.len).foldl(a + b, db.top.delta.sTab.len)
|
||||||
|
|
||||||
func nLayersLabel*(db: AristoDbRef): int =
|
func nLayersKey*(db: AristoDbRef): int =
|
||||||
## Number of vertex ID/label entries on the cache layers. This is an upper
|
## Number of vertex ID/key entries on the cache layers. This is an upper bound
|
||||||
## bound for the number of effective vertex ID mappingss held on the cache
|
## for the number of effective vertex ID mappingss held on the cache layers as
|
||||||
## layers as there might be duplicate entries for the same vertex ID on
|
## there might be duplicate entries for the same vertex ID on different layers.
|
||||||
## different layers.
|
##
|
||||||
db.stack.mapIt(it.delta.kMap.len).foldl(a + b, db.top.delta.kMap.len)
|
db.stack.mapIt(it.delta.kMap.len).foldl(a + b, db.top.delta.kMap.len)
|
||||||
|
|
||||||
func nLayersLebal*(db: AristoDbRef): int =
|
func nLayersYek*(db: AristoDbRef): int =
|
||||||
## Number of label/vertex IDs reverse lookup entries on the cache layers.
|
## Number of key/vertex IDs reverse lookup entries on the cache layers. This
|
||||||
## This is an upper bound for the number of effective label mappingss held
|
## is an upper bound for the number of effective key mappingss held on the
|
||||||
## on the cache layers as there might be duplicate entries for the same label
|
## cache layers as there might be duplicate entries for the same key on
|
||||||
## on different layers.
|
## different layers.
|
||||||
|
##
|
||||||
db.stack.mapIt(it.delta.pAmk.len).foldl(a + b, db.top.delta.pAmk.len)
|
db.stack.mapIt(it.delta.pAmk.len).foldl(a + b, db.top.delta.pAmk.len)
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
@ -104,10 +105,9 @@ proc layersGetVtxOrVoid*(db: AristoDbRef; vid: VertexID): VertexRef =
|
||||||
db.layersGetVtx(vid).valueOr: VertexRef(nil)
|
db.layersGetVtx(vid).valueOr: VertexRef(nil)
|
||||||
|
|
||||||
|
|
||||||
proc layersGetLabel*(db: AristoDbRef; vid: VertexID): Result[HashLabel,void] =
|
proc layersGetKey*(db: AristoDbRef; vid: VertexID): Result[HashKey,void] =
|
||||||
## Find a hash label (containh the `HashKey`) on the cache layers. An
|
## Find a hash key on the cache layers. An `ok()` result might contain a void
|
||||||
## `ok()` result might contain a void hash label if it is stored on the
|
## hash key if it is stored on the cache that way.
|
||||||
## cache that way.
|
|
||||||
##
|
##
|
||||||
if db.top.delta.kMap.hasKey vid:
|
if db.top.delta.kMap.hasKey vid:
|
||||||
# This is ok regardless of the `dirty` flag. If this vertex has become
|
# This is ok regardless of the `dirty` flag. If this vertex has become
|
||||||
|
@ -121,43 +121,30 @@ proc layersGetLabel*(db: AristoDbRef; vid: VertexID): Result[HashLabel,void] =
|
||||||
|
|
||||||
err()
|
err()
|
||||||
|
|
||||||
proc layersGetlabelOrVoid*(db: AristoDbRef; vid: VertexID): HashLabel =
|
|
||||||
## Simplified version of `layersGetLabel()`
|
|
||||||
db.layersGetLabel(vid).valueOr: VOID_HASH_LABEL
|
|
||||||
|
|
||||||
|
|
||||||
proc layersGetKey*(db: AristoDbRef; vid: VertexID): Result[HashKey,void] =
|
|
||||||
## Variant of `layersGetLabel()` for returning the `HashKey` part of the
|
|
||||||
## label only.
|
|
||||||
let lbl = db.layersGetLabel(vid).valueOr:
|
|
||||||
return err()
|
|
||||||
# Note that `lbl.isValid == lbl.key.isValid`
|
|
||||||
ok(lbl.key)
|
|
||||||
|
|
||||||
proc layersGetKeyOrVoid*(db: AristoDbRef; vid: VertexID): HashKey =
|
proc layersGetKeyOrVoid*(db: AristoDbRef; vid: VertexID): HashKey =
|
||||||
## Simplified version of `layersGetKey()`
|
## Simplified version of `layersGetkey()`
|
||||||
db.layersGetKey(vid).valueOr: VOID_HASH_KEY
|
db.layersGetKey(vid).valueOr: VOID_HASH_KEY
|
||||||
|
|
||||||
|
|
||||||
proc layersGetLebal*(
|
proc layersGetYek*(
|
||||||
db: AristoDbRef;
|
db: AristoDbRef;
|
||||||
lbl: HashLabel;
|
key: HashKey;
|
||||||
): Result[HashSet[VertexID],void] =
|
): Result[HashSet[VertexID],void] =
|
||||||
## Inverse of `layersGetKey()`. For a given argumnt `lbl`, find all vertex
|
## Inverse of `layersGetKey()`. For a given argumnt `key`, finds all vertex IDs
|
||||||
## IDs that have `layersGetLbl()` return this very `lbl` value for the these
|
## that have `layersGetKey()` return this very `key` value for the argument
|
||||||
## vertex IDs.
|
## vertex IDs.
|
||||||
if db.top.delta.pAmk.hasKey lbl:
|
if db.top.delta.pAmk.hasKey key:
|
||||||
return ok(db.top.delta.pAmk.getOrVoid lbl)
|
return ok(db.top.delta.pAmk.getOrVoid key)
|
||||||
|
|
||||||
for w in db.stack.reversed:
|
for w in db.stack.reversed:
|
||||||
if w.delta.pAmk.hasKey lbl:
|
if w.delta.pAmk.hasKey key:
|
||||||
return ok(w.delta.pAmk.getOrVoid lbl)
|
return ok(w.delta.pAmk.getOrVoid key)
|
||||||
|
|
||||||
err()
|
err()
|
||||||
|
|
||||||
proc layersGetLebalOrVoid*(db: AristoDbRef; lbl: HashLabel): HashSet[VertexID] =
|
proc layersGetYekOrVoid*(db: AristoDbRef; key: HashKey): HashSet[VertexID] =
|
||||||
## Simplified version of `layersGetVidsOrVoid()`
|
## Simplified version of `layersGetVidsOrVoid()`
|
||||||
db.layersGetLebal(lbl).valueOr: EmptyVidSet
|
db.layersGetYek(key).valueOr: EmptyVidSet
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
# Public functions: put variants
|
# Public functions: put variants
|
||||||
|
@ -174,43 +161,43 @@ proc layersResVtx*(db: AristoDbRef; vid: VertexID) =
|
||||||
db.layersPutVtx(vid, VertexRef(nil))
|
db.layersPutVtx(vid, VertexRef(nil))
|
||||||
|
|
||||||
|
|
||||||
proc layersPutLabel*(db: AristoDbRef; vid: VertexID; lbl: HashLabel) =
|
proc layersPutKey*(db: AristoDbRef; vid: VertexID; key: HashKey) =
|
||||||
## Store a (potentally void) hash label on the top layer
|
## Store a (potentally void) hash key on the top layer
|
||||||
|
|
||||||
# Get previous label
|
# Get previous key
|
||||||
let blb = db.top.delta.kMap.getOrVoid vid
|
let prvKey = db.top.delta.kMap.getOrVoid vid
|
||||||
|
|
||||||
# Update label on `label->vid` mapping table
|
# Update key on `kMap:key->vid` mapping table
|
||||||
db.top.delta.kMap[vid] = lbl
|
db.top.delta.kMap[vid] = key
|
||||||
db.top.final.dirty = true # Modified top cache layers
|
db.top.final.dirty = true # Modified top cache layers
|
||||||
|
|
||||||
# Clear previous value on reverse table if it has changed
|
# Clear previous value on reverse table if it has changed
|
||||||
if blb.isValid and blb != lbl:
|
if prvKey.isValid and prvKey != key:
|
||||||
var vidsLen = -1
|
var vidsLen = -1
|
||||||
db.top.delta.pAmk.withValue(blb, value):
|
db.top.delta.pAmk.withValue(prvKey, value):
|
||||||
value[].excl vid
|
value[].excl vid
|
||||||
vidsLen = value[].len
|
vidsLen = value[].len
|
||||||
do: # provide empty lookup
|
do: # provide empty lookup
|
||||||
let vids = db.stack.getLebalOrVoid(blb)
|
let vids = db.stack.getLebalOrVoid(prvKey)
|
||||||
if vids.isValid and vid in vids:
|
if vids.isValid and vid in vids:
|
||||||
# This entry supersedes non-emtpty changed ones from lower levels
|
# This entry supersedes non-emtpty changed ones from lower levels
|
||||||
db.top.delta.pAmk[blb] = vids - @[vid].toHashSet
|
db.top.delta.pAmk[prvKey] = vids - @[vid].toHashSet
|
||||||
if vidsLen == 0 and not db.stack.getLebalOrVoid(blb).isValid:
|
if vidsLen == 0 and not db.stack.getLebalOrVoid(prvKey).isValid:
|
||||||
# There is no non-emtpty entry on lower levels, so ledete this one
|
# There is no non-emtpty entry on lower levels, so ledete this one
|
||||||
db.top.delta.pAmk.del blb
|
db.top.delta.pAmk.del prvKey
|
||||||
|
|
||||||
# Add updated value on reverse table if non-zero
|
# Add updated value on reverse table if non-zero
|
||||||
if lbl.isValid:
|
if key.isValid:
|
||||||
db.top.delta.pAmk.withValue(lbl, value):
|
db.top.delta.pAmk.withValue(key, value):
|
||||||
value[].incl vid
|
value[].incl vid
|
||||||
do: # else if not found: need to merge with value set from lower layer
|
do: # else if not found: need to merge with value set from lower layer
|
||||||
db.top.delta.pAmk[lbl] = db.stack.getLebalOrVoid(lbl) + @[vid].toHashSet
|
db.top.delta.pAmk[key] = db.stack.getLebalOrVoid(key) + @[vid].toHashSet
|
||||||
|
|
||||||
|
|
||||||
proc layersResLabel*(db: AristoDbRef; vid: VertexID) =
|
proc layersResKey*(db: AristoDbRef; vid: VertexID) =
|
||||||
## Shortcut for `db.layersPutLabel(vid, VOID_HASH_LABEL)`. It is sort of the
|
## Shortcut for `db.layersPutKey(vid, VOID_HASH_KEY)`. It is sort of the
|
||||||
## equivalent of a delete function.
|
## equivalent of a delete function.
|
||||||
db.layersPutLabel(vid, VOID_HASH_LABEL)
|
db.layersPutKey(vid, VOID_HASH_KEY)
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
# Public functions
|
# Public functions
|
||||||
|
@ -225,18 +212,18 @@ proc layersMergeOnto*(src: LayerRef; trg: var LayerObj; stack: seq[LayerRef]) =
|
||||||
|
|
||||||
for (vid,vtx) in src.delta.sTab.pairs:
|
for (vid,vtx) in src.delta.sTab.pairs:
|
||||||
trg.delta.sTab[vid] = vtx
|
trg.delta.sTab[vid] = vtx
|
||||||
for (vid,lbl) in src.delta.kMap.pairs:
|
for (vid,key) in src.delta.kMap.pairs:
|
||||||
trg.delta.kMap[vid] = lbl
|
trg.delta.kMap[vid] = key
|
||||||
|
|
||||||
if stack.len == 0:
|
if stack.len == 0:
|
||||||
# Re-calculate `pAmk[]`
|
# Re-calculate `pAmk[]`
|
||||||
trg.recalcLebal()
|
trg.recalcLebal()
|
||||||
else:
|
else:
|
||||||
# Merge reverse `kMap[]` layers. Empty label image sets are ignored unless
|
# Merge reverse `kMap[]` layers. Empty key set images are ignored unless
|
||||||
# they supersede non-empty values on the argument `stack[]`.
|
# they supersede non-empty values on the argument `stack[]`.
|
||||||
for (lbl,vids) in src.delta.pAmk.pairs:
|
for (key,vids) in src.delta.pAmk.pairs:
|
||||||
if 0 < vids.len or stack.getLebalOrVoid(lbl).isValid:
|
if 0 < vids.len or stack.getLebalOrVoid(key).isValid:
|
||||||
trg.delta.pAmk[lbl] = vids
|
trg.delta.pAmk[key] = vids
|
||||||
|
|
||||||
|
|
||||||
func layersCc*(db: AristoDbRef; level = high(int)): LayerRef =
|
func layersCc*(db: AristoDbRef; level = high(int)): LayerRef =
|
||||||
|
@ -258,8 +245,8 @@ func layersCc*(db: AristoDbRef; level = high(int)): LayerRef =
|
||||||
for n in 1 ..< layers.len:
|
for n in 1 ..< layers.len:
|
||||||
for (vid,vtx) in layers[n].delta.sTab.pairs:
|
for (vid,vtx) in layers[n].delta.sTab.pairs:
|
||||||
result.delta.sTab[vid] = vtx
|
result.delta.sTab[vid] = vtx
|
||||||
for (vid,lbl) in layers[n].delta.kMap.pairs:
|
for (vid,key) in layers[n].delta.kMap.pairs:
|
||||||
result.delta.kMap[vid] = lbl
|
result.delta.kMap[vid] = key
|
||||||
|
|
||||||
# Re-calculate `pAmk[]`
|
# Re-calculate `pAmk[]`
|
||||||
result[].recalcLebal()
|
result[].recalcLebal()
|
||||||
|
@ -298,37 +285,37 @@ iterator layersWalkVtx*(
|
||||||
yield (vid,vtx)
|
yield (vid,vtx)
|
||||||
|
|
||||||
|
|
||||||
iterator layersWalkLabel*(
|
iterator layersWalkKey*(
|
||||||
db: AristoDbRef;
|
db: AristoDbRef;
|
||||||
): tuple[vid: VertexID, lbl: HashLabel] =
|
): tuple[vid: VertexID, key: HashKey] =
|
||||||
## Walk over all `(VertexID,HashLabel)` pairs on the cache layers. Note that
|
## Walk over all `(VertexID,HashKey)` pairs on the cache layers. Note that
|
||||||
## entries are unsorted.
|
## entries are unsorted.
|
||||||
var seen: HashSet[VertexID]
|
var seen: HashSet[VertexID]
|
||||||
for (vid,lbl) in db.top.delta.kMap.pairs:
|
for (vid,key) in db.top.delta.kMap.pairs:
|
||||||
yield (vid,lbl)
|
yield (vid,key)
|
||||||
seen.incl vid
|
seen.incl vid
|
||||||
|
|
||||||
for w in db.stack.reversed:
|
for w in db.stack.reversed:
|
||||||
for (vid,lbl) in w.delta.kMap.pairs:
|
for (vid,key) in w.delta.kMap.pairs:
|
||||||
if vid notin seen:
|
if vid notin seen:
|
||||||
yield (vid,lbl)
|
yield (vid,key)
|
||||||
seen.incl vid
|
seen.incl vid
|
||||||
|
|
||||||
|
|
||||||
iterator layersWalkLebal*(
|
iterator layersWalkYek*(
|
||||||
db: AristoDbRef;
|
db: AristoDbRef;
|
||||||
): tuple[lbl: HashLabel, vids: HashSet[VertexID]] =
|
): tuple[key: HashKey, vids: HashSet[VertexID]] =
|
||||||
## Walk over `(HashLabel,HashSet[VertexID])` pairs.
|
## Walk over `(HashKey,HashSet[VertexID])` pairs.
|
||||||
var seen: HashSet[HashLabel]
|
var seen: HashSet[HashKey]
|
||||||
for (lbl,vids) in db.top.delta.pAmk.pairs:
|
for (key,vids) in db.top.delta.pAmk.pairs:
|
||||||
yield (lbl,vids)
|
yield (key,vids)
|
||||||
seen.incl lbl
|
seen.incl key
|
||||||
|
|
||||||
for w in db.stack.reversed:
|
for w in db.stack.reversed:
|
||||||
for (lbl,vids) in w.delta.pAmk.pairs:
|
for (key,vids) in w.delta.pAmk.pairs:
|
||||||
if lbl notin seen:
|
if key notin seen:
|
||||||
yield (lbl,vids)
|
yield (key,vids)
|
||||||
seen.incl lbl
|
seen.incl key
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
# End
|
# End
|
||||||
|
|
|
@ -81,7 +81,7 @@ proc nullifyKey(
|
||||||
vid: VertexID; # Vertex IDs to clear
|
vid: VertexID; # Vertex IDs to clear
|
||||||
) =
|
) =
|
||||||
# Register for void hash (to be recompiled)
|
# Register for void hash (to be recompiled)
|
||||||
db.layersResLabel vid
|
db.layersResKey vid
|
||||||
|
|
||||||
proc clearMerkleKeys(
|
proc clearMerkleKeys(
|
||||||
db: AristoDbRef; # Database, top layer
|
db: AristoDbRef; # Database, top layer
|
||||||
|
@ -97,7 +97,7 @@ proc setVtxAndKey(
|
||||||
vtx: VertexRef; # Vertex to add
|
vtx: VertexRef; # Vertex to add
|
||||||
) =
|
) =
|
||||||
db.layersPutVtx(vid, vtx)
|
db.layersPutVtx(vid, vtx)
|
||||||
db.layersResLabel vid
|
db.layersResKey vid
|
||||||
|
|
||||||
# -----------
|
# -----------
|
||||||
|
|
||||||
|
@ -512,8 +512,7 @@ proc mergeNodeImpl(
|
||||||
# already. This is provided for if the `nodes` are processed in the right
|
# already. This is provided for if the `nodes` are processed in the right
|
||||||
# order `root->.. ->leaf`.
|
# order `root->.. ->leaf`.
|
||||||
let
|
let
|
||||||
hashLbl = HashLabel(root: rootVid, key: hashKey)
|
vids = db.layersGetYekOrVoid(hashKey).toSeq
|
||||||
vids = db.layersGetLebalOrVoid(hashLbl).toSeq
|
|
||||||
isRoot = rootVid in vids
|
isRoot = rootVid in vids
|
||||||
if vids.len == 0:
|
if vids.len == 0:
|
||||||
return err(MergeRevVidMustHaveBeenCached)
|
return err(MergeRevVidMustHaveBeenCached)
|
||||||
|
@ -522,8 +521,8 @@ proc mergeNodeImpl(
|
||||||
return err(MergeHashKeyRevLookUpGarbled)
|
return err(MergeHashKeyRevLookUpGarbled)
|
||||||
|
|
||||||
# Use the first vertex ID from the `vis` list as representant for all others
|
# Use the first vertex ID from the `vis` list as representant for all others
|
||||||
let lbl = db.layersGetLabelOrVoid vids[0]
|
let key = db.layersGetKeyOrVoid vids[0]
|
||||||
if lbl == hashLbl:
|
if key == hashKey:
|
||||||
if db.layersGetVtx(vids[0]).isOk:
|
if db.layersGetVtx(vids[0]).isOk:
|
||||||
for n in 1 ..< vids.len:
|
for n in 1 ..< vids.len:
|
||||||
if db.layersGetVtx(vids[n]).isErr:
|
if db.layersGetVtx(vids[n]).isErr:
|
||||||
|
@ -531,7 +530,7 @@ proc mergeNodeImpl(
|
||||||
# This is tyically considered OK
|
# This is tyically considered OK
|
||||||
return err(MergeHashKeyCachedAlready)
|
return err(MergeHashKeyCachedAlready)
|
||||||
# Otherwise proceed
|
# Otherwise proceed
|
||||||
elif lbl.isValid:
|
elif key.isValid:
|
||||||
# Different key assigned => error
|
# Different key assigned => error
|
||||||
return err(MergeHashKeyDiffersFromCached)
|
return err(MergeHashKeyDiffersFromCached)
|
||||||
|
|
||||||
|
@ -548,7 +547,7 @@ proc mergeNodeImpl(
|
||||||
# Verify that all `vids` entries are similar
|
# Verify that all `vids` entries are similar
|
||||||
for n in 1 ..< vids.len:
|
for n in 1 ..< vids.len:
|
||||||
let w = vids[n]
|
let w = vids[n]
|
||||||
if lbl != db.layersGetLabelOrVoid(w) or db.layersGetVtx(w).isOk:
|
if key != db.layersGetKeyOrVoid(w) or db.layersGetVtx(w).isOk:
|
||||||
return err(MergeHashKeyRevLookUpGarbled)
|
return err(MergeHashKeyRevLookUpGarbled)
|
||||||
if not hasVtx:
|
if not hasVtx:
|
||||||
# Prefer existing node which has all links available, already.
|
# Prefer existing node which has all links available, already.
|
||||||
|
@ -556,31 +555,31 @@ proc mergeNodeImpl(
|
||||||
if u.isValid:
|
if u.isValid:
|
||||||
(vtx, hasVtx) = (u, true)
|
(vtx, hasVtx) = (u, true)
|
||||||
|
|
||||||
# The `vertexID <-> hashLabel` mappings need to be set up now (if any)
|
# The `vertexID <-> hashKey` mappings need to be set up now (if any)
|
||||||
case node.vType:
|
case node.vType:
|
||||||
of Leaf:
|
of Leaf:
|
||||||
discard
|
discard
|
||||||
of Extension:
|
of Extension:
|
||||||
if node.key[0].isValid:
|
if node.key[0].isValid:
|
||||||
let eLbl = HashLabel(root: rootVid, key: node.key[0])
|
let eKey = node.key[0]
|
||||||
if not hasVtx:
|
if not hasVtx:
|
||||||
# Brand new reverse lookup link for this vertex
|
# Brand new reverse lookup link for this vertex
|
||||||
vtx.eVid = db.vidFetch
|
vtx.eVid = db.vidFetch
|
||||||
db.layersPutLabel(vtx.eVid, eLbl)
|
db.layersPutKey(vtx.eVid, eKey)
|
||||||
elif not vtx.eVid.isValid:
|
elif not vtx.eVid.isValid:
|
||||||
return err(MergeNodeVtxDiffersFromExisting)
|
return err(MergeNodeVtxDiffersFromExisting)
|
||||||
db.layersPutLabel(vtx.eVid, eLbl)
|
db.layersPutKey(vtx.eVid, eKey)
|
||||||
of Branch:
|
of Branch:
|
||||||
for n in 0..15:
|
for n in 0..15:
|
||||||
if node.key[n].isValid:
|
if node.key[n].isValid:
|
||||||
let bLbl = HashLabel(root: rootVid, key: node.key[n])
|
let bKey = node.key[n]
|
||||||
if not hasVtx:
|
if not hasVtx:
|
||||||
# Brand new reverse lookup link for this vertex
|
# Brand new reverse lookup link for this vertex
|
||||||
vtx.bVid[n] = db.vidFetch
|
vtx.bVid[n] = db.vidFetch
|
||||||
db.layersPutLabel(vtx.bVid[n], bLbl)
|
db.layersPutKey(vtx.bVid[n], bKey)
|
||||||
elif not vtx.bVid[n].isValid:
|
elif not vtx.bVid[n].isValid:
|
||||||
return err(MergeNodeVtxDiffersFromExisting)
|
return err(MergeNodeVtxDiffersFromExisting)
|
||||||
db.layersPutLabel(vtx.bVid[n], bLbl)
|
db.layersPutKey(vtx.bVid[n], bKey)
|
||||||
|
|
||||||
for w in vids:
|
for w in vids:
|
||||||
db.top.final.pPrf.incl w
|
db.top.final.pPrf.incl w
|
||||||
|
@ -824,13 +823,11 @@ proc merge*(
|
||||||
if 0 < chain.len and chain[^1] == rootKey:
|
if 0 < chain.len and chain[^1] == rootKey:
|
||||||
chains.add chain
|
chains.add chain
|
||||||
|
|
||||||
# Make sure that the reverse lookup for the root vertex label is available.
|
# Make sure that the reverse lookup for the root vertex key is available.
|
||||||
block:
|
block:
|
||||||
let
|
let vids = db.layersGetYekOrVoid rootKey
|
||||||
lbl = HashLabel(root: rootVid, key: rootKey)
|
|
||||||
vids = db.layersGetLebalOrVoid lbl
|
|
||||||
if not vids.isValid:
|
if not vids.isValid:
|
||||||
db.layersPutlabel(rootVid, lbl)
|
db.layersPutKey(rootVid, rootKey)
|
||||||
|
|
||||||
# Process over chains in reverse mode starting with the root node. This
|
# Process over chains in reverse mode starting with the root node. This
|
||||||
# allows the algorithm to find existing nodes on the backend.
|
# allows the algorithm to find existing nodes on the backend.
|
||||||
|
@ -882,7 +879,7 @@ proc merge*(
|
||||||
return ok rootVid
|
return ok rootVid
|
||||||
|
|
||||||
if not key.isValid:
|
if not key.isValid:
|
||||||
db.layersPutLabel(rootVid, HashLabel(root: rootVid, key: rootLink))
|
db.layersPutKey(rootVid, rootLink)
|
||||||
return ok rootVid
|
return ok rootVid
|
||||||
else:
|
else:
|
||||||
let key = db.getKey VertexID(1)
|
let key = db.getKey VertexID(1)
|
||||||
|
@ -891,13 +888,13 @@ proc merge*(
|
||||||
|
|
||||||
# Otherwise assign unless valid
|
# Otherwise assign unless valid
|
||||||
if not key.isValid:
|
if not key.isValid:
|
||||||
db.layersPutLabel(VertexID(1),HashLabel(root: VertexID(1), key: rootLink))
|
db.layersPutKey(VertexID(1), rootLink)
|
||||||
return ok VertexID(1)
|
return ok VertexID(1)
|
||||||
|
|
||||||
# Create and assign a new root key
|
# Create and assign a new root key
|
||||||
if not rootVid.isValid:
|
if not rootVid.isValid:
|
||||||
let vid = db.vidFetch
|
let vid = db.vidFetch
|
||||||
db.layersPutLabel(vid, HashLabel(root: vid, key: rootLink))
|
db.layersPutKey(vid, rootLink)
|
||||||
return ok vid
|
return ok vid
|
||||||
|
|
||||||
err(MergeRootKeyDiffersForVid)
|
err(MergeRootKeyDiffersForVid)
|
||||||
|
|
|
@ -108,10 +108,10 @@ proc toNode*(
|
||||||
##
|
##
|
||||||
proc getKey(db: AristoDbRef; vid: VertexID; beOk: bool): HashKey =
|
proc getKey(db: AristoDbRef; vid: VertexID; beOk: bool): HashKey =
|
||||||
block body:
|
block body:
|
||||||
let lbl = db.layersGetLabel(vid).valueOr:
|
let key = db.layersGetKey(vid).valueOr:
|
||||||
break body
|
break body
|
||||||
if lbl.isValid:
|
if key.isValid:
|
||||||
return lbl.key
|
return key
|
||||||
else:
|
else:
|
||||||
return VOID_HASH_KEY
|
return VOID_HASH_KEY
|
||||||
if beOk:
|
if beOk:
|
||||||
|
@ -225,7 +225,7 @@ proc registerAccount*(
|
||||||
|
|
||||||
# Clear Merkle keys and store leaf record
|
# Clear Merkle keys and store leaf record
|
||||||
for w in hike.legs.mapIt(it.wp.vid):
|
for w in hike.legs.mapIt(it.wp.vid):
|
||||||
db.layersResLabel w
|
db.layersResKey w
|
||||||
db.top.final.lTab[lty] = wp.vid
|
db.top.final.lTab[lty] = wp.vid
|
||||||
|
|
||||||
ok()
|
ok()
|
||||||
|
|
|
@ -76,8 +76,7 @@ func ppFil(w: FilterRef; db = AristoDbRef(nil)): string =
|
||||||
let n = key.to(UInt256)
|
let n = key.to(UInt256)
|
||||||
if n == 0: "£ø" else: "£" & $n
|
if n == 0: "£ø" else: "£" & $n
|
||||||
else:
|
else:
|
||||||
let keyLink = HashKey.fromBytes(key.data).value
|
HashKey.fromBytes(key.data).value.pp(db)
|
||||||
HashLabel(root: VertexID(1), key: keyLink).pp(db)
|
|
||||||
"(" & w.fid.pp & "," & w.src.qq(db) & "->" & w.trg.qq(db) & ")"
|
"(" & w.fid.pp & "," & w.src.qq(db) & "->" & w.trg.qq(db) & ")"
|
||||||
|
|
||||||
func pp(qf: (QueueID,FilterRef); db = AristoDbRef(nil)): string =
|
func pp(qf: (QueueID,FilterRef); db = AristoDbRef(nil)): string =
|
||||||
|
|
|
@ -59,7 +59,7 @@ func pp*(
|
||||||
let
|
let
|
||||||
pfx = indent.toPfx
|
pfx = indent.toPfx
|
||||||
rootLink = w.root.to(HashKey)
|
rootLink = w.root.to(HashKey)
|
||||||
result = "(" & HashLabel(root: rootID, key: rootLink).pp(db)
|
result = "(" & rootLink.pp(db)
|
||||||
result &= "," & $w.id & ",[" & $w.proof.len & "],"
|
result &= "," & $w.id & ",[" & $w.proof.len & "],"
|
||||||
result &= pfx & " ["
|
result &= pfx & " ["
|
||||||
for n,kvp in w.kvpLst:
|
for n,kvp in w.kvpLst:
|
||||||
|
|
|
@ -493,7 +493,7 @@ proc testShortKeys*(
|
||||||
"\n r=", r.pp(sig),
|
"\n r=", r.pp(sig),
|
||||||
"\n ", sig.pp(),
|
"\n ", sig.pp(),
|
||||||
"\n",
|
"\n",
|
||||||
"\n pAmk=", sig.db.layersWalkLebal.toSeq.toTable.pp(sig.db),
|
"\n pAmk=", sig.db.layersWalkYek.toSeq.toTable.pp(sig.db),
|
||||||
"\n"
|
"\n"
|
||||||
let w = sig.merkleSignCommit().value
|
let w = sig.merkleSignCommit().value
|
||||||
gossip.say "*** testShortkeys (2)", "n=", n, " inx=", inx,
|
gossip.say "*** testShortkeys (2)", "n=", n, " inx=", inx,
|
||||||
|
@ -502,7 +502,7 @@ proc testShortKeys*(
|
||||||
"\n R=", w.pp(sig),
|
"\n R=", w.pp(sig),
|
||||||
"\n ", sig.pp(),
|
"\n ", sig.pp(),
|
||||||
"\n",
|
"\n",
|
||||||
"\n pAmk=", sig.db.layersWalkLebal.toSeq.toTable.pp(sig.db),
|
"\n pAmk=", sig.db.layersWalkYek.toSeq.toTable.pp(sig.db),
|
||||||
"\n",
|
"\n",
|
||||||
"\n ----------------",
|
"\n ----------------",
|
||||||
"\n"
|
"\n"
|
||||||
|
|
|
@ -109,7 +109,7 @@ proc schedStow(
|
||||||
): Result[void,AristoError] =
|
): Result[void,AristoError] =
|
||||||
## Scheduled storage
|
## Scheduled storage
|
||||||
let
|
let
|
||||||
layersMeter = db.nLayersVtx + db.nLayersLabel
|
layersMeter = db.nLayersVtx() + db.nLayersKey()
|
||||||
filterMeter = if db.roFilter.isNil: 0
|
filterMeter = if db.roFilter.isNil: 0
|
||||||
else: db.roFilter.sTab.len + db.roFilter.kMap.len
|
else: db.roFilter.sTab.len + db.roFilter.kMap.len
|
||||||
persistent = MaxFilterBulk < max(layersMeter, filterMeter)
|
persistent = MaxFilterBulk < max(layersMeter, filterMeter)
|
||||||
|
@ -557,7 +557,7 @@ proc testTxMergeProofAndKvpList*(
|
||||||
xCheck w.proof.len == proved.merged + proved.dups
|
xCheck w.proof.len == proved.merged + proved.dups
|
||||||
xCheck db.lTab.len == lTabLen
|
xCheck db.lTab.len == lTabLen
|
||||||
xCheck db.nLayersVtx() <= proved.merged + sTabLen
|
xCheck db.nLayersVtx() <= proved.merged + sTabLen
|
||||||
xCheck proved.merged < db.nLayersLebal()
|
xCheck proved.merged < db.nLayersYek()
|
||||||
|
|
||||||
let
|
let
|
||||||
merged = db.mergeList leafs
|
merged = db.mergeList leafs
|
||||||
|
|
|
@ -46,7 +46,24 @@ let
|
||||||
when unittest2DisableParamFiltering:
|
when unittest2DisableParamFiltering:
|
||||||
# Filter out local options and pass on the rest to `unittest2`
|
# Filter out local options and pass on the rest to `unittest2`
|
||||||
proc cmdLineConfig(): tuple[samples: seq[CaptureSpecs]] =
|
proc cmdLineConfig(): tuple[samples: seq[CaptureSpecs]] =
|
||||||
|
## This helper allows to pass additional command line options to the
|
||||||
|
## unit test.
|
||||||
|
##
|
||||||
|
## Example:
|
||||||
|
## ::
|
||||||
|
## nim c -r ...\
|
||||||
|
## -d:unittest2DisableParamFiltering \
|
||||||
|
## ./tests/test_coredb.nim \
|
||||||
|
## --output-level=VERBOSE \
|
||||||
|
## --sample=goerli-lp,goerli-ar
|
||||||
|
## or
|
||||||
|
## ::
|
||||||
|
## nim c ... -d:unittest2DisableParamFiltering ./tests/test_coredb.nim
|
||||||
|
## ./tests/test_coredb.out --output-level=VERBOSE --sample=goerli-ar
|
||||||
|
## ...
|
||||||
|
##
|
||||||
|
## At the moment, only the `--sample=` additional option is provided.
|
||||||
|
##
|
||||||
# Define sample list from the command line (if any)
|
# Define sample list from the command line (if any)
|
||||||
const optPfx = "--sample=" # Custom option with sample list
|
const optPfx = "--sample=" # Custom option with sample list
|
||||||
|
|
||||||
|
@ -182,8 +199,10 @@ proc chainSyncRunner(
|
||||||
capture = bChainCapture;
|
capture = bChainCapture;
|
||||||
dbType = CoreDbType(0);
|
dbType = CoreDbType(0);
|
||||||
ldgType = ldgTypeDefault;
|
ldgType = ldgTypeDefault;
|
||||||
enaLogging = false;
|
profilingOk = false;
|
||||||
lastOneExtra = true;
|
finalDiskCleanUpOk = true;
|
||||||
|
enaLoggingOk = false;
|
||||||
|
lastOneExtraOk = true;
|
||||||
) =
|
) =
|
||||||
|
|
||||||
## Test backend database and ledger
|
## Test backend database and ledger
|
||||||
|
@ -215,9 +234,9 @@ proc chainSyncRunner(
|
||||||
let
|
let
|
||||||
com = initRunnerDB(dbDir, capture, dbType, ldgType)
|
com = initRunnerDB(dbDir, capture, dbType, ldgType)
|
||||||
defer:
|
defer:
|
||||||
com.db.finish(flush = true)
|
com.db.finish(flush = finalDiskCleanUpOk)
|
||||||
#noisy.testChainSyncProfilingPrint numBlocks
|
if profilingOk: noisy.testChainSyncProfilingPrint numBlocks
|
||||||
if persistent: dbDir.flushDbDir
|
if persistent and finalDiskCleanUpOk: dbDir.flushDbDir
|
||||||
|
|
||||||
if noisy:
|
if noisy:
|
||||||
com.db.trackNewApi = true
|
com.db.trackNewApi = true
|
||||||
|
@ -226,7 +245,7 @@ proc chainSyncRunner(
|
||||||
com.db.localDbOnly = true
|
com.db.localDbOnly = true
|
||||||
|
|
||||||
check noisy.testChainSync(filePaths, com, numBlocks,
|
check noisy.testChainSync(filePaths, com, numBlocks,
|
||||||
lastOneExtra=lastOneExtra, enaLogging=enaLogging)
|
lastOneExtra=lastOneExtraOk, enaLogging=enaLoggingOk)
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
# Main function(s)
|
# Main function(s)
|
||||||
|
@ -258,10 +277,13 @@ when isMainModule:
|
||||||
for n,capture in sampleList:
|
for n,capture in sampleList:
|
||||||
noisy.profileSection("@testList #" & $n, state):
|
noisy.profileSection("@testList #" & $n, state):
|
||||||
noisy.chainSyncRunner(
|
noisy.chainSyncRunner(
|
||||||
capture=capture,
|
capture = capture,
|
||||||
#dbType = ...,
|
#dbType = ..,
|
||||||
ldgType=LedgerCache,
|
ldgType=LedgerCache,
|
||||||
#enaLogging = true
|
#profilingOk = ..,
|
||||||
|
finalDiskCleanUpOk = false,
|
||||||
|
#enaLoggingOk = ..,
|
||||||
|
#lastOneExtraOk = ..,
|
||||||
)
|
)
|
||||||
|
|
||||||
noisy.say "***", "total elapsed: ", state[0].pp, " sections: ", state[1]
|
noisy.say "***", "total elapsed: ", state[0].pp, " sections: ", state[1]
|
||||||
|
|
|
@ -92,6 +92,14 @@ let
|
||||||
|
|
||||||
|
|
||||||
# To be compared against the proof-of-concept implementation as reference
|
# To be compared against the proof-of-concept implementation as reference
|
||||||
|
legaTest0* = CaptureSpecs(
|
||||||
|
builtIn: true,
|
||||||
|
name: ariTest0.name.replace("-am", "-lm"),
|
||||||
|
network: ariTest0.network,
|
||||||
|
files: ariTest0.files,
|
||||||
|
numBlocks: ariTest0.numBlocks,
|
||||||
|
dbType: LegacyDbMemory)
|
||||||
|
|
||||||
legaTest1* = CaptureSpecs(
|
legaTest1* = CaptureSpecs(
|
||||||
builtIn: true,
|
builtIn: true,
|
||||||
name: ariTest1.name.replace("-ar", "-lp"),
|
name: ariTest1.name.replace("-ar", "-lp"),
|
||||||
|
@ -112,6 +120,6 @@ let
|
||||||
allSamples* = [
|
allSamples* = [
|
||||||
bulkTest0, bulkTest1, bulkTest2, bulkTest3,
|
bulkTest0, bulkTest1, bulkTest2, bulkTest3,
|
||||||
ariTest0, ariTest1, ariTest2,
|
ariTest0, ariTest1, ariTest2,
|
||||||
legaTest1, legaTest2]
|
legaTest0, legaTest1, legaTest2]
|
||||||
|
|
||||||
# End
|
# End
|
||||||
|
|
Loading…
Reference in New Issue