clean up vertex delete (#2644)

avoid allocating and updating the trie twice when the branch is fully
removed
This commit is contained in:
Jacek Sieka 2024-09-20 10:31:29 +02:00 committed by GitHub
parent b4b4d16729
commit 7a15aa2a3a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 17 additions and 17 deletions

View File

@ -25,10 +25,13 @@ import
# Private heplers # Private heplers
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
proc branchStillNeeded(vtx: VertexRef): Result[int,void] = proc branchStillNeeded(vtx: VertexRef, removed: int): Result[int,void] =
## Returns the nibble if there is only one reference left. ## Returns the nibble if there is only one reference left.
var nibble = -1 var nibble = -1
for n in 0 .. 15: for n in 0 .. 15:
if n == removed:
continue
if vtx.bVid[n].isValid: if vtx.bVid[n].isValid:
if 0 <= nibble: if 0 <= nibble:
return ok(-1) return ok(-1)
@ -61,31 +64,23 @@ proc deleteImpl(
# leaves to update # leaves to update
return ok(nil) return ok(nil)
# Get current `Branch` vertex `br` if hike.legs[^2].wp.vtx.vType != Branch:
let br = block:
var wp = hike.legs[^2].wp
wp.vtx = wp.vtx.dup # make sure that layers are not impliciteley modified
wp
if br.vtx.vType != Branch:
return err(DelBranchExpexted) return err(DelBranchExpexted)
# Unlink child vertex from structural table # Get current `Branch` vertex `br`
br.vtx.bVid[hike.legs[^2].nibble] = VertexID(0) let
db.layersPutVtx((hike.root, br.vid), br.vtx) br = hike.legs[^2].wp
nbl = br.vtx.branchStillNeeded(hike.legs[^2].nibble).valueOr:
return err(DelBranchWithoutRefs)
# Clear all Merkle hash keys up to the root key # Clear all Merkle hash keys up to the root key
for n in 0 .. hike.legs.len - 2: for n in 0 .. hike.legs.len - 2:
let vid = hike.legs[n].wp.vid let vid = hike.legs[n].wp.vid
db.layersResKey((hike.root, vid)) db.layersResKey((hike.root, vid))
let nbl = block:
let rc = br.vtx.branchStillNeeded()
if rc.isErr:
return err(DelBranchWithoutRefs)
rc.value
if 0 <= nbl: if 0 <= nbl:
# Branch has only one entry - convert it to a leaf or join with parent # Branch has only one entry - move that entry to where the branch was and
# update its path
# Get child vertex (there must be one after a `Branch` node) # Get child vertex (there must be one after a `Branch` node)
let let
@ -118,6 +113,11 @@ proc deleteImpl(
else: else:
ok(nil) ok(nil)
else: else:
# Clear the removed leaf from the branch (that still contains other children)
let brDup = br.vtx.dup
brDup.bVid[hike.legs[^2].nibble] = VertexID(0)
db.layersPutVtx((hike.root, br.vid), brDup)
ok(nil) ok(nil)
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------