Add computeHashes at virtual tree

This commit is contained in:
2021-05-17 22:16:08 +02:00
parent e13b09215e
commit 66f6ae14bb
2 changed files with 118 additions and 6 deletions

73
vt.go
View File

@@ -2,7 +2,6 @@
// without computing any hash. With the idea of once all the leafs are placed in
// their positions, the hashes can be computed, avoiding computing a node hash
// more than one time.
//nolint:unused,deadcode
package arbo
import (
@@ -18,7 +17,7 @@ type node struct {
k []byte
v []byte
path []bool
// h []byte
h []byte
}
type params struct {
@@ -60,6 +59,18 @@ func (t *vt) add(k, v []byte) error {
return nil
}
// computeHashes should be called after all the vt.add is used, once all the
// leafs are in the tree
func (t *vt) computeHashes() ([][2][]byte, error) {
var pairs [][2][]byte
var err error
pairs, err = t.root.computeHashes(t.params, pairs)
if err != nil {
return pairs, err
}
return pairs, nil
}
func newLeafNode(p *params, k, v []byte) *node {
keyPath := make([]byte, p.hashFunction.Len())
copy(keyPath[:], k)
@@ -150,10 +161,8 @@ func (n *node) downUntilDivergence(p *params, currLvl int, oldLeaf, newLeaf *nod
return fmt.Errorf("max virtual level %d", currLvl)
}
// if oldLeaf.path[currLvl+1] != newLeaf.path[currLvl+1] {
if oldLeaf.path[currLvl] != newLeaf.path[currLvl] {
// reached divergence in next level
// if newLeaf.path[currLvl+1] {
if newLeaf.path[currLvl] {
n.l = oldLeaf
n.r = newLeaf
@@ -181,10 +190,60 @@ func (n *node) downUntilDivergence(p *params, currLvl int, oldLeaf, newLeaf *nod
return nil
}
func (n *node) computeHashes() ([]kv, error) {
return nil, nil
// returns an array of key-values to store in the db
func (n *node) computeHashes(p *params, pairs [][2][]byte) ([][2][]byte, error) {
if pairs == nil {
pairs = [][2][]byte{}
}
var err error
t := n.typ()
switch t {
case vtLeaf:
leafKey, leafValue, err := newLeafValue(p.hashFunction, n.k, n.v)
if err != nil {
return pairs, err
}
n.h = leafKey
kv := [2][]byte{leafKey, leafValue}
pairs = append(pairs, kv)
case vtMid:
if n.l != nil {
pairs, err = n.l.computeHashes(p, pairs)
if err != nil {
return pairs, err
}
} else {
n.l = &node{
h: p.emptyHash,
}
}
if n.r != nil {
pairs, err = n.r.computeHashes(p, pairs)
if err != nil {
return pairs, err
}
} else {
n.r = &node{
h: p.emptyHash,
}
}
// once the sub nodes are computed, can compute the current node
// hash
k, v, err := newIntermediate(p.hashFunction, n.l.h, n.r.h)
if err != nil {
return nil, err
}
n.h = k
kv := [2][]byte{k, v}
pairs = append(pairs, kv)
default:
return nil, fmt.Errorf("ERR TMP") // TODO
}
return pairs, nil
}
//nolint:unused
func (t *vt) graphviz(w io.Writer) error {
fmt.Fprintf(w, `digraph hierarchy {
node [fontname=Monospace,fontsize=10,shape=box]
@@ -196,6 +255,7 @@ node [fontname=Monospace,fontsize=10,shape=box]
return nil
}
//nolint:unused
func (n *node) graphviz(w io.Writer, p *params, nEmpties int) (int, error) {
nChars := 4 // TODO move to global constant
if n == nil {
@@ -254,6 +314,7 @@ func (n *node) graphviz(w io.Writer, p *params, nEmpties int) (int, error) {
return nEmpties, nil
}
//nolint:unused
func (t *vt) printGraphviz() error {
w := bytes.NewBufferString("")
fmt.Fprintf(w,