trie: use explicit private flags (fixes Go 1.5 reflection issue).

This commit is contained in:
Péter Szilágyi 2016-10-14 12:48:41 +03:00
parent b74240ff76
commit 543ed15f91
4 changed files with 23 additions and 20 deletions

View file

@ -78,16 +78,16 @@ func (h *hasher) hash(n node, db DatabaseWriter, force bool) (node, node, error)
switch cached := cached.(type) { switch cached := cached.(type) {
case *shortNode: case *shortNode:
cached = cached.copy() cached = cached.copy()
cached.hash = hash cached.flags.hash = hash
if db != nil { if db != nil {
cached.dirty = false cached.flags.dirty = false
} }
return hashed, cached, nil return hashed, cached, nil
case *fullNode: case *fullNode:
cached = cached.copy() cached = cached.copy()
cached.hash = hash cached.flags.hash = hash
if db != nil { if db != nil {
cached.dirty = false cached.flags.dirty = false
} }
return hashed, cached, nil return hashed, cached, nil
} }

View file

@ -156,7 +156,7 @@ func (it *NodeIterator) step() error {
for parent.child++; parent.child < len(node.Children); parent.child++ { for parent.child++; parent.child < len(node.Children); parent.child++ {
if current := node.Children[parent.child]; current != nil { if current := node.Children[parent.child]; current != nil {
it.stack = append(it.stack, &nodeIteratorState{ it.stack = append(it.stack, &nodeIteratorState{
hash: common.BytesToHash(node.hash), hash: common.BytesToHash(node.flags.hash),
node: current, node: current,
parent: ancestor, parent: ancestor,
child: -1, child: -1,
@ -171,7 +171,7 @@ func (it *NodeIterator) step() error {
} }
parent.child++ parent.child++
it.stack = append(it.stack, &nodeIteratorState{ it.stack = append(it.stack, &nodeIteratorState{
hash: common.BytesToHash(node.hash), hash: common.BytesToHash(node.flags.hash),
node: node.Val, node: node.Val,
parent: ancestor, parent: ancestor,
child: -1, child: -1,

View file

@ -36,12 +36,12 @@ type node interface {
type ( type (
fullNode struct { fullNode struct {
Children [17]node // Actual trie node data to encode/decode (needs custom encoder) Children [17]node // Actual trie node data to encode/decode (needs custom encoder)
nodeFlag flags nodeFlag
} }
shortNode struct { shortNode struct {
Key []byte Key []byte
Val node Val node
nodeFlag flags nodeFlag
} }
hashNode []byte hashNode []byte
valueNode []byte valueNode []byte
@ -63,7 +63,7 @@ type nodeFlag struct {
} }
// canUnload tells whether a node can be unloaded. // canUnload tells whether a node can be unloaded.
func (n nodeFlag) canUnload(cachegen, cachelimit uint16) bool { func (n *nodeFlag) canUnload(cachegen, cachelimit uint16) bool {
var dist uint16 var dist uint16
if n.gen > cachegen { if n.gen > cachegen {
dist = n.gen - cachegen dist = n.gen - cachegen
@ -73,10 +73,13 @@ func (n nodeFlag) canUnload(cachegen, cachelimit uint16) bool {
return !n.dirty && dist > cachelimit return !n.dirty && dist > cachelimit
} }
func (n *fullNode) canUnload(gen, limit uint16) bool { return (&n.flags).canUnload(gen, limit) }
func (n *shortNode) canUnload(gen, limit uint16) bool { return (&n.flags).canUnload(gen, limit) }
func (n hashNode) canUnload(uint16, uint16) bool { return false } func (n hashNode) canUnload(uint16, uint16) bool { return false }
func (n valueNode) canUnload(uint16, uint16) bool { return false } func (n valueNode) canUnload(uint16, uint16) bool { return false }
func (n nodeFlag) cache() (hashNode, bool) { return n.hash, n.dirty } func (n *fullNode) cache() (hashNode, bool) { return n.flags.hash, n.flags.dirty }
func (n *shortNode) cache() (hashNode, bool) { return n.flags.hash, n.flags.dirty }
func (n hashNode) cache() (hashNode, bool) { return nil, true } func (n hashNode) cache() (hashNode, bool) { return nil, true }
func (n valueNode) cache() (hashNode, bool) { return nil, true } func (n valueNode) cache() (hashNode, bool) { return nil, true }
@ -159,7 +162,7 @@ func decodeShort(hash, buf, elems []byte) (node, error) {
} }
func decodeFull(hash, buf, elems []byte) (*fullNode, error) { func decodeFull(hash, buf, elems []byte) (*fullNode, error) {
n := &fullNode{nodeFlag: nodeFlag{hash: hash}} n := &fullNode{flags: nodeFlag{hash: hash}}
for i := 0; i < 16; i++ { for i := 0; i < 16; i++ {
cld, rest, err := decodeRef(elems) cld, rest, err := decodeRef(elems)
if err != nil { if err != nil {

View file

@ -226,7 +226,7 @@ func (t *Trie) insert(n node, prefix, key []byte, value node) (bool, node, error
return true, &shortNode{n.Key, nn, t.newFlag()}, nil return true, &shortNode{n.Key, nn, t.newFlag()}, nil
} }
// Otherwise branch out at the index where they differ. // Otherwise branch out at the index where they differ.
branch := &fullNode{nodeFlag: t.newFlag()} branch := &fullNode{flags: t.newFlag()}
var err error var err error
_, branch.Children[n.Key[matchlen]], err = t.insert(nil, append(prefix, n.Key[:matchlen+1]...), n.Key[matchlen+1:], n.Val) _, branch.Children[n.Key[matchlen]], err = t.insert(nil, append(prefix, n.Key[:matchlen+1]...), n.Key[matchlen+1:], n.Val)
if err != nil { if err != nil {
@ -249,7 +249,7 @@ func (t *Trie) insert(n node, prefix, key []byte, value node) (bool, node, error
return false, n, err return false, n, err
} }
n = n.copy() n = n.copy()
n.Children[key[0]], n.hash, n.dirty = nn, nil, true n.Children[key[0]], n.flags.hash, n.flags.dirty = nn, nil, true
return true, n, nil return true, n, nil
case nil: case nil:
@ -333,7 +333,7 @@ func (t *Trie) delete(n node, prefix, key []byte) (bool, node, error) {
return false, n, err return false, n, err
} }
n = n.copy() n = n.copy()
n.Children[key[0]], n.hash, n.dirty = nn, nil, true n.Children[key[0]], n.flags.hash, n.flags.dirty = nn, nil, true
// Check how many non-nil entries are left after deleting and // Check how many non-nil entries are left after deleting and
// reduce the full node to a short node if only one entry is // reduce the full node to a short node if only one entry is