github.com/ledgerwatch/erigon-lib@v1.0.0/bptree/node.go (about)

     1  /*
     2     Copyright 2022 Erigon contributors
     3  
     4     Licensed under the Apache License, Version 2.0 (the "License");
     5     you may not use this file except in compliance with the License.
     6     You may obtain a copy of the License at
     7  
     8         http://www.apache.org/licenses/LICENSE-2.0
     9  
    10     Unless required by applicable law or agreed to in writing, software
    11     distributed under the License is distributed on an "AS IS" BASIS,
    12     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13     See the License for the specific language governing permissions and
    14     limitations under the License.
    15  */
    16  
    17  package bptree
    18  
    19  import (
    20  	"fmt"
    21  	"strings"
    22  	"unsafe"
    23  )
    24  
    25  type Keys []Felt
    26  
    27  func (keys Keys) Len() int { return len(keys) }
    28  
    29  func (keys Keys) Less(i, j int) bool { return keys[i] < keys[j] }
    30  
    31  func (keys Keys) Swap(i, j int) { keys[i], keys[j] = keys[j], keys[i] }
    32  
    33  func (keys Keys) Contains(key Felt) bool {
    34  	for _, k := range keys {
    35  		if k == key {
    36  			return true
    37  		}
    38  	}
    39  	return false
    40  }
    41  
    42  func (keys Keys) String() string {
    43  	b := strings.Builder{}
    44  	for i, k := range keys {
    45  		fmt.Fprintf(&b, "%v", k)
    46  		if i != len(keys)-1 {
    47  			fmt.Fprintf(&b, " ")
    48  		}
    49  	}
    50  	return b.String()
    51  }
    52  
    53  type KeyValues struct {
    54  	keys   []*Felt
    55  	values []*Felt
    56  }
    57  
    58  func (kv KeyValues) Len() int { return len(kv.keys) }
    59  
    60  func (kv KeyValues) Less(i, j int) bool { return *kv.keys[i] < *kv.keys[j] }
    61  
    62  func (kv KeyValues) Swap(i, j int) {
    63  	kv.keys[i], kv.keys[j] = kv.keys[j], kv.keys[i]
    64  	kv.values[i], kv.values[j] = kv.values[j], kv.values[i]
    65  }
    66  
    67  func (kv KeyValues) String() string {
    68  	b := strings.Builder{}
    69  	for i, k := range kv.keys {
    70  		v := kv.values[i]
    71  		fmt.Fprintf(&b, "{%v, %v}", *k, *v)
    72  		if i != len(kv.keys)-1 {
    73  			fmt.Fprintf(&b, " ")
    74  		}
    75  	}
    76  	return b.String()
    77  }
    78  
    79  type Node23 struct {
    80  	children []*Node23
    81  	keys     []*Felt
    82  	values   []*Felt
    83  	isLeaf   bool
    84  	exposed  bool
    85  	updated  bool
    86  }
    87  
    88  func (n *Node23) String() string {
    89  	s := fmt.Sprintf("{%p isLeaf=%t keys=%v-%v children=[", n, n.isLeaf, deref(n.keys), n.keys)
    90  	for i, child := range n.children {
    91  		s += fmt.Sprintf("%p", child)
    92  		if i != len(n.children)-1 {
    93  			s += " "
    94  		}
    95  	}
    96  	s += "]}"
    97  	return s
    98  }
    99  
   100  func makeInternalNode(children []*Node23, keys []*Felt, stats *Stats) *Node23 {
   101  	stats.CreatedCount++
   102  	n := &Node23{isLeaf: false, children: children, keys: keys, values: make([]*Felt, 0), exposed: true, updated: true}
   103  	return n
   104  }
   105  
   106  func makeLeafNode(keys, values []*Felt, stats *Stats) *Node23 {
   107  	ensure(len(keys) > 0, "number of keys is zero")
   108  	ensure(len(keys) == len(values), "keys and values have different cardinality")
   109  	stats.CreatedCount++
   110  	n := &Node23{isLeaf: true, children: make([]*Node23, 0), keys: keys, values: values, exposed: true, updated: true}
   111  	return n
   112  }
   113  
   114  func makeEmptyLeafNode() *Node23 {
   115  	// At least nil next key is always present
   116  	return makeLeafNode(make([]*Felt, 1), make([]*Felt, 1), &Stats{}) // do not count it into stats
   117  }
   118  
   119  func promote(nodes []*Node23, intermediateKeys []*Felt, stats *Stats) *Node23 {
   120  	if len(nodes) > 3 {
   121  		promotedNodes := make([]*Node23, 0)
   122  		promotedKeys := make([]*Felt, 0)
   123  		for len(nodes) > 3 {
   124  			promotedNodes = append(promotedNodes, makeInternalNode(nodes[:2], intermediateKeys[:1], stats))
   125  			nodes = nodes[2:]
   126  			promotedKeys = append(promotedKeys, intermediateKeys[1])
   127  			intermediateKeys = intermediateKeys[2:]
   128  		}
   129  		promotedNodes = append(promotedNodes, makeInternalNode(nodes, intermediateKeys, stats))
   130  		return promote(promotedNodes, promotedKeys, stats)
   131  	}
   132  	promotedRoot := makeInternalNode(nodes, intermediateKeys, stats)
   133  	return promotedRoot
   134  }
   135  
   136  func (n *Node23) reset() {
   137  	n.exposed = false
   138  	n.updated = false
   139  	if !n.isLeaf {
   140  		for _, child := range n.children {
   141  			child.reset()
   142  		}
   143  	}
   144  }
   145  
   146  func (n *Node23) isValid() (bool, error) {
   147  	ensure(n.exposed || !n.updated, "isValid: node is not exposed but updated")
   148  	if n.isLeaf {
   149  		return n.isValidLeaf()
   150  	}
   151  	return n.isValidInternal()
   152  }
   153  
   154  func (n *Node23) isValidLeaf() (bool, error) {
   155  	ensure(n.isLeaf, "isValidLeaf: node is not leaf")
   156  
   157  	/* Any leaf node shall have no children */
   158  	if n.childrenCount() != 0 {
   159  		return false, fmt.Errorf("invalid %d children in %v", n.childrenCount(), n)
   160  	}
   161  	/* Any leaf node can have either 1 or 2 keys (plus next key) */
   162  	return n.keyCount() == 1+1 || n.keyCount() == 2+1, fmt.Errorf("invalid %d keys in %v", n.keyCount(), n)
   163  }
   164  
   165  func (n *Node23) isValidInternal() (bool, error) {
   166  	ensure(!n.isLeaf, "isValidInternal: node is leaf")
   167  
   168  	/* Any internal node can have either 1 keys and 2 children or 2 keys and 3 children */
   169  	if n.keyCount() != 1 && n.keyCount() != 2 {
   170  		return false, fmt.Errorf("invalid %d keys in %v", n.keyCount(), n)
   171  	}
   172  	if n.keyCount() == 1 && n.childrenCount() != 2 {
   173  		return false, fmt.Errorf("invalid %d keys %d children in %v", n.keyCount(), n.childrenCount(), n)
   174  	}
   175  	if n.keyCount() == 2 && n.childrenCount() != 3 {
   176  		return false, fmt.Errorf("invalid %d children in %v", n.keyCount(), n)
   177  	}
   178  	subtree := n.walkNodesPostOrder()
   179  	// Check that each internal node has unique keys corresponding to leaf next keys
   180  	for _, key := range n.keys {
   181  		hasNextKey := false
   182  		for _, node := range subtree {
   183  			if !node.isLeaf {
   184  				if node != n && node.hasKey(key) {
   185  					return false, fmt.Errorf("internal key %d not unique", *key)
   186  				}
   187  				continue
   188  			}
   189  			leafNextKey := node.nextKey()
   190  			if leafNextKey != nil && *key == *leafNextKey {
   191  				hasNextKey = true
   192  			}
   193  		}
   194  		if !hasNextKey {
   195  			return false, fmt.Errorf("internal key %d not present in next keys", *key)
   196  		}
   197  	}
   198  	// Check that leaves in subtree are chained together (next key -> first key)
   199  	for i, node := range subtree {
   200  		if !node.isLeaf {
   201  			// Post-order walk => previous and next nodes are contiguous leaves except last
   202  			if i == len(subtree)-1 {
   203  				continue
   204  			}
   205  			previous, next := subtree[i], subtree[i+1]
   206  			if previous.isLeaf && next.isLeaf {
   207  				// Previous node's next key must be equal to next node's first key
   208  				if previous.nextKey() != next.firstKey() {
   209  					return false, fmt.Errorf("nodes %v and %v not chained by next key", previous, next)
   210  				}
   211  			}
   212  			continue
   213  		}
   214  	}
   215  	for i := len(n.children) - 1; i >= 0; i-- {
   216  		child := n.children[i]
   217  		// Check that each child subtree is a 2-3 tree
   218  		childValid, err := child.isValid()
   219  		if !childValid {
   220  			return false, fmt.Errorf("invalid child %v in %v, error: %w", child, n, err)
   221  		}
   222  	}
   223  	return true, nil
   224  }
   225  
   226  func (n *Node23) keyCount() int {
   227  	return len(n.keys)
   228  }
   229  
   230  func (n *Node23) childrenCount() int {
   231  	return len(n.children)
   232  }
   233  
   234  func (n *Node23) valueCount() int {
   235  	return len(n.values)
   236  }
   237  
   238  func (n *Node23) firstKey() *Felt {
   239  	ensure(len(n.keys) > 0, "firstKey: node has no key")
   240  	return n.keys[0]
   241  }
   242  
   243  func (n *Node23) firstValue() *Felt {
   244  	ensure(len(n.values) > 0, "firstValue: node has no value")
   245  	return n.values[0]
   246  }
   247  
   248  func (n *Node23) firstChild() *Node23 {
   249  	ensure(len(n.children) > 0, "firstChild: node has no children")
   250  	return n.children[0]
   251  }
   252  
   253  func (n *Node23) firstLeaf() *Node23 {
   254  	if n.isLeaf {
   255  		return n
   256  	}
   257  	firstLeaf := n.firstChild()
   258  	for !firstLeaf.isLeaf {
   259  		firstLeaf = firstLeaf.firstChild()
   260  	}
   261  	ensure(firstLeaf.isLeaf, "firstLeaf: last is not leaf")
   262  	return firstLeaf
   263  }
   264  
   265  func (n *Node23) lastChild() *Node23 {
   266  	ensure(len(n.children) > 0, "lastChild: node has no children")
   267  	return n.children[len(n.children)-1]
   268  }
   269  
   270  func (n *Node23) lastLeaf() *Node23 {
   271  	if n.isLeaf {
   272  		return n
   273  	}
   274  	lastLeaf := n.lastChild()
   275  	for !lastLeaf.isLeaf {
   276  		lastLeaf = lastLeaf.lastChild()
   277  	}
   278  	ensure(lastLeaf.isLeaf, "lastLeaf: last is not leaf")
   279  	return lastLeaf
   280  }
   281  
   282  func (n *Node23) nextKey() *Felt {
   283  	ensure(len(n.keys) > 0, "nextKey: node has no key")
   284  	return n.keys[len(n.keys)-1]
   285  }
   286  
   287  func (n *Node23) nextValue() *Felt {
   288  	ensure(len(n.values) > 0, "nextValue: node has no value")
   289  	return n.values[len(n.values)-1]
   290  }
   291  
   292  func (n *Node23) rawPointer() uintptr {
   293  	return uintptr(unsafe.Pointer(n))
   294  }
   295  
   296  func (n *Node23) setNextKey(nextKey *Felt, stats *Stats) {
   297  	ensure(len(n.keys) > 0, "setNextKey: node has no key")
   298  	n.keys[len(n.keys)-1] = nextKey
   299  	if !n.exposed {
   300  		n.exposed = true
   301  		stats.ExposedCount++
   302  		stats.OpeningHashes += n.howManyHashes()
   303  	}
   304  	n.updated = true
   305  	stats.UpdatedCount++
   306  }
   307  
   308  func (n *Node23) canonicalKeys() []Felt {
   309  	if n.isLeaf {
   310  		ensure(len(n.keys) > 0, "canonicalKeys: node has no key")
   311  		return deref(n.keys[:len(n.keys)-1])
   312  	} else {
   313  		return deref(n.keys)
   314  	}
   315  }
   316  
   317  func (n *Node23) hasKey(targetKey *Felt) bool {
   318  	var keys []*Felt
   319  	if n.isLeaf {
   320  		ensure(len(n.keys) > 0, "hasKey: node has no key")
   321  		keys = n.keys[:len(n.keys)-1]
   322  	} else {
   323  		keys = n.keys
   324  	}
   325  	for _, key := range keys {
   326  		if *key == *targetKey {
   327  			return true
   328  		}
   329  	}
   330  	return false
   331  }
   332  
   333  func (n *Node23) isEmpty() bool {
   334  	if n.isLeaf {
   335  		// At least next key is always present
   336  		return n.keyCount() == 1
   337  	} else {
   338  		return n.childrenCount() == 0
   339  	}
   340  }
   341  
   342  func (n *Node23) height() int {
   343  	if n.isLeaf {
   344  		return 1
   345  	} else {
   346  		ensure(len(n.children) > 0, "height: internal node has zero children")
   347  		return n.children[0].height() + 1
   348  	}
   349  }
   350  
   351  func (n *Node23) keysInLevelOrder() []Felt {
   352  	keysByLevel := make([]Felt, 0)
   353  	for i := 0; i < n.height(); i++ {
   354  		keysByLevel = append(keysByLevel, n.keysByLevel(i)...)
   355  	}
   356  	return keysByLevel
   357  }
   358  
   359  func (n *Node23) keysByLevel(level int) []Felt {
   360  	if level == 0 {
   361  		return n.canonicalKeys()
   362  	} else {
   363  		levelKeys := make([]Felt, 0)
   364  		for _, child := range n.children {
   365  			childLevelKeys := child.keysByLevel(level - 1)
   366  			levelKeys = append(levelKeys, childLevelKeys...)
   367  		}
   368  		return levelKeys
   369  	}
   370  }
   371  
   372  type Walker func(*Node23) interface{}
   373  
   374  func (n *Node23) walkPostOrder(w Walker) []interface{} {
   375  	items := make([]interface{}, 0)
   376  	if !n.isLeaf {
   377  		for _, child := range n.children {
   378  			childItems := child.walkPostOrder(w)
   379  			items = append(items, childItems...)
   380  		}
   381  	}
   382  	items = append(items, w(n))
   383  	return items
   384  }
   385  
   386  func (n *Node23) walkNodesPostOrder() []*Node23 {
   387  	nodeItems := n.walkPostOrder(func(n *Node23) interface{} { return n })
   388  	nodes := make([]*Node23, len(nodeItems))
   389  	for i := range nodeItems {
   390  		nodes[i] = nodeItems[i].(*Node23)
   391  	}
   392  	return nodes
   393  }
   394  
   395  func (n *Node23) howManyHashes() uint {
   396  	if n.isLeaf {
   397  		// all leaves except last one: 2 or 3 keys + 1 or 2 values => 3 or 5 data => 2 or 4 hashes
   398  		// last leaf: 1 or 2 keys + 1 or 2 values => 2 or 4 data => 1 or 3 hashes
   399  		switch n.keyCount() {
   400  		case 2:
   401  			nextKey := n.keys[1]
   402  			if nextKey == nil {
   403  				return 1
   404  			} else {
   405  				return 2
   406  			}
   407  		case 3:
   408  			nextKey := n.keys[2]
   409  			if nextKey == nil {
   410  				return 3
   411  			} else {
   412  				return 4
   413  			}
   414  		default:
   415  			ensure(false, fmt.Sprintf("howManyHashes: unexpected keyCount=%d\n", n.keyCount()))
   416  			return 0
   417  		}
   418  	} else {
   419  		// internal node: 2 or 3 children => 1 or 2 hashes
   420  		switch n.childrenCount() {
   421  		case 2:
   422  			return 1
   423  		case 3:
   424  			return 2
   425  		default:
   426  			ensure(false, fmt.Sprintf("howManyHashes: unexpected childrenCount=%d\n", n.childrenCount()))
   427  			return 0
   428  		}
   429  	}
   430  }
   431  
   432  func (n *Node23) hashNode() []byte {
   433  	if n.isLeaf {
   434  		return n.hashLeaf()
   435  	} else {
   436  		return n.hashInternal()
   437  	}
   438  }
   439  
   440  func (n *Node23) hashLeaf() []byte {
   441  	ensure(n.isLeaf, "hashLeaf: node is not leaf")
   442  	ensure(n.valueCount() == n.keyCount(), "hashLeaf: insufficient number of values")
   443  	switch n.keyCount() {
   444  	case 2:
   445  		k, nextKey, v := *n.keys[0], n.keys[1], *n.values[0]
   446  		h := hash2(k.Binary(), v.Binary())
   447  		if nextKey == nil {
   448  			return h
   449  		} else {
   450  			return hash2(h, (*nextKey).Binary())
   451  		}
   452  	case 3:
   453  		k1, k2, nextKey, v1, v2 := *n.keys[0], *n.keys[1], n.keys[2], *n.values[0], *n.values[1]
   454  		h1 := hash2(k1.Binary(), v1.Binary())
   455  		h2 := hash2(k2.Binary(), v2.Binary())
   456  		h12 := hash2(h1, h2)
   457  		if nextKey == nil {
   458  			return h12
   459  		} else {
   460  			return hash2(h12, (*nextKey).Binary())
   461  		}
   462  	default:
   463  		ensure(false, fmt.Sprintf("hashLeaf: unexpected keyCount=%d\n", n.keyCount()))
   464  		return []byte{}
   465  	}
   466  }
   467  
   468  func (n *Node23) hashInternal() []byte {
   469  	ensure(!n.isLeaf, "hashInternal: node is not internal")
   470  	switch n.childrenCount() {
   471  	case 2:
   472  		child1, child2 := n.children[0], n.children[1]
   473  		return hash2(child1.hashNode(), child2.hashNode())
   474  	case 3:
   475  		child1, child2, child3 := n.children[0], n.children[1], n.children[2]
   476  		return hash2(hash2(child1.hashNode(), child2.hashNode()), child3.hashNode())
   477  	default:
   478  		ensure(false, fmt.Sprintf("hashInternal: unexpected childrenCount=%d\n", n.childrenCount()))
   479  		return []byte{}
   480  	}
   481  }