github.com/ledgerwatch/erigon-lib@v1.0.0/bptree/tree_test.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  	"bufio"
    21  	"bytes"
    22  	"encoding/hex"
    23  	"sort"
    24  	"testing"
    25  
    26  	"github.com/stretchr/testify/assert"
    27  	"github.com/stretchr/testify/require"
    28  )
    29  
    30  func assertTwoThreeTree(t *testing.T, tree *Tree23, expectedKeysLevelOrder []Felt) {
    31  	t.Helper()
    32  	treeValid, err := tree.IsValid()
    33  	assert.True(t, treeValid, "2-3-tree properties do not hold for tree: %v, error: %v", tree.KeysInLevelOrder(), err)
    34  	if expectedKeysLevelOrder != nil {
    35  		assert.Equal(t, expectedKeysLevelOrder, tree.KeysInLevelOrder(), "different keys by level")
    36  	}
    37  }
    38  
    39  func require23Tree(t *testing.T, tree *Tree23, expectedKeysLevelOrder []Felt, input1, input2 []byte) {
    40  	t.Helper()
    41  	treeValid, err := tree.IsValid()
    42  	require.True(t, treeValid, "2-3-tree properties do not hold: input [%v %v] [%+q %+q], error: %v",
    43  		input1, input2, string(input1), string(input2), err)
    44  	if expectedKeysLevelOrder != nil {
    45  		assert.Equal(t, expectedKeysLevelOrder, tree.KeysInLevelOrder(), "different keys by level")
    46  	}
    47  }
    48  
    49  type HeightTest struct {
    50  	initialItems   KeyValues
    51  	expectedHeight int
    52  }
    53  
    54  type IsTree23Test struct {
    55  	initialItems           KeyValues
    56  	expectedKeysLevelOrder []Felt
    57  }
    58  
    59  type RootHashTest struct {
    60  	expectedHash string
    61  	initialItems KeyValues
    62  }
    63  
    64  type UpsertTest struct {
    65  	initialItems          KeyValues
    66  	initialKeysLevelOrder []Felt
    67  	deltaItems            KeyValues
    68  	finalKeysLevelOrder   []Felt
    69  }
    70  
    71  type DeleteTest struct {
    72  	initialItems          KeyValues
    73  	initialKeysLevelOrder []Felt
    74  	keysToDelete          []Felt
    75  	finalKeysLevelOrder   []Felt
    76  }
    77  
    78  func K(keys []Felt) KeyValues {
    79  	values := make([]Felt, len(keys))
    80  	copy(values, keys)
    81  	return KV(keys, values)
    82  }
    83  
    84  var heightTestTable = []HeightTest{
    85  	{K([]Felt{}), 0},
    86  	{K([]Felt{1}), 1},
    87  	{K([]Felt{1, 2}), 1},
    88  	{K([]Felt{1, 2, 3}), 2},
    89  	{K([]Felt{1, 2, 3, 4}), 2},
    90  	{K([]Felt{1, 2, 3, 4, 5}), 2},
    91  	{K([]Felt{1, 2, 3, 4, 5, 6}), 2},
    92  	{K([]Felt{1, 2, 3, 4, 5, 6, 7}), 3},
    93  	{K([]Felt{1, 2, 3, 4, 5, 6, 7, 8}), 3},
    94  }
    95  
    96  var isTree23TestTable = []IsTree23Test{
    97  	{K([]Felt{}), []Felt{}},
    98  	{K([]Felt{1}), []Felt{1}},
    99  	{K([]Felt{1, 2}), []Felt{1, 2}},
   100  	{K([]Felt{1, 2, 3}), []Felt{3, 1, 2, 3}},
   101  	{K([]Felt{1, 2, 3, 4}), []Felt{3, 1, 2, 3, 4}},
   102  	{K([]Felt{1, 2, 3, 4, 5}), []Felt{3, 5, 1, 2, 3, 4, 5}},
   103  	{K([]Felt{1, 2, 3, 4, 5, 6}), []Felt{3, 5, 1, 2, 3, 4, 5, 6}},
   104  	{K([]Felt{1, 2, 3, 4, 5, 6, 7}), []Felt{5, 3, 7, 1, 2, 3, 4, 5, 6, 7}},
   105  	{K([]Felt{1, 2, 3, 4, 5, 6, 7, 8}), []Felt{5, 3, 7, 1, 2, 3, 4, 5, 6, 7, 8}},
   106  	{K([]Felt{1, 2, 3, 4, 5, 6, 7, 8, 9}), []Felt{5, 3, 7, 9, 1, 2, 3, 4, 5, 6, 7, 8, 9}},
   107  	{K([]Felt{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}), []Felt{5, 3, 7, 9, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}},
   108  	{K([]Felt{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}), []Felt{5, 9, 3, 7, 11, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}},
   109  	{K([]Felt{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}), []Felt{5, 9, 3, 7, 11, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}},
   110  	{K([]Felt{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17}), []Felt{9, 5, 13, 3, 7, 11, 15, 17, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17}},
   111  	{K([]Felt{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18}), []Felt{9, 5, 13, 3, 7, 11, 15, 17, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18}},
   112  }
   113  
   114  var rootHashTestTable = []RootHashTest{
   115  	{"", K([]Felt{})},
   116  	{"532deabf88729cb43995ab5a9cd49bf9b90a079904dc0645ecda9e47ce7345a9", K([]Felt{1})},
   117  	{"d3782c59c224da5b6344108ef3431ba4e01d2c30b6570137a91b8b383908c361", K([]Felt{1, 2})},
   118  }
   119  
   120  var insertTestTable = []UpsertTest{
   121  	{K([]Felt{}), []Felt{}, K([]Felt{1}), []Felt{1}},
   122  	{K([]Felt{}), []Felt{}, K([]Felt{1, 2}), []Felt{1, 2}},
   123  	{K([]Felt{}), []Felt{}, K([]Felt{1, 2, 3}), []Felt{3, 1, 2, 3}},
   124  	{K([]Felt{}), []Felt{}, K([]Felt{1, 2, 3, 4}), []Felt{3, 1, 2, 3, 4}},
   125  
   126  	{K([]Felt{1}), []Felt{1}, K([]Felt{0}), []Felt{0, 1}},
   127  	{K([]Felt{1}), []Felt{1}, K([]Felt{2}), []Felt{1, 2}},
   128  	{K([]Felt{1}), []Felt{1}, K([]Felt{0, 2}), []Felt{2, 0, 1, 2}},
   129  	{K([]Felt{1}), []Felt{1}, K([]Felt{0, 2, 3}), []Felt{2, 0, 1, 2, 3}},
   130  	{K([]Felt{1}), []Felt{1}, K([]Felt{0, 2, 3, 4}), []Felt{2, 4, 0, 1, 2, 3, 4}},
   131  	{K([]Felt{2}), []Felt{2}, K([]Felt{0, 1, 3, 4}), []Felt{2, 4, 0, 1, 2, 3, 4}},
   132  	{K([]Felt{3}), []Felt{3}, K([]Felt{0, 1, 2, 4}), []Felt{2, 4, 0, 1, 2, 3, 4}},
   133  	{K([]Felt{4}), []Felt{4}, K([]Felt{0, 1, 2, 3}), []Felt{2, 4, 0, 1, 2, 3, 4}},
   134  
   135  	{K([]Felt{1, 2}), []Felt{1, 2}, K([]Felt{0}), []Felt{2, 0, 1, 2}},
   136  	{K([]Felt{1, 2}), []Felt{1, 2}, K([]Felt{0, 3}), []Felt{2, 0, 1, 2, 3}},
   137  	{K([]Felt{1, 2}), []Felt{1, 2}, K([]Felt{0, 3, 4}), []Felt{2, 4, 0, 1, 2, 3, 4}},
   138  	{K([]Felt{1, 2}), []Felt{1, 2}, K([]Felt{0, 3, 4, 5}), []Felt{2, 4, 0, 1, 2, 3, 4, 5}},
   139  	{K([]Felt{2, 3}), []Felt{2, 3}, K([]Felt{0}), []Felt{3, 0, 2, 3}},
   140  	{K([]Felt{2, 3}), []Felt{2, 3}, K([]Felt{0, 1}), []Felt{2, 0, 1, 2, 3}},
   141  	{K([]Felt{2, 3}), []Felt{2, 3}, K([]Felt{5}), []Felt{5, 2, 3, 5}},
   142  	{K([]Felt{2, 3}), []Felt{2, 3}, K([]Felt{4, 5}), []Felt{4, 2, 3, 4, 5}},
   143  	{K([]Felt{2, 3}), []Felt{2, 3}, K([]Felt{0, 4, 5}), []Felt{3, 5, 0, 2, 3, 4, 5}},
   144  	{K([]Felt{2, 3}), []Felt{2, 3}, K([]Felt{0, 1, 4, 5}), []Felt{2, 4, 0, 1, 2, 3, 4, 5}},
   145  	{K([]Felt{4, 5}), []Felt{4, 5}, K([]Felt{0}), []Felt{5, 0, 4, 5}},
   146  	{K([]Felt{4, 5}), []Felt{4, 5}, K([]Felt{0, 1}), []Felt{4, 0, 1, 4, 5}},
   147  	{K([]Felt{4, 5}), []Felt{4, 5}, K([]Felt{0, 1, 2}), []Felt{2, 5, 0, 1, 2, 4, 5}},
   148  	{K([]Felt{4, 5}), []Felt{4, 5}, K([]Felt{0, 1, 2, 3}), []Felt{2, 4, 0, 1, 2, 3, 4, 5}},
   149  	{K([]Felt{1, 4}), []Felt{1, 4}, K([]Felt{0}), []Felt{4, 0, 1, 4}},
   150  	{K([]Felt{1, 4}), []Felt{1, 4}, K([]Felt{0, 2}), []Felt{2, 0, 1, 2, 4}},
   151  	{K([]Felt{1, 4}), []Felt{1, 4}, K([]Felt{0, 2, 5}), []Felt{2, 5, 0, 1, 2, 4, 5}},
   152  	{K([]Felt{1, 4}), []Felt{1, 4}, K([]Felt{0, 2, 3, 5}), []Felt{2, 4, 0, 1, 2, 3, 4, 5}},
   153  
   154  	{K([]Felt{1, 3, 5}), []Felt{5, 1, 3, 5}, K([]Felt{0}), []Felt{3, 5, 0, 1, 3, 5}},
   155  	{K([]Felt{1, 3, 5}), []Felt{5, 1, 3, 5}, K([]Felt{0, 2, 4}), []Felt{4, 2, 5, 0, 1, 2, 3, 4, 5}},
   156  	{K([]Felt{1, 3, 5}), []Felt{5, 1, 3, 5}, K([]Felt{6, 7, 8}), []Felt{5, 7, 1, 3, 5, 6, 7, 8}},
   157  	{K([]Felt{1, 3, 5}), []Felt{5, 1, 3, 5}, K([]Felt{6, 7, 8, 9}), []Felt{7, 5, 9, 1, 3, 5, 6, 7, 8, 9}},
   158  
   159  	{K([]Felt{1, 2, 3, 4}), []Felt{3, 1, 2, 3, 4}, K([]Felt{0}), []Felt{2, 3, 0, 1, 2, 3, 4}},
   160  	{K([]Felt{1, 3, 5, 7}), []Felt{5, 1, 3, 5, 7}, K([]Felt{0}), []Felt{3, 5, 0, 1, 3, 5, 7}},
   161  
   162  	{K([]Felt{1, 3, 5, 7, 9}), []Felt{5, 9, 1, 3, 5, 7, 9}, K([]Felt{0}), []Felt{5, 3, 9, 0, 1, 3, 5, 7, 9}},
   163  
   164  	// Debug
   165  	{K([]Felt{1, 2, 3, 5, 6, 7, 8}), []Felt{6, 3, 8, 1, 2, 3, 5, 6, 7, 8}, K([]Felt{4}), []Felt{6, 3, 5, 8, 1, 2, 3, 4, 5, 6, 7, 8}},
   166  
   167  	{
   168  		K([]Felt{10, 15, 20}),
   169  		[]Felt{20, 10, 15, 20},
   170  		K([]Felt{1, 2, 3, 4, 5, 11, 13, 18, 19, 30, 31}),
   171  		[]Felt{15, 5, 20, 3, 11, 19, 31, 1, 2, 3, 4, 5, 10, 11, 13, 15, 18, 19, 20, 30, 31},
   172  	},
   173  
   174  	{
   175  		K([]Felt{0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20}),
   176  		[]Felt{8, 16, 4, 12, 20, 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20},
   177  		K([]Felt{1, 3, 5}),
   178  		[]Felt{8, 4, 16, 2, 6, 12, 20, 0, 1, 2, 3, 4, 5, 6, 8, 10, 12, 14, 16, 18, 20},
   179  	},
   180  
   181  	{
   182  		K([]Felt{4, 10, 17, 85, 104, 107, 112, 115, 136, 156, 191}),
   183  		[]Felt{104, 136, 17, 112, 191, 4, 10, 17, 85, 104, 107, 112, 115, 136, 156, 191},
   184  		K([]Felt{0, 96, 120, 129, 133, 164, 187, 189}),
   185  		nil,
   186  	},
   187  }
   188  
   189  var updateTestTable = []UpsertTest{
   190  	{K([]Felt{10}), []Felt{10}, KV([]Felt{10}, []Felt{100}), []Felt{10}},
   191  	{K([]Felt{10, 20}), []Felt{10, 20}, KV([]Felt{10, 20}, []Felt{100, 200}), []Felt{10, 20}},
   192  }
   193  
   194  var deleteTestTable = []DeleteTest{
   195  	/// POSITIVE TEST CASES
   196  	{K([]Felt{}), []Felt{}, []Felt{}, []Felt{}},
   197  
   198  	{K([]Felt{1}), []Felt{1}, []Felt{}, []Felt{1}},
   199  	{K([]Felt{1}), []Felt{1}, []Felt{1}, []Felt{}},
   200  
   201  	{K([]Felt{1, 2}), []Felt{1, 2}, []Felt{}, []Felt{1, 2}},
   202  	{K([]Felt{1, 2}), []Felt{1, 2}, []Felt{1}, []Felt{2}},
   203  	{K([]Felt{1, 2}), []Felt{1, 2}, []Felt{2}, []Felt{1}},
   204  	{K([]Felt{1, 2}), []Felt{1, 2}, []Felt{1, 2}, []Felt{}},
   205  
   206  	{K([]Felt{1, 2, 3}), []Felt{3, 1, 2, 3}, []Felt{}, []Felt{3, 1, 2, 3}},
   207  	{K([]Felt{1, 2, 3}), []Felt{3, 1, 2, 3}, []Felt{1}, []Felt{2, 3}},
   208  	{K([]Felt{1, 2, 3}), []Felt{3, 1, 2, 3}, []Felt{2}, []Felt{1, 3}},
   209  	{K([]Felt{1, 2, 3}), []Felt{3, 1, 2, 3}, []Felt{3}, []Felt{1, 2}},
   210  	{K([]Felt{1, 2, 3}), []Felt{3, 1, 2, 3}, []Felt{1, 2}, []Felt{3}},
   211  	{K([]Felt{1, 2, 3}), []Felt{3, 1, 2, 3}, []Felt{1, 3}, []Felt{2}},
   212  	{K([]Felt{1, 2, 3}), []Felt{3, 1, 2, 3}, []Felt{2, 3}, []Felt{1}},
   213  	{K([]Felt{1, 2, 3}), []Felt{3, 1, 2, 3}, []Felt{1, 2, 3}, []Felt{}},
   214  
   215  	{K([]Felt{1, 2, 3, 4}), []Felt{3, 1, 2, 3, 4}, []Felt{1}, []Felt{3, 2, 3, 4}},
   216  	{K([]Felt{1, 2, 3, 4}), []Felt{3, 1, 2, 3, 4}, []Felt{2}, []Felt{3, 1, 3, 4}},
   217  	{K([]Felt{1, 2, 3, 4}), []Felt{3, 1, 2, 3, 4}, []Felt{3}, []Felt{4, 1, 2, 4}},
   218  	{K([]Felt{1, 2, 3, 4}), []Felt{3, 1, 2, 3, 4}, []Felt{4}, []Felt{3, 1, 2, 3}},
   219  
   220  	{K([]Felt{1, 2, 3, 4, 5}), []Felt{3, 5, 1, 2, 3, 4, 5}, []Felt{1}, []Felt{3, 5, 2, 3, 4, 5}},
   221  	{K([]Felt{1, 2, 3, 4, 5}), []Felt{3, 5, 1, 2, 3, 4, 5}, []Felt{2}, []Felt{3, 5, 1, 3, 4, 5}},
   222  	{K([]Felt{1, 2, 3, 4, 5}), []Felt{3, 5, 1, 2, 3, 4, 5}, []Felt{3}, []Felt{4, 5, 1, 2, 4, 5}},
   223  	{K([]Felt{1, 2, 3, 4, 5}), []Felt{3, 5, 1, 2, 3, 4, 5}, []Felt{4}, []Felt{3, 5, 1, 2, 3, 5}},
   224  	{K([]Felt{1, 2, 3, 4, 5}), []Felt{3, 5, 1, 2, 3, 4, 5}, []Felt{5}, []Felt{3, 1, 2, 3, 4}},
   225  	{K([]Felt{1, 2, 3, 4, 5, 6, 7}), []Felt{5, 3, 7, 1, 2, 3, 4, 5, 6, 7}, []Felt{7}, []Felt{3, 5, 1, 2, 3, 4, 5, 6}},
   226  
   227  	{K([]Felt{16, 25, 155, 182, 184, 210, 215}), []Felt{184, 155, 215, 16, 25, 155, 182, 184, 210, 215}, []Felt{155, 182}, []Felt{184, 215, 16, 25, 184, 210, 215}},
   228  
   229  	/// NEGATIVE TEST CASES
   230  	{K([]Felt{}), []Felt{}, []Felt{1}, []Felt{}},
   231  	{K([]Felt{1}), []Felt{1}, []Felt{2}, []Felt{1}},
   232  	{K([]Felt{1, 2}), []Felt{1, 2}, []Felt{3}, []Felt{1, 2}},
   233  	{K([]Felt{1, 2, 3}), []Felt{3, 1, 2, 3}, []Felt{4}, []Felt{3, 1, 2, 3}},
   234  	{K([]Felt{1, 2, 3, 4}), []Felt{3, 1, 2, 3, 4}, []Felt{5}, []Felt{3, 1, 2, 3, 4}},
   235  	{K([]Felt{1, 2, 3, 4, 5}), []Felt{3, 5, 1, 2, 3, 4, 5}, []Felt{6}, []Felt{3, 5, 1, 2, 3, 4, 5}},
   236  
   237  	/// MIXED TEST CASES
   238  	{K([]Felt{0, 46, 50, 89, 134, 218}), []Felt{50, 134, 0, 46, 50, 89, 134, 218}, []Felt{46, 50, 89, 134, 218}, []Felt{0}},
   239  }
   240  
   241  func TestHeight(t *testing.T) {
   242  	for _, data := range heightTestTable {
   243  		tree := NewTree23(data.initialItems)
   244  		assert.Equal(t, data.expectedHeight, tree.Height(), "different height")
   245  	}
   246  }
   247  
   248  func TestIs23Tree(t *testing.T) {
   249  	for _, data := range isTree23TestTable {
   250  		tree := NewTree23(data.initialItems)
   251  		//tree.GraphAndPicture("is23Tree")
   252  		assertTwoThreeTree(t, tree, data.expectedKeysLevelOrder)
   253  	}
   254  }
   255  
   256  func Test23TreeSeries(t *testing.T) {
   257  	maxNumberOfNodes := 100
   258  	for i := 0; i < maxNumberOfNodes; i++ {
   259  		kvPairs := KeyValues{make([]*Felt, 0), make([]*Felt, 0)}
   260  		for j := 0; j < i; j++ {
   261  			key, value := Felt(j), Felt(j)
   262  			kvPairs.keys = append(kvPairs.keys, &key)
   263  			kvPairs.values = append(kvPairs.values, &value)
   264  		}
   265  		tree := NewTree23(kvPairs)
   266  		assertTwoThreeTree(t, tree, nil)
   267  	}
   268  }
   269  
   270  func TestRootHash(t *testing.T) {
   271  	for _, data := range rootHashTestTable {
   272  		tree := NewTree23(data.initialItems)
   273  		assert.Equal(t, data.expectedHash, hex.EncodeToString(tree.RootHash()), "different root hash")
   274  	}
   275  }
   276  
   277  func TestUpsertInsert(t *testing.T) {
   278  	for _, data := range insertTestTable {
   279  		tree := NewTree23(data.initialItems)
   280  		assertTwoThreeTree(t, tree, data.initialKeysLevelOrder)
   281  		//tree.GraphAndPicture("tree_step1")
   282  		tree.Upsert(data.deltaItems)
   283  		//tree.GraphAndPicture("tree_step2")
   284  		assertTwoThreeTree(t, tree, data.finalKeysLevelOrder)
   285  	}
   286  }
   287  
   288  func TestUpsertUpdate(t *testing.T) {
   289  	for _, data := range updateTestTable {
   290  		tree := NewTree23(data.initialItems)
   291  		assertTwoThreeTree(t, tree, data.initialKeysLevelOrder)
   292  		// TODO: add check for old values
   293  		tree.Upsert(data.deltaItems)
   294  		assertTwoThreeTree(t, tree, data.finalKeysLevelOrder)
   295  		// TODO: add check for new values
   296  	}
   297  }
   298  
   299  func TestUpsertIdempotent(t *testing.T) {
   300  	for _, data := range isTree23TestTable {
   301  		tree := NewTree23(data.initialItems)
   302  		assertTwoThreeTree(t, tree, data.expectedKeysLevelOrder)
   303  		tree.Upsert(data.initialItems)
   304  		assertTwoThreeTree(t, tree, data.expectedKeysLevelOrder)
   305  	}
   306  }
   307  
   308  func TestUpsertNextKey(t *testing.T) {
   309  	dataCount := 4
   310  	data := KeyValues{make([]*Felt, dataCount), make([]*Felt, dataCount)}
   311  	for i := 0; i < dataCount; i++ {
   312  		key, value := Felt(i*2), Felt(i*2)
   313  		data.keys[i], data.values[i] = &key, &value
   314  	}
   315  	tn := NewTree23(data)
   316  	//tn.GraphAndPicture("tn1")
   317  
   318  	for i := 0; i < dataCount; i++ {
   319  		key, value := Felt(i*2+1), Felt(i*2+1)
   320  		data.keys[i], data.values[i] = &key, &value
   321  	}
   322  	tn = tn.Upsert(data)
   323  	//tn.GraphAndPicture("tn2")
   324  	assertTwoThreeTree(t, tn, []Felt{4, 2, 6, 0, 1, 2, 3, 4, 5, 6, 7})
   325  
   326  	data = K([]Felt{100, 101, 200, 201, 202})
   327  	tn = tn.Upsert(data)
   328  	//tn.GraphAndPicture("tn3")
   329  	assertTwoThreeTree(t, tn, []Felt{4, 100, 2, 6, 200, 202, 0, 1, 2, 3, 4, 5, 6, 7, 100, 101, 200, 201, 202})
   330  
   331  	data = K([]Felt{10, 150, 250, 251, 252})
   332  	tn = tn.Upsert(data)
   333  	//tn.GraphAndPicture("tn4")
   334  	assertTwoThreeTree(t, tn, []Felt{100, 4, 200, 2, 6, 10, 150, 202, 251, 0, 1, 2, 3, 4, 5, 6, 7, 10, 100, 101, 150, 200, 201, 202, 250, 251, 252})
   335  }
   336  
   337  func TestUpsertFirstKey(t *testing.T) {
   338  }
   339  
   340  func TestDelete(t *testing.T) {
   341  	for _, data := range deleteTestTable {
   342  		tree := NewTree23(data.initialItems)
   343  		assertTwoThreeTree(t, tree, data.initialKeysLevelOrder)
   344  		//tree.GraphAndPicture("tree_delete1")
   345  		tree.Delete(data.keysToDelete)
   346  		//tree.GraphAndPicture("tree_delete2")
   347  		assertTwoThreeTree(t, tree, data.finalKeysLevelOrder)
   348  	}
   349  }
   350  
   351  func FuzzUpsert(f *testing.F) {
   352  	f.Fuzz(func(t *testing.T, input1, input2 []byte) {
   353  		//t.Parallel()
   354  		keyFactory := NewKeyBinaryFactory(1)
   355  		bytesReader1 := bytes.NewReader(input1)
   356  		kvStatePairs := keyFactory.NewUniqueKeyValues(bufio.NewReader(bytesReader1))
   357  		require.True(t, sort.IsSorted(kvStatePairs), "kvStatePairs is not sorted")
   358  		bytesReader2 := bytes.NewReader(input2)
   359  		kvStateChangesPairs := keyFactory.NewUniqueKeyValues(bufio.NewReader(bytesReader2))
   360  		//fmt.Printf("kvStatePairs=%v kvStateChangesPairs=%v\n", kvStatePairs, kvStateChangesPairs)
   361  		require.True(t, sort.IsSorted(kvStateChangesPairs), "kvStateChangesPairs is not sorted")
   362  		tree := NewTree23(kvStatePairs)
   363  		//tree.GraphAndPicture("fuzz_tree_upsert1")
   364  		assertTwoThreeTree(t, tree, nil)
   365  		tree = tree.Upsert(kvStateChangesPairs)
   366  		//tree.GraphAndPicture("fuzz_tree_upsert2")
   367  		assertTwoThreeTree(t, tree, nil)
   368  	})
   369  }
   370  
   371  func FuzzDelete(f *testing.F) {
   372  	f.Fuzz(func(t *testing.T, input1, input2 []byte) {
   373  		//t.Parallel()
   374  		//fmt.Printf("input1=%v input2=%v\n", input1, input2)
   375  		keyFactory := NewKeyBinaryFactory(1)
   376  		bytesReader1 := bytes.NewReader(input1)
   377  		kvStatePairs := keyFactory.NewUniqueKeyValues(bufio.NewReader(bytesReader1))
   378  		require.True(t, sort.IsSorted(kvStatePairs), "kvStatePairs is not sorted")
   379  		bytesReader2 := bytes.NewReader(input2)
   380  		keysToDelete := keyFactory.NewUniqueKeys(bufio.NewReader(bytesReader2))
   381  		//fmt.Printf("kvStatePairs=%v keysToDelete=%v\n", kvStatePairs, keysToDelete)
   382  		require.True(t, sort.IsSorted(keysToDelete), "keysToDelete is not sorted")
   383  		tree1 := NewTree23(kvStatePairs)
   384  		//tree1.GraphAndPicture("fuzz_tree_delete1")
   385  		require23Tree(t, tree1, nil, input1, input2)
   386  		tree2 := tree1.Delete(keysToDelete)
   387  		//tree2.GraphAndPicture("fuzz_tree_delete2")
   388  		require23Tree(t, tree2, nil, input1, input2)
   389  		// TODO: check the difference properties
   390  		// Check that *each* T1 node is present either in Td or in T2
   391  		// Check that *each* T2 node is not present in Td
   392  		// Check that *each* Td node is present in T1 but not in T2
   393  	})
   394  }
   395  
   396  func BenchmarkNewTree23(b *testing.B) {
   397  	const dataCount = 1_000_000
   398  	data := KeyValues{make([]*Felt, dataCount), make([]*Felt, dataCount)}
   399  	for i := 0; i < dataCount; i++ {
   400  		key, value := Felt(i*2), Felt(i*2)
   401  		data.keys[i], data.values[i] = &key, &value
   402  	}
   403  	b.ResetTimer()
   404  	for i := 0; i < b.N; i++ {
   405  		NewTree23(data)
   406  	}
   407  }
   408  
   409  func BenchmarkUpsert(b *testing.B) {
   410  	dataCount := 5_000_000
   411  	data := KeyValues{make([]*Felt, dataCount), make([]*Felt, dataCount)}
   412  	for i := 0; i < dataCount; i++ {
   413  		key, value := Felt(i*2), Felt(i*2)
   414  		data.keys[i], data.values[i] = &key, &value
   415  	}
   416  	tree := NewTree23(data)
   417  	dataCount = 500_000
   418  	data = KeyValues{make([]*Felt, dataCount), make([]*Felt, dataCount)}
   419  	for i := 0; i < dataCount; i++ {
   420  		key, value := Felt(i*2+1), Felt(i*2+1)
   421  		data.keys[i], data.values[i] = &key, &value
   422  	}
   423  	b.ResetTimer()
   424  	for i := 0; i < b.N; i++ {
   425  		tree.Upsert(data)
   426  	}
   427  }