github.com/turingchain2020/turingchain@v1.1.21/system/store/mavl/db/node.go (about)

     1  // Copyright Turing Corp. 2018 All Rights Reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package mavl
     6  
     7  import (
     8  	"bytes"
     9  
    10  	"fmt"
    11  
    12  	"github.com/turingchain2020/turingchain/common"
    13  	"github.com/turingchain2020/turingchain/types"
    14  	farm "github.com/dgryski/go-farm"
    15  	"github.com/golang/protobuf/proto"
    16  )
    17  
    18  // Node merkle avl Node
    19  type Node struct {
    20  	key        []byte
    21  	value      []byte
    22  	height     int32
    23  	size       int32
    24  	hash       []byte
    25  	leftHash   []byte
    26  	leftNode   *Node
    27  	rightHash  []byte
    28  	rightNode  *Node
    29  	parentNode *Node
    30  	persisted  bool
    31  }
    32  
    33  // NewNode 创建节点;保存数据的是叶子节点
    34  func NewNode(key []byte, value []byte) *Node {
    35  	return &Node{
    36  		key:    key,
    37  		value:  value,
    38  		height: 0,
    39  		size:   1,
    40  	}
    41  }
    42  
    43  // MakeNode 从数据库中读取数据,创建Node
    44  // NOTE: The hash is not saved or set.  The caller should set the hash afterwards.
    45  // (Presumably the caller already has the hash)
    46  func MakeNode(buf []byte, t *Tree) (node *Node, err error) {
    47  	node = &Node{}
    48  
    49  	var storeNode types.StoreNode
    50  
    51  	err = proto.Unmarshal(buf, &storeNode)
    52  	if err != nil {
    53  		return nil, err
    54  	}
    55  
    56  	// node header
    57  	node.height = storeNode.Height
    58  	node.size = storeNode.Size
    59  	node.key = storeNode.Key
    60  
    61  	//leaf(叶子节点保存数据)
    62  	if node.height == 0 {
    63  		node.value = storeNode.Value
    64  	} else {
    65  		node.leftHash = storeNode.LeftHash
    66  		node.rightHash = storeNode.RightHash
    67  	}
    68  	return node, nil
    69  }
    70  
    71  func (node *Node) _copy() *Node {
    72  	if node.height == 0 {
    73  		panic("Why are you copying a value node?")
    74  	}
    75  	return &Node{
    76  		key:        node.key,
    77  		height:     node.height,
    78  		size:       node.size,
    79  		hash:       nil, // Going to be mutated anyways.
    80  		leftHash:   node.leftHash,
    81  		leftNode:   node.leftNode,
    82  		rightHash:  node.rightHash,
    83  		rightNode:  node.rightNode,
    84  		parentNode: node.parentNode,
    85  		persisted:  false, // Going to be mutated, so it can't already be persisted.
    86  	}
    87  }
    88  
    89  func (node *Node) has(t *Tree, key []byte) (has bool) {
    90  	if bytes.Equal(node.key, key) {
    91  		return true
    92  	}
    93  	if node.height == 0 {
    94  		return false
    95  	}
    96  	if bytes.Compare(key, node.key) < 0 {
    97  		return node.getLeftNode(t).has(t, key)
    98  	}
    99  	return node.getRightNode(t).has(t, key)
   100  }
   101  
   102  func (node *Node) get(t *Tree, key []byte) (index int32, value []byte, exists bool) {
   103  	if node.height == 0 {
   104  		cmp := bytes.Compare(node.key, key)
   105  		if cmp == 0 {
   106  			return 0, node.value, true
   107  		} else if cmp == -1 {
   108  			return 1, nil, false
   109  		} else {
   110  			return 0, nil, false
   111  		}
   112  	}
   113  	if bytes.Compare(key, node.key) < 0 {
   114  		return node.getLeftNode(t).get(t, key)
   115  	}
   116  	rightNode := node.getRightNode(t)
   117  	index, value, exists = rightNode.get(t, key)
   118  	index += node.size - rightNode.size
   119  	return index, value, exists
   120  }
   121  
   122  func (node *Node) getHash(t *Tree, key []byte) (index int32, hash []byte, exists bool) {
   123  	if node.height == 0 {
   124  		cmp := bytes.Compare(node.key, key)
   125  		if cmp == 0 {
   126  			return 0, node.hash, true
   127  		} else if cmp == -1 {
   128  			return 1, nil, false
   129  		} else {
   130  			return 0, nil, false
   131  		}
   132  	}
   133  	if bytes.Compare(key, node.key) < 0 {
   134  		return node.getLeftNode(t).getHash(t, key)
   135  	}
   136  	rightNode := node.getRightNode(t)
   137  	index, hash, exists = rightNode.getHash(t, key)
   138  	index += node.size - rightNode.size
   139  	return index, hash, exists
   140  }
   141  
   142  //通过index获取leaf节点信息
   143  func (node *Node) getByIndex(t *Tree, index int32) (key []byte, value []byte) {
   144  	if node.height == 0 {
   145  		if index == 0 {
   146  			return node.key, node.value
   147  		}
   148  		panic("getByIndex asked for invalid index")
   149  	} else {
   150  		// TODO: could improve this by storing the sizes as well as left/right hash.
   151  		leftNode := node.getLeftNode(t)
   152  		if index < leftNode.size {
   153  			return leftNode.getByIndex(t, index)
   154  		}
   155  		return node.getRightNode(t).getByIndex(t, index-leftNode.size)
   156  	}
   157  }
   158  
   159  // Hash 计算节点的hash
   160  func (node *Node) Hash(t *Tree) []byte {
   161  	if node.hash != nil {
   162  		return node.hash
   163  	}
   164  
   165  	//leafnode
   166  	if node.height == 0 {
   167  		var leafnode types.LeafNode
   168  		leafnode.Height = node.height
   169  		leafnode.Key = node.key
   170  		leafnode.Size = node.size
   171  		leafnode.Value = node.value
   172  		node.hash = leafnode.Hash()
   173  
   174  		if t.config != nil && t.config.EnableMavlPrefix && node.height != t.root.height {
   175  			hashKey := genPrefixHashKey(node, t.blockHeight)
   176  			hashKey = append(hashKey, node.hash...)
   177  			node.hash = hashKey
   178  		}
   179  	} else {
   180  		var innernode types.InnerNode
   181  		innernode.Height = node.height
   182  		innernode.Size = node.size
   183  
   184  		// left
   185  		if node.leftNode != nil {
   186  			leftHash := node.leftNode.Hash(t)
   187  			node.leftHash = leftHash
   188  		}
   189  		if node.leftHash == nil {
   190  			panic("node.leftHash was nil in writeHashBytes")
   191  		}
   192  		innernode.LeftHash = node.leftHash
   193  
   194  		// right
   195  		if node.rightNode != nil {
   196  			rightHash := node.rightNode.Hash(t)
   197  			node.rightHash = rightHash
   198  		}
   199  		if node.rightHash == nil {
   200  			panic("node.rightHash was nil in writeHashBytes")
   201  		}
   202  		innernode.RightHash = node.rightHash
   203  		node.hash = innernode.Hash()
   204  		if t.config != nil && t.config.EnableMavlPrefix && node.height != t.root.height {
   205  			hashKey := genPrefixHashKey(node, t.blockHeight)
   206  			hashKey = append(hashKey, node.hash...)
   207  			node.hash = hashKey
   208  		}
   209  
   210  		if t.config != nil && t.config.EnableMavlPrune {
   211  			//加入parentNode
   212  			if node.leftNode != nil && node.leftNode.height != t.root.height {
   213  				node.leftNode.parentNode = node
   214  			}
   215  			if node.rightNode != nil && node.rightNode.height != t.root.height {
   216  				node.rightNode.parentNode = node
   217  			}
   218  		}
   219  	}
   220  
   221  	if t.config != nil && t.config.EnableMemTree {
   222  		updateLocalMemTree(t, node)
   223  	}
   224  	return node.hash
   225  }
   226  
   227  // NOTE: clears leftNode/rigthNode recursively sets hashes recursively
   228  func (node *Node) save(t *Tree) int64 {
   229  	if node.hash == nil {
   230  		node.hash = node.Hash(t)
   231  	}
   232  	if node.persisted {
   233  		return 0
   234  	}
   235  	var leftsaveNodeNo int64
   236  	var rightsaveNodeNo int64
   237  
   238  	// save children
   239  	if node.leftNode != nil {
   240  		leftsaveNodeNo = node.leftNode.save(t)
   241  		node.leftNode = nil
   242  	}
   243  	if node.rightNode != nil {
   244  		rightsaveNodeNo = node.rightNode.save(t)
   245  		node.rightNode = nil
   246  	}
   247  
   248  	// save node
   249  	t.ndb.SaveNode(t, node)
   250  	return leftsaveNodeNo + rightsaveNodeNo + 1
   251  }
   252  
   253  // 保存root节点hash以及区块高度
   254  func (node *Node) saveRootHash(t *Tree) (err error) {
   255  	if node.hash == nil || t.ndb == nil || t.ndb.db == nil {
   256  		return
   257  	}
   258  	h := &types.Int64{}
   259  	h.Data = t.blockHeight
   260  	value, err := proto.Marshal(h)
   261  	if err != nil {
   262  		return err
   263  	}
   264  	t.ndb.batch.Set(genRootHashHeight(t.blockHeight, node.hash), value)
   265  	return nil
   266  }
   267  
   268  //将内存中的node转换成存储到db中的格式
   269  func (node *Node) storeNode(t *Tree) []byte {
   270  	var storeNode types.StoreNode
   271  
   272  	// node header
   273  	storeNode.Height = node.height
   274  	storeNode.Size = node.size
   275  	storeNode.Key = node.key
   276  	storeNode.Value = nil
   277  	storeNode.LeftHash = nil
   278  	storeNode.RightHash = nil
   279  
   280  	//leafnode
   281  	if node.height == 0 {
   282  		if (t.config == nil) ||
   283  			(t.config != nil && !t.config.EnableMVCC) {
   284  			storeNode.Value = node.value
   285  		}
   286  	} else {
   287  		// left
   288  		if node.leftHash == nil {
   289  			panic("node.leftHash was nil in writePersistBytes")
   290  		}
   291  		storeNode.LeftHash = node.leftHash
   292  
   293  		// right
   294  		if node.rightHash == nil {
   295  			panic("node.rightHash was nil in writePersistBytes")
   296  		}
   297  		storeNode.RightHash = node.rightHash
   298  	}
   299  	storeNodebytes, err := proto.Marshal(&storeNode)
   300  	if err != nil {
   301  		panic(err)
   302  	}
   303  	return storeNodebytes
   304  }
   305  
   306  //从指定node开始插入一个新的node,updated表示是否有叶子结点的value更新
   307  func (node *Node) set(t *Tree, key []byte, value []byte) (newSelf *Node, updated bool) {
   308  	if node.height == 0 {
   309  		cmp := bytes.Compare(key, node.key)
   310  		if cmp < 0 {
   311  			return &Node{
   312  				key:       node.key,
   313  				height:    1,
   314  				size:      2,
   315  				leftNode:  NewNode(key, value),
   316  				rightNode: node,
   317  			}, false
   318  		} else if cmp == 0 {
   319  			removeOrphan(t, node)
   320  			return NewNode(key, value), true
   321  		} else {
   322  			return &Node{
   323  				key:       key,
   324  				height:    1,
   325  				size:      2,
   326  				leftNode:  node,
   327  				rightNode: NewNode(key, value),
   328  			}, false
   329  		}
   330  	} else {
   331  		removeOrphan(t, node)
   332  		node = node._copy()
   333  		if bytes.Compare(key, node.key) < 0 {
   334  			node.leftNode, updated = node.getLeftNode(t).set(t, key, value)
   335  			node.leftHash = nil // leftHash is yet unknown
   336  		} else {
   337  			node.rightNode, updated = node.getRightNode(t).set(t, key, value)
   338  			node.rightHash = nil // rightHash is yet unknown
   339  		}
   340  		if updated {
   341  			return node, updated
   342  		}
   343  		//有节点插入,需要重新计算height和size以及tree的平衡
   344  		node.calcHeightAndSize(t)
   345  		return node.balance(t), updated
   346  	}
   347  }
   348  
   349  func (node *Node) getLeftNode(t *Tree) *Node {
   350  	if node.leftNode != nil {
   351  		return node.leftNode
   352  	}
   353  	leftNode, err := t.ndb.GetNode(t, node.leftHash)
   354  	if err != nil {
   355  		panic(fmt.Sprintln("left hash", common.ToHex(node.leftHash), err)) //数据库已经损坏
   356  	}
   357  	return leftNode
   358  }
   359  
   360  func (node *Node) getRightNode(t *Tree) *Node {
   361  	if node.rightNode != nil {
   362  		return node.rightNode
   363  	}
   364  	rightNode, err := t.ndb.GetNode(t, node.rightHash)
   365  	if err != nil {
   366  		panic(fmt.Sprintln("right hash", common.ToHex(node.rightHash), err))
   367  	}
   368  	return rightNode
   369  }
   370  
   371  // NOTE: overwrites node TODO: optimize balance & rotate
   372  func (node *Node) rotateRight(t *Tree) *Node {
   373  	node = node._copy()
   374  	l := node.getLeftNode(t)
   375  	removeOrphan(t, l)
   376  	_l := l._copy()
   377  
   378  	_lrHash, _lrCached := _l.rightHash, _l.rightNode
   379  	_l.rightHash, _l.rightNode = node.hash, node
   380  	node.leftHash, node.leftNode = _lrHash, _lrCached
   381  
   382  	node.calcHeightAndSize(t)
   383  	_l.calcHeightAndSize(t)
   384  
   385  	return _l
   386  }
   387  
   388  // NOTE: overwrites node TODO: optimize balance & rotate
   389  func (node *Node) rotateLeft(t *Tree) *Node {
   390  	node = node._copy()
   391  	r := node.getRightNode(t)
   392  	removeOrphan(t, r)
   393  	_r := r._copy()
   394  
   395  	_rlHash, _rlCached := _r.leftHash, _r.leftNode
   396  	_r.leftHash, _r.leftNode = node.hash, node
   397  	node.rightHash, node.rightNode = _rlHash, _rlCached
   398  
   399  	node.calcHeightAndSize(t)
   400  	_r.calcHeightAndSize(t)
   401  
   402  	return _r
   403  }
   404  
   405  // NOTE: mutates height and size
   406  func (node *Node) calcHeightAndSize(t *Tree) {
   407  	leftN := node.getLeftNode(t)
   408  	rightN := node.getRightNode(t)
   409  	node.height = maxInt32(leftN.height, rightN.height) + 1
   410  	node.size = leftN.size + rightN.size
   411  }
   412  
   413  func (node *Node) calcBalance(t *Tree) int {
   414  	return int(node.getLeftNode(t).height) - int(node.getRightNode(t).height)
   415  }
   416  
   417  // NOTE: assumes that node can be modified TODO: optimize balance & rotate
   418  func (node *Node) balance(t *Tree) (newSelf *Node) {
   419  	if node.persisted {
   420  		panic("Unexpected balance() call on persisted node")
   421  	}
   422  	balance := node.calcBalance(t)
   423  	if balance > 1 {
   424  		if node.getLeftNode(t).calcBalance(t) >= 0 {
   425  			// Left Left Case
   426  			return node.rotateRight(t)
   427  		}
   428  		// Left Right Case
   429  		// node = node._copy()
   430  		left := node.getLeftNode(t)
   431  		removeOrphan(t, left)
   432  		node.leftHash, node.leftNode = nil, left.rotateLeft(t)
   433  		//node.calcHeightAndSize()
   434  		return node.rotateRight(t)
   435  	}
   436  	if balance < -1 {
   437  		if node.getRightNode(t).calcBalance(t) <= 0 {
   438  			// Right Right Case
   439  			return node.rotateLeft(t)
   440  		}
   441  		// Right Left Case
   442  		// node = node._copy()
   443  		right := node.getRightNode(t)
   444  		removeOrphan(t, right)
   445  		node.rightHash, node.rightNode = nil, right.rotateRight(t)
   446  		//node.calcHeightAndSize()
   447  		return node.rotateLeft(t)
   448  	}
   449  	// Nothing changed
   450  	return node
   451  }
   452  
   453  // newHash/newNode: The new hash or node to replace node after remove.
   454  // newKey: new leftmost leaf key for tree after successfully removing 'key' if changed.
   455  // value: removed value.
   456  func (node *Node) remove(t *Tree, key []byte) (
   457  	newHash []byte, newNode *Node, newKey []byte, value []byte, removed bool) {
   458  	if node.height == 0 {
   459  		if bytes.Equal(key, node.key) {
   460  			removeOrphan(t, node)
   461  			return nil, nil, nil, node.value, true
   462  		}
   463  		return node.hash, node, nil, nil, false
   464  	}
   465  	if bytes.Compare(key, node.key) < 0 {
   466  		var newLeftHash []byte
   467  		var newLeftNode *Node
   468  		newLeftHash, newLeftNode, newKey, value, removed = node.getLeftNode(t).remove(t, key)
   469  		if !removed {
   470  			return node.hash, node, nil, value, false
   471  		} else if newLeftHash == nil && newLeftNode == nil { // left node held value, was removed
   472  			return node.rightHash, node.rightNode, node.key, value, true
   473  		}
   474  		removeOrphan(t, node)
   475  		node = node._copy()
   476  		node.leftHash, node.leftNode = newLeftHash, newLeftNode
   477  		node.calcHeightAndSize(t)
   478  		node = node.balance(t)
   479  		return node.hash, node, newKey, value, true
   480  	}
   481  	var newRightHash []byte
   482  	var newRightNode *Node
   483  	newRightHash, newRightNode, newKey, value, removed = node.getRightNode(t).remove(t, key)
   484  	if !removed {
   485  		return node.hash, node, nil, value, false
   486  	} else if newRightHash == nil && newRightNode == nil { // right node held value, was removed
   487  		return node.leftHash, node.leftNode, nil, value, true
   488  	}
   489  	removeOrphan(t, node)
   490  	node = node._copy()
   491  	node.rightHash, node.rightNode = newRightHash, newRightNode
   492  	if newKey != nil {
   493  		node.key = newKey
   494  	}
   495  	node.calcHeightAndSize(t)
   496  	node = node.balance(t)
   497  	return node.hash, node, nil, value, true
   498  }
   499  
   500  func removeOrphan(t *Tree, node *Node) {
   501  	if !node.persisted {
   502  		return
   503  	}
   504  	if t.ndb == nil {
   505  		return
   506  	}
   507  	if t != nil && t.config != nil && t.config.EnableMemTree {
   508  		t.obsoleteNode[uintkey(farm.Hash64(node.hash))] = struct{}{}
   509  	}
   510  	t.ndb.RemoveNode(t, node)
   511  }
   512  
   513  // 迭代整个树
   514  func (node *Node) traverse(t *Tree, ascending bool, cb func(*Node) bool) bool {
   515  	return node.traverseInRange(t, nil, nil, ascending, false, 0, func(node *Node, depth uint8) bool {
   516  		return cb(node)
   517  	})
   518  }
   519  
   520  func (node *Node) traverseWithDepth(t *Tree, ascending bool, cb func(*Node, uint8) bool) bool {
   521  	return node.traverseInRange(t, nil, nil, ascending, false, 0, cb)
   522  }
   523  
   524  func (node *Node) traverseInRange(t *Tree, start, end []byte, ascending bool, inclusive bool, depth uint8, cb func(*Node, uint8) bool) bool {
   525  	afterStart := start == nil || bytes.Compare(start, node.key) <= 0
   526  	beforeEnd := end == nil || bytes.Compare(node.key, end) < 0
   527  	if inclusive {
   528  		beforeEnd = end == nil || bytes.Compare(node.key, end) <= 0
   529  	}
   530  
   531  	stop := false
   532  	if afterStart && beforeEnd {
   533  		// IterateRange ignores this if not leaf
   534  		stop = cb(node, depth)
   535  	}
   536  	if stop {
   537  		return stop
   538  	}
   539  	if node.height == 0 {
   540  		return stop
   541  	}
   542  
   543  	if ascending {
   544  		// check lower nodes, then higher
   545  		if afterStart {
   546  			stop = node.getLeftNode(t).traverseInRange(t, start, end, ascending, inclusive, depth+1, cb)
   547  		}
   548  		if stop {
   549  			return stop
   550  		}
   551  		if beforeEnd {
   552  			stop = node.getRightNode(t).traverseInRange(t, start, end, ascending, inclusive, depth+1, cb)
   553  		}
   554  	} else {
   555  		// check the higher nodes first
   556  		if beforeEnd {
   557  			stop = node.getRightNode(t).traverseInRange(t, start, end, ascending, inclusive, depth+1, cb)
   558  		}
   559  		if stop {
   560  			return stop
   561  		}
   562  		if afterStart {
   563  			stop = node.getLeftNode(t).traverseInRange(t, start, end, ascending, inclusive, depth+1, cb)
   564  		}
   565  	}
   566  
   567  	return stop
   568  }
   569  
   570  // Only used in testing...
   571  func (node *Node) lmd(t *Tree) *Node {
   572  	if node.height == 0 {
   573  		return node
   574  	}
   575  	return node.getLeftNode(t).lmd(t)
   576  }
   577  
   578  // Only used in testing...
   579  func (node *Node) rmd(t *Tree) *Node {
   580  	if node.height == 0 {
   581  		return node
   582  	}
   583  	return node.getRightNode(t).rmd(t)
   584  }