github.com/ledgerwatch/erigon-lib@v1.0.0/bptree/bulk.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  	"sort"
    22  )
    23  
    24  func upsert(n *Node23, kvItems KeyValues, stats *Stats) (nodes []*Node23, newFirstKey *Felt, intermediateKeys []*Felt) {
    25  	ensure(sort.IsSorted(kvItems), "kvItems are not sorted by key")
    26  
    27  	if kvItems.Len() == 0 && n == nil {
    28  		return []*Node23{n}, nil, []*Felt{}
    29  	}
    30  	if n == nil {
    31  		n = makeEmptyLeafNode()
    32  	}
    33  	if n.isLeaf {
    34  		return upsertLeaf(n, kvItems, stats)
    35  	} else {
    36  		return upsertInternal(n, kvItems, stats)
    37  	}
    38  }
    39  
    40  func upsertLeaf(n *Node23, kvItems KeyValues, stats *Stats) (nodes []*Node23, newFirstKey *Felt, intermediateKeys []*Felt) {
    41  	ensure(n.isLeaf, "node is not leaf")
    42  
    43  	if kvItems.Len() == 0 {
    44  		if n.nextKey() != nil {
    45  			intermediateKeys = append(intermediateKeys, n.nextKey())
    46  		}
    47  		return []*Node23{n}, nil, intermediateKeys
    48  	}
    49  
    50  	if !n.exposed {
    51  		n.exposed = true
    52  		stats.ExposedCount++
    53  		stats.OpeningHashes += n.howManyHashes()
    54  	}
    55  
    56  	currentFirstKey := n.firstKey()
    57  	addOrReplaceLeaf(n, kvItems, stats)
    58  	if n.firstKey() != currentFirstKey {
    59  		newFirstKey = n.firstKey()
    60  	} else {
    61  		newFirstKey = nil
    62  	}
    63  
    64  	if n.keyCount() > 3 {
    65  		for n.keyCount() > 3 {
    66  			newLeaf := makeLeafNode(n.keys[:3], n.values[:3], stats)
    67  			intermediateKeys = append(intermediateKeys, n.keys[2])
    68  			nodes = append(nodes, newLeaf)
    69  			n.keys, n.values = n.keys[2:], n.values[2:]
    70  		}
    71  		newLeaf := makeLeafNode(n.keys, n.values, stats)
    72  		if n.nextKey() != nil {
    73  			intermediateKeys = append(intermediateKeys, n.nextKey())
    74  		}
    75  		nodes = append(nodes, newLeaf)
    76  		return nodes, newFirstKey, intermediateKeys
    77  	} else {
    78  		if n.nextKey() != nil {
    79  			intermediateKeys = append(intermediateKeys, n.nextKey())
    80  		}
    81  		return []*Node23{n}, newFirstKey, intermediateKeys
    82  	}
    83  }
    84  
    85  func upsertInternal(n *Node23, kvItems KeyValues, stats *Stats) (nodes []*Node23, newFirstKey *Felt, intermediateKeys []*Felt) {
    86  	ensure(!n.isLeaf, "node is not internal")
    87  
    88  	if kvItems.Len() == 0 {
    89  		if n.lastLeaf().nextKey() != nil {
    90  			intermediateKeys = append(intermediateKeys, n.lastLeaf().nextKey())
    91  		}
    92  		return []*Node23{n}, nil, intermediateKeys
    93  	}
    94  
    95  	if !n.exposed {
    96  		n.exposed = true
    97  		stats.ExposedCount++
    98  		stats.OpeningHashes += n.howManyHashes()
    99  	}
   100  
   101  	itemSubsets := splitItems(n, kvItems)
   102  
   103  	newChildren := make([]*Node23, 0)
   104  	newKeys := make([]*Felt, 0)
   105  	for i := len(n.children) - 1; i >= 0; i-- {
   106  		child := n.children[i]
   107  		childNodes, childNewFirstKey, childIntermediateKeys := upsert(child, itemSubsets[i], stats)
   108  		newChildren = append(childNodes, newChildren...)
   109  		newKeys = append(childIntermediateKeys, newKeys...)
   110  		if childNewFirstKey != nil {
   111  			if i > 0 {
   112  				// Handle newFirstKey here
   113  				previousChild := n.children[i-1]
   114  				if previousChild.isLeaf {
   115  					ensure(len(previousChild.keys) > 0, "upsertInternal: previousChild has no keys")
   116  					if previousChild.nextKey() != childNewFirstKey {
   117  						previousChild.setNextKey(childNewFirstKey, stats)
   118  					}
   119  				} else {
   120  					ensure(len(previousChild.children) > 0, "upsertInternal: previousChild has no children")
   121  					lastLeaf := previousChild.lastLeaf()
   122  					if lastLeaf.nextKey() != childNewFirstKey {
   123  						lastLeaf.setNextKey(childNewFirstKey, stats)
   124  					}
   125  				}
   126  				// TODO(canepat): previousChild/previousLastLeaf changed instead of making new node
   127  			} else {
   128  				// Propagate newFirstKey up
   129  				newFirstKey = childNewFirstKey
   130  			}
   131  		}
   132  	}
   133  
   134  	n.children = newChildren
   135  	if n.childrenCount() > 3 {
   136  		ensure(len(newKeys) >= n.childrenCount()-1 || n.childrenCount()%2 == 0 && n.childrenCount()%len(newKeys) == 0, "upsertInternal: inconsistent #children vs #newKeys")
   137  		var hasIntermediateKeys bool
   138  		if len(newKeys) == n.childrenCount()-1 || len(newKeys) == n.childrenCount() {
   139  			/* Groups are: 2,2...2 or 3 */
   140  			hasIntermediateKeys = true
   141  		} else {
   142  			/* Groups are: 2,2...2 */
   143  			hasIntermediateKeys = false
   144  		}
   145  		for n.childrenCount() > 3 {
   146  			nodes = append(nodes, makeInternalNode(n.children[:2], newKeys[:1], stats))
   147  			n.children = n.children[2:]
   148  			if hasIntermediateKeys {
   149  				intermediateKeys = append(intermediateKeys, newKeys[1])
   150  				newKeys = newKeys[2:]
   151  			} else {
   152  				newKeys = newKeys[1:]
   153  			}
   154  		}
   155  		ensure(n.childrenCount() > 0 && len(newKeys) > 0, "upsertInternal: inconsistent #children vs #newKeys")
   156  		if n.childrenCount() == 2 {
   157  			ensure(len(newKeys) > 0, "upsertInternal: inconsistent #newKeys")
   158  			nodes = append(nodes, makeInternalNode(n.children, newKeys[:1], stats))
   159  			intermediateKeys = append(intermediateKeys, newKeys[1:]...)
   160  		} else if n.childrenCount() == 3 {
   161  			ensure(len(newKeys) > 1, "upsertInternal: inconsistent #newKeys")
   162  			nodes = append(nodes, makeInternalNode(n.children, newKeys[:2], stats))
   163  			intermediateKeys = append(intermediateKeys, newKeys[2:]...)
   164  		} else {
   165  			ensure(false, fmt.Sprintf("upsertInternal: inconsistent #children=%d #newKeys=%d\n", n.childrenCount(), len(newKeys)))
   166  		}
   167  		return nodes, newFirstKey, intermediateKeys
   168  	} else { // n.childrenCount() is 2 or 3
   169  		ensure(len(newKeys) > 0, "upsertInternal: newKeys count is zero")
   170  		if len(newKeys) == len(n.children) {
   171  			n.keys = newKeys[:len(newKeys)-1]
   172  			intermediateKeys = append(intermediateKeys, newKeys[len(newKeys)-1])
   173  		} else {
   174  			n.keys = newKeys
   175  		}
   176  		// TODO(canepat): n.keys changed instead of making new node
   177  		n.updated = true
   178  		stats.UpdatedCount++
   179  		return []*Node23{n}, newFirstKey, intermediateKeys
   180  	}
   181  }
   182  
   183  func addOrReplaceLeaf(n *Node23, kvItems KeyValues, stats *Stats) {
   184  	ensure(n.isLeaf, "addOrReplaceLeaf: node is not leaf")
   185  	ensure(len(n.keys) > 0 && len(n.values) > 0, "addOrReplaceLeaf: node keys/values are empty")
   186  	ensure(len(kvItems.keys) > 0 && len(kvItems.keys) == len(kvItems.values), "addOrReplaceLeaf: invalid kvItems")
   187  
   188  	// Temporarily remove next key/value
   189  	nextKey, nextValue := n.nextKey(), n.nextValue()
   190  
   191  	n.keys = n.keys[:len(n.keys)-1]
   192  	n.values = n.values[:len(n.values)-1]
   193  
   194  	// kvItems are ordered by key: search there using n.keys that here are 1 or 2 by design (0 just for empty tree)
   195  	switch n.keyCount() {
   196  	case 0:
   197  		n.keys = append(n.keys, kvItems.keys...)
   198  		n.values = append(n.values, kvItems.values...)
   199  	case 1:
   200  		addOrReplaceLeaf1(n, kvItems, stats)
   201  	case 2:
   202  		addOrReplaceLeaf2(n, kvItems, stats)
   203  	default:
   204  		ensure(false, fmt.Sprintf("addOrReplaceLeaf: invalid key count %d", n.keyCount()))
   205  	}
   206  
   207  	// Restore next key/value
   208  	n.keys = append(n.keys, nextKey)
   209  	n.values = append(n.values, nextValue)
   210  }
   211  
   212  func addOrReplaceLeaf1(n *Node23, kvItems KeyValues, stats *Stats) {
   213  	ensure(n.isLeaf, "addOrReplaceLeaf1: node is not leaf")
   214  	ensure(n.keyCount() == 1, "addOrReplaceLeaf1: leaf has not 1 *canonical* key")
   215  
   216  	key0, value0 := n.keys[0], n.values[0]
   217  	index0 := sort.Search(kvItems.Len(), func(i int) bool { return *kvItems.keys[i] >= *key0 })
   218  	if index0 < kvItems.Len() {
   219  		// Insert keys/values concatenating new ones around key0
   220  		n.keys = append(make([]*Felt, 0), kvItems.keys[:index0]...)
   221  		n.values = append(make([]*Felt, 0), kvItems.values[:index0]...)
   222  		n.keys = append(n.keys, key0)
   223  		n.values = append(n.values, value0)
   224  		if *kvItems.keys[index0] == *key0 {
   225  			// Incoming key matches an existing key: update
   226  			n.keys = append(n.keys, kvItems.keys[index0+1:]...)
   227  			n.values = append(n.values, kvItems.values[index0+1:]...)
   228  			n.updated = true
   229  			stats.UpdatedCount++
   230  		} else {
   231  			n.keys = append(n.keys, kvItems.keys[index0:]...)
   232  			n.values = append(n.values, kvItems.values[index0:]...)
   233  		}
   234  	} else {
   235  		// key0 greater than any input key
   236  		n.keys = append(kvItems.keys, key0)
   237  		n.values = append(kvItems.values, value0)
   238  	}
   239  }
   240  
   241  func addOrReplaceLeaf2(n *Node23, kvItems KeyValues, stats *Stats) {
   242  	ensure(n.isLeaf, "addOrReplaceLeaf2: node is not leaf")
   243  	ensure(n.keyCount() == 2, "addOrReplaceLeaf2: leaf has not 2 *canonical* keys")
   244  
   245  	key0, value0, key1, value1 := n.keys[0], n.values[0], n.keys[1], n.values[1]
   246  	index0 := sort.Search(kvItems.Len(), func(i int) bool { return *kvItems.keys[i] >= *key0 })
   247  	index1 := sort.Search(kvItems.Len(), func(i int) bool { return *kvItems.keys[i] >= *key1 })
   248  	ensure(index1 >= index0, "addOrReplaceLeaf2: keys not ordered")
   249  	if index0 < kvItems.Len() {
   250  		if index1 < kvItems.Len() {
   251  			// Insert keys/values concatenating new ones around key0 and key1
   252  			n.keys = append(make([]*Felt, 0), kvItems.keys[:index0]...)
   253  			n.values = append(make([]*Felt, 0), kvItems.values[:index0]...)
   254  			n.keys = append(n.keys, key0)
   255  			n.values = append(n.values, value0)
   256  			if *kvItems.keys[index0] == *key0 {
   257  				// Incoming key matches an existing key: update
   258  				n.keys = append(n.keys, kvItems.keys[index0+1:index1]...)
   259  				n.values = append(n.values, kvItems.values[index0+1:index1]...)
   260  				n.updated = true
   261  				stats.UpdatedCount++
   262  			} else {
   263  				n.keys = append(n.keys, kvItems.keys[index0:index1]...)
   264  				n.values = append(n.values, kvItems.values[index0:index1]...)
   265  			}
   266  			n.keys = append(n.keys, key1)
   267  			n.values = append(n.values, value1)
   268  			if *kvItems.keys[index1] == *key1 {
   269  				// Incoming key matches an existing key: update
   270  				n.keys = append(n.keys, kvItems.keys[index1+1:]...)
   271  				n.values = append(n.values, kvItems.values[index1+1:]...)
   272  				if !n.updated {
   273  					n.updated = true
   274  					stats.UpdatedCount++
   275  				}
   276  			} else {
   277  				n.keys = append(n.keys, kvItems.keys[index1:]...)
   278  				n.values = append(n.values, kvItems.values[index1:]...)
   279  			}
   280  		} else {
   281  			// Insert keys/values concatenating new ones around key0, then add key1
   282  			n.keys = append(make([]*Felt, 0), kvItems.keys[:index0]...)
   283  			n.values = append(make([]*Felt, 0), kvItems.values[:index0]...)
   284  			n.keys = append(n.keys, key0)
   285  			n.values = append(n.values, value0)
   286  			if *kvItems.keys[index0] == *key0 {
   287  				// Incoming key matches an existing key: update
   288  				n.keys = append(n.keys, kvItems.keys[index0+1:]...)
   289  				n.values = append(n.values, kvItems.values[index0+1:]...)
   290  				n.updated = true
   291  				stats.UpdatedCount++
   292  			} else {
   293  				n.keys = append(n.keys, kvItems.keys[index0:]...)
   294  				n.values = append(n.values, kvItems.values[index0:]...)
   295  			}
   296  			n.keys = append(n.keys, key1)
   297  			n.values = append(n.values, value1)
   298  		}
   299  	} else {
   300  		ensure(index1 == index0, "addOrReplaceLeaf2: keys not ordered")
   301  		// Both key0 and key1 greater than any input key
   302  		n.keys = append(kvItems.keys, key0, key1)
   303  		n.values = append(kvItems.values, value0, value1)
   304  	}
   305  }
   306  
   307  func splitItems(n *Node23, kvItems KeyValues) []KeyValues {
   308  	ensure(!n.isLeaf, "splitItems: node is not internal")
   309  	ensure(len(n.keys) > 0, "splitItems: internal node has no keys")
   310  
   311  	itemSubsets := make([]KeyValues, 0)
   312  	for i, key := range n.keys {
   313  		splitIndex := sort.Search(kvItems.Len(), func(i int) bool { return *kvItems.keys[i] >= *key })
   314  		itemSubsets = append(itemSubsets, KeyValues{kvItems.keys[:splitIndex], kvItems.values[:splitIndex]})
   315  		kvItems = KeyValues{kvItems.keys[splitIndex:], kvItems.values[splitIndex:]}
   316  		if i == len(n.keys)-1 {
   317  			itemSubsets = append(itemSubsets, kvItems)
   318  		}
   319  	}
   320  	ensure(len(itemSubsets) == len(n.children), "item subsets and children have different cardinality")
   321  	return itemSubsets
   322  }
   323  
   324  func del(n *Node23, keysToDelete []Felt, stats *Stats) (deleted *Node23, nextKey *Felt, intermediateKeys []*Felt) {
   325  	ensure(sort.IsSorted(Keys(keysToDelete)), "keysToDelete are not sorted")
   326  
   327  	if n == nil {
   328  		return n, nil, intermediateKeys
   329  	}
   330  	if n.isLeaf {
   331  		return deleteLeaf(n, keysToDelete, stats)
   332  	} else {
   333  		return deleteInternal(n, keysToDelete, stats)
   334  	}
   335  }
   336  
   337  func deleteLeaf(n *Node23, keysToDelete []Felt, stats *Stats) (deleted *Node23, nextKey *Felt, intermediateKeys []*Felt) {
   338  	ensure(n.isLeaf, fmt.Sprintf("node %s is not leaf", n))
   339  
   340  	if len(keysToDelete) == 0 {
   341  		if n.nextKey() != nil {
   342  			intermediateKeys = append(intermediateKeys, n.nextKey())
   343  		}
   344  		return n, nil, intermediateKeys
   345  	}
   346  
   347  	if !n.exposed {
   348  		n.exposed = true
   349  		stats.ExposedCount++
   350  		stats.OpeningHashes += n.howManyHashes()
   351  	}
   352  
   353  	currentFirstKey := n.firstKey()
   354  	deleteLeafKeys(n, keysToDelete, stats)
   355  	if n.keyCount() == 1 {
   356  		return nil, n.nextKey(), intermediateKeys
   357  	} else {
   358  		if n.nextKey() != nil {
   359  			intermediateKeys = append(intermediateKeys, n.nextKey())
   360  		}
   361  		if n.firstKey() != currentFirstKey {
   362  			return n, n.firstKey(), intermediateKeys
   363  		} else {
   364  			return n, nil, intermediateKeys
   365  		}
   366  	}
   367  }
   368  
   369  func deleteLeafKeys(n *Node23, keysToDelete []Felt, stats *Stats) (deleted KeyValues) {
   370  	ensure(n.isLeaf, "deleteLeafKeys: node is not leaf")
   371  	switch n.keyCount() {
   372  	case 2:
   373  		if Keys(keysToDelete).Contains(*n.keys[0]) {
   374  			deleted.keys = n.keys[:1]
   375  			deleted.values = n.values[:1]
   376  			n.keys = n.keys[1:]
   377  			n.values = n.values[1:]
   378  			stats.DeletedCount++
   379  		}
   380  	case 3:
   381  		if Keys(keysToDelete).Contains(*n.keys[0]) {
   382  			if Keys(keysToDelete).Contains(*n.keys[1]) {
   383  				deleted.keys = n.keys[:2]
   384  				deleted.values = n.values[:2]
   385  				n.keys = n.keys[2:]
   386  				n.values = n.values[2:]
   387  				stats.DeletedCount++
   388  			} else {
   389  				deleted.keys = n.keys[:1]
   390  				deleted.values = n.values[:1]
   391  				n.keys = n.keys[1:]
   392  				n.values = n.values[1:]
   393  				n.updated = true
   394  				stats.UpdatedCount++
   395  			}
   396  		} else {
   397  			if Keys(keysToDelete).Contains(*n.keys[1]) {
   398  				deleted.keys = n.keys[1:2]
   399  				deleted.values = n.values[1:2]
   400  				n.keys = append(n.keys[:1], n.keys[2])
   401  				n.values = append(n.values[:1], n.values[2])
   402  				n.updated = true
   403  				stats.UpdatedCount++
   404  			}
   405  		}
   406  	default:
   407  		ensure(false, fmt.Sprintf("unexpected number of keys in %s", n))
   408  	}
   409  	return deleted
   410  }
   411  
   412  func deleteInternal(n *Node23, keysToDelete []Felt, stats *Stats) (deleted *Node23, nextKey *Felt, intermediateKeys []*Felt) {
   413  	ensure(!n.isLeaf, fmt.Sprintf("node %s is not internal", n))
   414  
   415  	if len(keysToDelete) == 0 {
   416  		if n.lastLeaf().nextKey() != nil {
   417  			intermediateKeys = append(intermediateKeys, n.lastLeaf().nextKey())
   418  		}
   419  		return n, nil, intermediateKeys
   420  	}
   421  
   422  	if !n.exposed {
   423  		n.exposed = true
   424  		stats.ExposedCount++
   425  		stats.OpeningHashes += n.howManyHashes()
   426  	}
   427  
   428  	keySubsets := splitKeys(n, keysToDelete)
   429  
   430  	newKeys := make([]*Felt, 0)
   431  	for i := len(n.children) - 1; i >= 0; i-- {
   432  		child, childNextKey, childIntermediateKeys := del(n.children[i], keySubsets[i], stats)
   433  		newKeys = append(childIntermediateKeys, newKeys...)
   434  		if i > 0 {
   435  			previousIndex := i - 1
   436  			previousChild := n.children[previousIndex]
   437  			for previousChild.isEmpty() && previousIndex-1 >= 0 {
   438  				previousChild = n.children[previousIndex-1]
   439  				previousIndex = previousIndex - 1
   440  			}
   441  			if child == nil || childNextKey != nil {
   442  				if previousChild.isLeaf {
   443  					ensure(len(previousChild.keys) > 0, "delete: previousChild has no keys")
   444  					if previousChild.nextKey() != childNextKey {
   445  						previousChild.setNextKey(childNextKey, stats)
   446  					}
   447  				} else {
   448  					ensure(len(previousChild.children) > 0, "delete: previousChild has no children")
   449  					lastLeaf := previousChild.lastLeaf()
   450  					if lastLeaf.nextKey() != childNextKey {
   451  						lastLeaf.setNextKey(childNextKey, stats)
   452  					}
   453  				}
   454  			}
   455  			if !previousChild.isEmpty() && child != nil && child.childrenCount() == 1 {
   456  				child.keys = child.keys[:0]
   457  				newLeft, newRight := mergeRight2Left(previousChild, child, stats)
   458  				n.children = append(n.children[:previousIndex], append([]*Node23{newLeft, newRight}, n.children[i+1:]...)...)
   459  			}
   460  		} else {
   461  			nextIndex := i + 1
   462  			nextChild := n.children[nextIndex]
   463  			for nextChild.isEmpty() && nextIndex+1 < n.childrenCount() {
   464  				nextChild = n.children[nextIndex+1]
   465  				nextIndex = nextIndex + 1
   466  			}
   467  			if !nextChild.isEmpty() && child != nil && child.childrenCount() == 1 {
   468  				child.keys = child.keys[:0]
   469  				newLeft, newRight := mergeLeft2Right(child, nextChild, stats)
   470  				n.children = append([]*Node23{newLeft, newRight}, n.children[nextIndex+1:]...)
   471  			}
   472  			if childNextKey != nil {
   473  				nextKey = childNextKey
   474  			}
   475  		}
   476  	}
   477  	switch len(n.children) {
   478  	case 2:
   479  		nextKey, intermediateKeys = update2Node(n, newKeys, nextKey, intermediateKeys, stats)
   480  	case 3:
   481  		nextKey, intermediateKeys = update3Node(n, newKeys, nextKey, intermediateKeys, stats)
   482  	default:
   483  		ensure(false, fmt.Sprintf("unexpected number of children in %s", n))
   484  	}
   485  
   486  	for _, child := range n.children {
   487  		if child.updated {
   488  			n.updated = true
   489  			stats.UpdatedCount++
   490  			break
   491  		}
   492  	}
   493  
   494  	if n.keyCount() == 0 {
   495  		return nil, nextKey, intermediateKeys
   496  	} else {
   497  		return n, nextKey, intermediateKeys
   498  	}
   499  }
   500  
   501  func mergeLeft2Right(left, right *Node23, stats *Stats) (newLeft, newRight *Node23) {
   502  	ensure(!left.isLeaf, "mergeLeft2Right: left is leaf")
   503  	ensure(left.childrenCount() > 0, "mergeLeft2Right: left has no children")
   504  
   505  	if left.firstChild().childrenCount() == 1 {
   506  		newLeftFirstChild, newRightFirstChild := mergeLeft2Right(left.firstChild(), right.firstChild(), stats)
   507  		left = makeInternalNode(
   508  			[]*Node23{newLeftFirstChild},
   509  			left.keys,
   510  			stats,
   511  		)
   512  		right = makeInternalNode(
   513  			append([]*Node23{newRightFirstChild}, right.children[1:]...),
   514  			right.keys,
   515  			stats,
   516  		)
   517  	}
   518  
   519  	if right.childrenCount() >= 3 {
   520  		return mergeRight2Left(left, right, stats)
   521  	}
   522  	if left.firstChild().isEmpty() {
   523  		newRight = right
   524  		newLeft = makeInternalNode([]*Node23{}, []*Felt{}, stats)
   525  		return newLeft, newRight
   526  	}
   527  	if right.childrenCount() == 1 {
   528  		if right.firstChild().isEmpty() {
   529  			newLeft = left
   530  			newRight = makeInternalNode([]*Node23{}, []*Felt{}, stats)
   531  		} else {
   532  			newRight = makeInternalNode(
   533  				append([]*Node23{left.firstChild()}, right.children...),
   534  				[]*Felt{left.lastLeaf().nextKey()},
   535  				stats,
   536  			)
   537  			if left.keyCount() > 1 {
   538  				newLeft = makeInternalNode(left.children[1:], left.keys[1:], stats)
   539  			} else {
   540  				newLeft = makeInternalNode(left.children[1:], left.keys, stats)
   541  			}
   542  		}
   543  	} else {
   544  		newRight = makeInternalNode(
   545  			append([]*Node23{left.firstChild()}, right.children...),
   546  			append([]*Felt{left.lastLeaf().nextKey()}, right.keys...),
   547  			stats,
   548  		)
   549  		if left.keyCount() > 1 {
   550  			newLeft = makeInternalNode(left.children[1:], left.keys[1:], stats)
   551  		} else {
   552  			newLeft = makeInternalNode(left.children[1:], left.keys, stats)
   553  		}
   554  	}
   555  	return newLeft, newRight
   556  }
   557  
   558  func mergeRight2Left(left, right *Node23, stats *Stats) (newLeft, newRight *Node23) {
   559  	ensure(!right.isLeaf, "mergeRight2Left: right is leaf")
   560  	ensure(right.childrenCount() > 0, "mergeRight2Left: right has no children")
   561  
   562  	if right.firstChild().childrenCount() == 1 {
   563  		newLeftLastChild, newRightFirstChild := mergeRight2Left(left.lastChild(), right.firstChild(), stats)
   564  		left = makeInternalNode(
   565  			append(left.children[:len(left.children)-1], newLeftLastChild),
   566  			left.keys,
   567  			stats,
   568  		)
   569  		right = makeInternalNode(
   570  			[]*Node23{newRightFirstChild},
   571  			right.keys,
   572  			stats,
   573  		)
   574  	}
   575  
   576  	if left.childrenCount() < 3 {
   577  		if !right.firstChild().isEmpty() {
   578  			if left.childrenCount() == 1 {
   579  				if left.firstChild().isEmpty() {
   580  					newLeft = makeInternalNode([]*Node23{}, []*Felt{}, stats)
   581  					newRight = right
   582  				} else {
   583  					newLeft = makeInternalNode(
   584  						append(left.children, right.firstChild()),
   585  						[]*Felt{right.firstLeaf().firstKey()},
   586  						stats,
   587  					)
   588  					if right.keyCount() > 1 {
   589  						newRight = makeInternalNode(right.children[1:], right.keys[1:], stats)
   590  					} else {
   591  						newRight = makeInternalNode(right.children[1:], right.keys, stats)
   592  					}
   593  				}
   594  			} else {
   595  				newLeft = makeInternalNode(
   596  					append(left.children, right.firstChild()),
   597  					append(left.keys, right.firstLeaf().firstKey()),
   598  					stats,
   599  				)
   600  				if right.keyCount() > 1 {
   601  					newRight = makeInternalNode(right.children[1:], right.keys[1:], stats)
   602  				} else {
   603  					newRight = makeInternalNode(right.children[1:], right.keys, stats)
   604  				}
   605  			}
   606  		} else {
   607  			newLeft = left
   608  			newRight = makeInternalNode([]*Node23{}, []*Felt{}, stats)
   609  		}
   610  	} else {
   611  		newLeft, newRight = mergeLeft2Right(left, right, stats)
   612  	}
   613  	return newLeft, newRight
   614  }
   615  
   616  func splitKeys(n *Node23, keysToDelete []Felt) [][]Felt {
   617  	ensure(!n.isLeaf, "splitKeys: node is not internal")
   618  	ensure(len(n.keys) > 0, fmt.Sprintf("splitKeys: internal node %s has no keys", n))
   619  
   620  	keySubsets := make([][]Felt, 0)
   621  	for i, key := range n.keys {
   622  		splitIndex := sort.Search(len(keysToDelete), func(i int) bool { return keysToDelete[i] >= *key })
   623  		keySubsets = append(keySubsets, keysToDelete[:splitIndex])
   624  		keysToDelete = keysToDelete[splitIndex:]
   625  		if i == len(n.keys)-1 {
   626  			keySubsets = append(keySubsets, keysToDelete)
   627  		}
   628  	}
   629  	ensure(len(keySubsets) == len(n.children), "key subsets and children have different cardinality")
   630  	return keySubsets
   631  }
   632  
   633  func update2Node(n *Node23, newKeys []*Felt, nextKey *Felt, intermediateKeys []*Felt, stats *Stats) (*Felt, []*Felt) {
   634  	ensure(len(n.children) == 2, "update2Node: wrong number of children")
   635  
   636  	switch len(newKeys) {
   637  	case 0:
   638  		break
   639  	case 1:
   640  		n.keys = newKeys
   641  	case 2:
   642  		n.keys = newKeys[:1]
   643  		intermediateKeys = append(intermediateKeys, newKeys[1])
   644  	default:
   645  		ensure(false, fmt.Sprintf("update2Node: wrong number of newKeys=%d", len(newKeys)))
   646  	}
   647  	nodeA, nodeC := n.children[0], n.children[1]
   648  	if nodeA.isEmpty() {
   649  		if nodeC.isEmpty() {
   650  			/* A is empty, a_next is the "next key"; C is empty, c_next is the "next key" */
   651  			n.children = n.children[:0]
   652  			n.keys = n.keys[:0]
   653  			if nodeC.isLeaf {
   654  				return nodeC.nextKey(), intermediateKeys
   655  			}
   656  			return nextKey, intermediateKeys
   657  		} else {
   658  			/* A is empty, a_next is the "next key"; C is not empty */
   659  			n.children = n.children[1:]
   660  			/// n.keys = []*Felt{nodeC.lastLeaf().nextKey()}
   661  			if nodeA.isLeaf {
   662  				return nodeA.nextKey(), intermediateKeys
   663  			}
   664  			return nextKey, intermediateKeys
   665  		}
   666  	} else {
   667  		if nodeC.isEmpty() {
   668  			/* A is not empty; C is empty, c_next is the "next key" */
   669  			n.children = n.children[:1]
   670  			/// n.keys = []*Felt{nodeA.lastLeaf().nextKey()}
   671  			if nodeC.isLeaf {
   672  				nodeA.setNextKey(nodeC.nextKey(), stats)
   673  			}
   674  			return nextKey, intermediateKeys
   675  		} else {
   676  			/* A is not empty; C is not empty */
   677  			n.keys = []*Felt{nodeA.lastLeaf().nextKey()}
   678  			return nextKey, intermediateKeys
   679  		}
   680  	}
   681  }
   682  
   683  func update3Node(n *Node23, newKeys []*Felt, nextKey *Felt, intermediateKeys []*Felt, stats *Stats) (*Felt, []*Felt) {
   684  	ensure(len(n.children) == 3, "update3Node: wrong number of children")
   685  
   686  	switch len(newKeys) {
   687  	case 0:
   688  		break
   689  	case 1:
   690  		n.keys = newKeys
   691  	case 2:
   692  		n.keys = newKeys
   693  	case 3:
   694  		n.keys = newKeys[:2]
   695  		intermediateKeys = append(intermediateKeys, newKeys[2])
   696  	default:
   697  		ensure(false, fmt.Sprintf("update3Node: wrong number of newKeys=%d", len(newKeys)))
   698  	}
   699  	nodeA, nodeB, nodeC := n.children[0], n.children[1], n.children[2]
   700  	if nodeA.isEmpty() {
   701  		if nodeB.isEmpty() {
   702  			if nodeC.isEmpty() {
   703  				/* A is empty, a_next is the "next key"; B is empty, b_next is the "next key"; C is empty, c_next is the "next key" */
   704  				n.children = n.children[:0]
   705  				n.keys = n.keys[:0]
   706  				if nodeA.isLeaf {
   707  					return nodeC.nextKey(), intermediateKeys
   708  				}
   709  				return nextKey, intermediateKeys
   710  			} else {
   711  				/* A is empty, a_next is the "next key"; B is empty, b_next is the "next key"; C is not empty */
   712  				n.children = n.children[2:]
   713  				/// n.keys = []*Felt{nodeC.lastLeaf().nextKey()}
   714  				if nodeA.isLeaf {
   715  					return nodeB.nextKey(), intermediateKeys
   716  				}
   717  				return nextKey, intermediateKeys
   718  			}
   719  		} else {
   720  			if nodeC.isEmpty() {
   721  				/* A is empty, a_next is the "next key"; B is not empty; C is empty, c_next is the "next key" */
   722  				n.children = n.children[1:2]
   723  				/// n.keys = []*Felt{nodeB.lastLeaf().nextKey()}
   724  				if nodeA.isLeaf {
   725  					nodeB.setNextKey(nodeC.nextKey(), stats)
   726  					return nodeA.nextKey(), intermediateKeys
   727  				}
   728  				return nextKey, intermediateKeys
   729  			} else {
   730  				/* A is empty, a_next is the "next key"; B is not empty; C is not empty */
   731  				n.children = n.children[1:]
   732  				if nodeA.isLeaf {
   733  					n.keys = []*Felt{nodeB.nextKey()}
   734  					return nodeA.nextKey(), intermediateKeys
   735  				}
   736  				n.keys = []*Felt{nodeB.lastLeaf().nextKey()}
   737  				return nextKey, intermediateKeys
   738  			}
   739  		}
   740  	} else {
   741  		if nodeB.isEmpty() {
   742  			if nodeC.isEmpty() {
   743  				/* A is not empty; B is empty, b_next is the "next key"; C is empty, c_next is the "next key" */
   744  				n.children = n.children[:1]
   745  				if nodeA.isLeaf {
   746  					nodeA.setNextKey(nodeC.nextKey(), stats)
   747  				}
   748  				/// n.keys = []*Felt{nodeA.lastLeaf().nextKey()}
   749  				return nextKey, intermediateKeys
   750  			} else {
   751  				/* A is not empty; B is empty, b_next is the "next key"; C is not empty */
   752  				n.children = append(n.children[:1], n.children[2])
   753  				if nodeA.isLeaf {
   754  					n.keys = []*Felt{nodeB.nextKey()}
   755  					nodeA.setNextKey(nodeB.nextKey(), stats)
   756  				} else {
   757  					n.keys = []*Felt{nodeA.lastLeaf().nextKey()}
   758  				}
   759  				return nextKey, intermediateKeys
   760  			}
   761  		} else {
   762  			if nodeC.isEmpty() {
   763  				/* A is not empty; B is not empty; C is empty, c_next is the "next key" */
   764  				n.children = n.children[:2]
   765  				if nodeA.isLeaf {
   766  					n.keys = []*Felt{nodeA.nextKey()}
   767  					nodeB.setNextKey(nodeC.nextKey(), stats)
   768  				} else {
   769  					n.keys = []*Felt{nodeA.lastLeaf().nextKey()}
   770  				}
   771  				return nextKey, intermediateKeys
   772  			} else {
   773  				/* A is not empty; B is not empty; C is not empty */
   774  				///n.keys = []*Felt{nodeA.lastLeaf().nextKey(), nodeB.lastLeaf().nextKey()}
   775  				return nextKey, intermediateKeys
   776  			}
   777  		}
   778  	}
   779  }
   780  
   781  func demote(node *Node23, nextKey *Felt, intermediateKeys []*Felt, stats *Stats) (*Node23, *Felt) {
   782  	if node == nil {
   783  		return nil, nextKey
   784  	} else if len(node.children) == 0 {
   785  		if len(node.keys) == 0 {
   786  			return nil, nextKey
   787  		} else {
   788  			return node, nextKey
   789  		}
   790  	} else if len(node.children) == 1 {
   791  		return demote(node.children[0], nextKey, intermediateKeys, stats)
   792  	} else if len(node.children) == 2 {
   793  		firstChild, secondChild := node.children[0], node.children[1]
   794  		if firstChild.keyCount() == 0 && secondChild.keyCount() == 0 {
   795  			return nil, nextKey
   796  		}
   797  		if firstChild.keyCount() == 0 && secondChild.keyCount() > 0 {
   798  			return secondChild, nextKey
   799  		}
   800  		if firstChild.keyCount() > 0 && secondChild.keyCount() == 0 {
   801  			return firstChild, nextKey
   802  		}
   803  		if firstChild.keyCount() == 2 && secondChild.keyCount() == 2 {
   804  			if firstChild.isLeaf {
   805  				keys := []*Felt{firstChild.firstKey(), secondChild.firstKey(), secondChild.nextKey()}
   806  				values := []*Felt{firstChild.firstValue(), secondChild.firstValue(), secondChild.nextValue()}
   807  				return makeLeafNode(keys, values, stats), nextKey
   808  			}
   809  		}
   810  	}
   811  	return node, nextKey
   812  }