erigon-pulse/bptree/tree_test.go
canepat e58d0fa537
Add B+ tree prototype implementation (#258)
* Add B+ tree prototype implementation

* Add Apache license header to all files
Fix linter errors
2022-01-21 07:06:09 +00:00

429 lines
16 KiB
Go

//go:build gofuzzbeta
// +build gofuzzbeta
/*
Copyright 2022 Erigon contributors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package bptree
import (
"bufio"
"bytes"
"encoding/hex"
"sort"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func assertTwoThreeTree(t *testing.T, tree *Tree23, expectedKeysLevelOrder []Felt) {
treeValid, err := tree.IsValid()
assert.True(t, treeValid, "2-3-tree properties do not hold for tree: %v, error: %v", tree.KeysInLevelOrder(), err)
if expectedKeysLevelOrder != nil {
assert.Equal(t, expectedKeysLevelOrder, tree.KeysInLevelOrder(), "different keys by level")
}
}
func require23Tree(t *testing.T, tree *Tree23, expectedKeysLevelOrder []Felt, input1, input2 []byte) {
treeValid, err := tree.IsValid()
require.True(t, treeValid, "2-3-tree properties do not hold: input [%v %v] [%+q %+q], error: %v",
input1, input2, string(input1), string(input2), err)
if expectedKeysLevelOrder != nil {
assert.Equal(t, expectedKeysLevelOrder, tree.KeysInLevelOrder(), "different keys by level")
}
}
type HeightTest struct {
initialItems KeyValues
expectedHeight int
}
type IsTree23Test struct {
initialItems KeyValues
expectedKeysLevelOrder []Felt
}
type RootHashTest struct {
initialItems KeyValues
expectedHash string
}
type UpsertTest struct {
initialItems KeyValues
initialKeysLevelOrder []Felt
deltaItems KeyValues
finalKeysLevelOrder []Felt
}
type DeleteTest struct {
initialItems KeyValues
initialKeysLevelOrder []Felt
keysToDelete []Felt
finalKeysLevelOrder []Felt
}
func K(keys []Felt) KeyValues {
values := make([]Felt, len(keys))
copy(values, keys)
return KV(keys, values)
}
var heightTestTable = []HeightTest{
{K([]Felt{}), 0},
{K([]Felt{1}), 1},
{K([]Felt{1, 2}), 1},
{K([]Felt{1, 2, 3}), 2},
{K([]Felt{1, 2, 3, 4}), 2},
{K([]Felt{1, 2, 3, 4, 5}), 2},
{K([]Felt{1, 2, 3, 4, 5, 6}), 2},
{K([]Felt{1, 2, 3, 4, 5, 6, 7}), 3},
{K([]Felt{1, 2, 3, 4, 5, 6, 7, 8}), 3},
}
var isTree23TestTable = []IsTree23Test{
{K([]Felt{}), []Felt{}},
{K([]Felt{1}), []Felt{1}},
{K([]Felt{1, 2}), []Felt{1, 2}},
{K([]Felt{1, 2, 3}), []Felt{3, 1, 2, 3}},
{K([]Felt{1, 2, 3, 4}), []Felt{3, 1, 2, 3, 4}},
{K([]Felt{1, 2, 3, 4, 5}), []Felt{3, 5, 1, 2, 3, 4, 5}},
{K([]Felt{1, 2, 3, 4, 5, 6}), []Felt{3, 5, 1, 2, 3, 4, 5, 6}},
{K([]Felt{1, 2, 3, 4, 5, 6, 7}), []Felt{5, 3, 7, 1, 2, 3, 4, 5, 6, 7}},
{K([]Felt{1, 2, 3, 4, 5, 6, 7, 8}), []Felt{5, 3, 7, 1, 2, 3, 4, 5, 6, 7, 8}},
{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}},
{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}},
{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}},
{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}},
{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}},
{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}},
}
var rootHashTestTable = []RootHashTest{
{K([]Felt{}), ""},
{K([]Felt{1}), "532deabf88729cb43995ab5a9cd49bf9b90a079904dc0645ecda9e47ce7345a9"},
{K([]Felt{1, 2}), "d3782c59c224da5b6344108ef3431ba4e01d2c30b6570137a91b8b383908c361"},
}
var insertTestTable = []UpsertTest{
{K([]Felt{}), []Felt{}, K([]Felt{1}), []Felt{1}},
{K([]Felt{}), []Felt{}, K([]Felt{1, 2}), []Felt{1, 2}},
{K([]Felt{}), []Felt{}, K([]Felt{1, 2, 3}), []Felt{3, 1, 2, 3}},
{K([]Felt{}), []Felt{}, K([]Felt{1, 2, 3, 4}), []Felt{3, 1, 2, 3, 4}},
{K([]Felt{1}), []Felt{1}, K([]Felt{0}), []Felt{0, 1}},
{K([]Felt{1}), []Felt{1}, K([]Felt{2}), []Felt{1, 2}},
{K([]Felt{1}), []Felt{1}, K([]Felt{0, 2}), []Felt{2, 0, 1, 2}},
{K([]Felt{1}), []Felt{1}, K([]Felt{0, 2, 3}), []Felt{2, 0, 1, 2, 3}},
{K([]Felt{1}), []Felt{1}, K([]Felt{0, 2, 3, 4}), []Felt{2, 4, 0, 1, 2, 3, 4}},
{K([]Felt{2}), []Felt{2}, K([]Felt{0, 1, 3, 4}), []Felt{2, 4, 0, 1, 2, 3, 4}},
{K([]Felt{3}), []Felt{3}, K([]Felt{0, 1, 2, 4}), []Felt{2, 4, 0, 1, 2, 3, 4}},
{K([]Felt{4}), []Felt{4}, K([]Felt{0, 1, 2, 3}), []Felt{2, 4, 0, 1, 2, 3, 4}},
{K([]Felt{1, 2}), []Felt{1, 2}, K([]Felt{0}), []Felt{2, 0, 1, 2}},
{K([]Felt{1, 2}), []Felt{1, 2}, K([]Felt{0, 3}), []Felt{2, 0, 1, 2, 3}},
{K([]Felt{1, 2}), []Felt{1, 2}, K([]Felt{0, 3, 4}), []Felt{2, 4, 0, 1, 2, 3, 4}},
{K([]Felt{1, 2}), []Felt{1, 2}, K([]Felt{0, 3, 4, 5}), []Felt{2, 4, 0, 1, 2, 3, 4, 5}},
{K([]Felt{2, 3}), []Felt{2, 3}, K([]Felt{0}), []Felt{3, 0, 2, 3}},
{K([]Felt{2, 3}), []Felt{2, 3}, K([]Felt{0, 1}), []Felt{2, 0, 1, 2, 3}},
{K([]Felt{2, 3}), []Felt{2, 3}, K([]Felt{5}), []Felt{5, 2, 3, 5}},
{K([]Felt{2, 3}), []Felt{2, 3}, K([]Felt{4, 5}), []Felt{4, 2, 3, 4, 5}},
{K([]Felt{2, 3}), []Felt{2, 3}, K([]Felt{0, 4, 5}), []Felt{3, 5, 0, 2, 3, 4, 5}},
{K([]Felt{2, 3}), []Felt{2, 3}, K([]Felt{0, 1, 4, 5}), []Felt{2, 4, 0, 1, 2, 3, 4, 5}},
{K([]Felt{4, 5}), []Felt{4, 5}, K([]Felt{0}), []Felt{5, 0, 4, 5}},
{K([]Felt{4, 5}), []Felt{4, 5}, K([]Felt{0, 1}), []Felt{4, 0, 1, 4, 5}},
{K([]Felt{4, 5}), []Felt{4, 5}, K([]Felt{0, 1, 2}), []Felt{2, 5, 0, 1, 2, 4, 5}},
{K([]Felt{4, 5}), []Felt{4, 5}, K([]Felt{0, 1, 2, 3}), []Felt{2, 4, 0, 1, 2, 3, 4, 5}},
{K([]Felt{1, 4}), []Felt{1, 4}, K([]Felt{0}), []Felt{4, 0, 1, 4}},
{K([]Felt{1, 4}), []Felt{1, 4}, K([]Felt{0, 2}), []Felt{2, 0, 1, 2, 4}},
{K([]Felt{1, 4}), []Felt{1, 4}, K([]Felt{0, 2, 5}), []Felt{2, 5, 0, 1, 2, 4, 5}},
{K([]Felt{1, 4}), []Felt{1, 4}, K([]Felt{0, 2, 3, 5}), []Felt{2, 4, 0, 1, 2, 3, 4, 5}},
{K([]Felt{1, 3, 5}), []Felt{5, 1, 3, 5}, K([]Felt{0}), []Felt{3, 5, 0, 1, 3, 5}},
{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}},
{K([]Felt{1, 3, 5}), []Felt{5, 1, 3, 5}, K([]Felt{6, 7, 8}), []Felt{5, 7, 1, 3, 5, 6, 7, 8}},
{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}},
{K([]Felt{1, 2, 3, 4}), []Felt{3, 1, 2, 3, 4}, K([]Felt{0}), []Felt{2, 3, 0, 1, 2, 3, 4}},
{K([]Felt{1, 3, 5, 7}), []Felt{5, 1, 3, 5, 7}, K([]Felt{0}), []Felt{3, 5, 0, 1, 3, 5, 7}},
{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}},
// Debug
{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}},
{
K([]Felt{10, 15, 20}),
[]Felt{20, 10, 15, 20},
K([]Felt{1, 2, 3, 4, 5, 11, 13, 18, 19, 30, 31}),
[]Felt{15, 5, 20, 3, 11, 19, 31, 1, 2, 3, 4, 5, 10, 11, 13, 15, 18, 19, 20, 30, 31},
},
{
K([]Felt{0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20}),
[]Felt{8, 16, 4, 12, 20, 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20},
K([]Felt{1, 3, 5}),
[]Felt{8, 4, 16, 2, 6, 12, 20, 0, 1, 2, 3, 4, 5, 6, 8, 10, 12, 14, 16, 18, 20},
},
{
K([]Felt{4, 10, 17, 85, 104, 107, 112, 115, 136, 156, 191}),
[]Felt{104, 136, 17, 112, 191, 4, 10, 17, 85, 104, 107, 112, 115, 136, 156, 191},
K([]Felt{0, 96, 120, 129, 133, 164, 187, 189}),
nil,
},
}
var updateTestTable = []UpsertTest{
{K([]Felt{10}), []Felt{10}, KV([]Felt{10}, []Felt{100}), []Felt{10}},
{K([]Felt{10, 20}), []Felt{10, 20}, KV([]Felt{10, 20}, []Felt{100, 200}), []Felt{10, 20}},
}
var deleteTestTable = []DeleteTest{
/// POSITIVE TEST CASES
{K([]Felt{}), []Felt{}, []Felt{}, []Felt{}},
{K([]Felt{1}), []Felt{1}, []Felt{}, []Felt{1}},
{K([]Felt{1}), []Felt{1}, []Felt{1}, []Felt{}},
{K([]Felt{1, 2}), []Felt{1, 2}, []Felt{}, []Felt{1, 2}},
{K([]Felt{1, 2}), []Felt{1, 2}, []Felt{1}, []Felt{2}},
{K([]Felt{1, 2}), []Felt{1, 2}, []Felt{2}, []Felt{1}},
{K([]Felt{1, 2}), []Felt{1, 2}, []Felt{1, 2}, []Felt{}},
{K([]Felt{1, 2, 3}), []Felt{3, 1, 2, 3}, []Felt{}, []Felt{3, 1, 2, 3}},
{K([]Felt{1, 2, 3}), []Felt{3, 1, 2, 3}, []Felt{1}, []Felt{2, 3}},
{K([]Felt{1, 2, 3}), []Felt{3, 1, 2, 3}, []Felt{2}, []Felt{1, 3}},
{K([]Felt{1, 2, 3}), []Felt{3, 1, 2, 3}, []Felt{3}, []Felt{1, 2}},
{K([]Felt{1, 2, 3}), []Felt{3, 1, 2, 3}, []Felt{1, 2}, []Felt{3}},
{K([]Felt{1, 2, 3}), []Felt{3, 1, 2, 3}, []Felt{1, 3}, []Felt{2}},
{K([]Felt{1, 2, 3}), []Felt{3, 1, 2, 3}, []Felt{2, 3}, []Felt{1}},
{K([]Felt{1, 2, 3}), []Felt{3, 1, 2, 3}, []Felt{1, 2, 3}, []Felt{}},
{K([]Felt{1, 2, 3, 4}), []Felt{3, 1, 2, 3, 4}, []Felt{1}, []Felt{3, 2, 3, 4}},
{K([]Felt{1, 2, 3, 4}), []Felt{3, 1, 2, 3, 4}, []Felt{2}, []Felt{3, 1, 3, 4}},
{K([]Felt{1, 2, 3, 4}), []Felt{3, 1, 2, 3, 4}, []Felt{3}, []Felt{4, 1, 2, 4}},
{K([]Felt{1, 2, 3, 4}), []Felt{3, 1, 2, 3, 4}, []Felt{4}, []Felt{3, 1, 2, 3}},
{K([]Felt{1, 2, 3, 4, 5}), []Felt{3, 5, 1, 2, 3, 4, 5}, []Felt{1}, []Felt{3, 5, 2, 3, 4, 5}},
{K([]Felt{1, 2, 3, 4, 5}), []Felt{3, 5, 1, 2, 3, 4, 5}, []Felt{2}, []Felt{3, 5, 1, 3, 4, 5}},
{K([]Felt{1, 2, 3, 4, 5}), []Felt{3, 5, 1, 2, 3, 4, 5}, []Felt{3}, []Felt{4, 5, 1, 2, 4, 5}},
{K([]Felt{1, 2, 3, 4, 5}), []Felt{3, 5, 1, 2, 3, 4, 5}, []Felt{4}, []Felt{3, 5, 1, 2, 3, 5}},
{K([]Felt{1, 2, 3, 4, 5}), []Felt{3, 5, 1, 2, 3, 4, 5}, []Felt{5}, []Felt{3, 1, 2, 3, 4}},
{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}},
{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}},
/// NEGATIVE TEST CASES
{K([]Felt{}), []Felt{}, []Felt{1}, []Felt{}},
{K([]Felt{1}), []Felt{1}, []Felt{2}, []Felt{1}},
{K([]Felt{1, 2}), []Felt{1, 2}, []Felt{3}, []Felt{1, 2}},
{K([]Felt{1, 2, 3}), []Felt{3, 1, 2, 3}, []Felt{4}, []Felt{3, 1, 2, 3}},
{K([]Felt{1, 2, 3, 4}), []Felt{3, 1, 2, 3, 4}, []Felt{5}, []Felt{3, 1, 2, 3, 4}},
{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}},
/// MIXED TEST CASES
{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}},
}
func TestHeight(t *testing.T) {
for _, data := range heightTestTable {
tree := NewTree23(data.initialItems)
assert.Equal(t, data.expectedHeight, tree.Height(), "different height")
}
}
func TestIs23Tree(t *testing.T) {
for _, data := range isTree23TestTable {
tree := NewTree23(data.initialItems)
//tree.GraphAndPicture("is23Tree")
assertTwoThreeTree(t, tree, data.expectedKeysLevelOrder)
}
}
func Test23TreeSeries(t *testing.T) {
maxNumberOfNodes := 100
for i := 0; i < maxNumberOfNodes; i++ {
kvPairs := KeyValues{make([]*Felt, 0), make([]*Felt, 0)}
for j := 0; j < i; j++ {
key, value := Felt(j), Felt(j)
kvPairs.keys = append(kvPairs.keys, &key)
kvPairs.values = append(kvPairs.values, &value)
}
tree := NewTree23(kvPairs)
assertTwoThreeTree(t, tree, nil)
}
}
func TestRootHash(t *testing.T) {
for _, data := range rootHashTestTable {
tree := NewTree23(data.initialItems)
assert.Equal(t, data.expectedHash, hex.EncodeToString(tree.RootHash()), "different root hash")
}
}
func TestUpsertInsert(t *testing.T) {
for _, data := range insertTestTable {
tree := NewTree23(data.initialItems)
assertTwoThreeTree(t, tree, data.initialKeysLevelOrder)
//tree.GraphAndPicture("tree_step1")
tree.Upsert(data.deltaItems)
//tree.GraphAndPicture("tree_step2")
assertTwoThreeTree(t, tree, data.finalKeysLevelOrder)
}
}
func TestUpsertUpdate(t *testing.T) {
for _, data := range updateTestTable {
tree := NewTree23(data.initialItems)
assertTwoThreeTree(t, tree, data.initialKeysLevelOrder)
// TODO: add check for old values
tree.Upsert(data.deltaItems)
assertTwoThreeTree(t, tree, data.finalKeysLevelOrder)
// TODO: add check for new values
}
}
func TestUpsertIdempotent(t *testing.T) {
for _, data := range isTree23TestTable {
tree := NewTree23(data.initialItems)
assertTwoThreeTree(t, tree, data.expectedKeysLevelOrder)
tree.Upsert(data.initialItems)
assertTwoThreeTree(t, tree, data.expectedKeysLevelOrder)
}
}
func TestUpsertNextKey(t *testing.T) {
dataCount := 4
data := KeyValues{make([]*Felt, dataCount), make([]*Felt, dataCount)}
for i := 0; i < dataCount; i++ {
key, value := Felt(i*2), Felt(i*2)
data.keys[i], data.values[i] = &key, &value
}
tn := NewTree23(data)
//tn.GraphAndPicture("tn1")
for i := 0; i < dataCount; i++ {
key, value := Felt(i*2+1), Felt(i*2+1)
data.keys[i], data.values[i] = &key, &value
}
tn = tn.Upsert(data)
//tn.GraphAndPicture("tn2")
assertTwoThreeTree(t, tn, []Felt{4, 2, 6, 0, 1, 2, 3, 4, 5, 6, 7})
data = K([]Felt{100, 101, 200, 201, 202})
tn = tn.Upsert(data)
//tn.GraphAndPicture("tn3")
assertTwoThreeTree(t, tn, []Felt{4, 100, 2, 6, 200, 202, 0, 1, 2, 3, 4, 5, 6, 7, 100, 101, 200, 201, 202})
data = K([]Felt{10, 150, 250, 251, 252})
tn = tn.Upsert(data)
//tn.GraphAndPicture("tn4")
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})
}
func TestUpsertFirstKey(t *testing.T) {
}
func TestDelete(t *testing.T) {
for _, data := range deleteTestTable {
tree := NewTree23(data.initialItems)
assertTwoThreeTree(t, tree, data.initialKeysLevelOrder)
//tree.GraphAndPicture("tree_delete1")
tree.Delete(data.keysToDelete)
//tree.GraphAndPicture("tree_delete2")
assertTwoThreeTree(t, tree, data.finalKeysLevelOrder)
}
}
func FuzzUpsert(f *testing.F) {
f.Fuzz(func(t *testing.T, input1, input2 []byte) {
//t.Parallel()
keyFactory := NewKeyBinaryFactory(1)
bytesReader1 := bytes.NewReader(input1)
kvStatePairs := keyFactory.NewUniqueKeyValues(bufio.NewReader(bytesReader1))
require.True(t, sort.IsSorted(kvStatePairs), "kvStatePairs is not sorted")
bytesReader2 := bytes.NewReader(input2)
kvStateChangesPairs := keyFactory.NewUniqueKeyValues(bufio.NewReader(bytesReader2))
//fmt.Printf("kvStatePairs=%v kvStateChangesPairs=%v\n", kvStatePairs, kvStateChangesPairs)
require.True(t, sort.IsSorted(kvStateChangesPairs), "kvStateChangesPairs is not sorted")
tree := NewTree23(kvStatePairs)
//tree.GraphAndPicture("fuzz_tree_upsert1")
assertTwoThreeTree(t, tree, nil)
tree = tree.Upsert(kvStateChangesPairs)
//tree.GraphAndPicture("fuzz_tree_upsert2")
assertTwoThreeTree(t, tree, nil)
})
}
func FuzzDelete(f *testing.F) {
f.Fuzz(func(t *testing.T, input1, input2 []byte) {
//t.Parallel()
//fmt.Printf("input1=%v input2=%v\n", input1, input2)
keyFactory := NewKeyBinaryFactory(1)
bytesReader1 := bytes.NewReader(input1)
kvStatePairs := keyFactory.NewUniqueKeyValues(bufio.NewReader(bytesReader1))
require.True(t, sort.IsSorted(kvStatePairs), "kvStatePairs is not sorted")
bytesReader2 := bytes.NewReader(input2)
keysToDelete := keyFactory.NewUniqueKeys(bufio.NewReader(bytesReader2))
//fmt.Printf("kvStatePairs=%v keysToDelete=%v\n", kvStatePairs, keysToDelete)
require.True(t, sort.IsSorted(Keys(keysToDelete)), "keysToDelete is not sorted")
tree1 := NewTree23(kvStatePairs)
//tree1.GraphAndPicture("fuzz_tree_delete1")
require23Tree(t, tree1, nil, input1, input2)
tree2 := tree1.Delete(keysToDelete)
//tree2.GraphAndPicture("fuzz_tree_delete2")
require23Tree(t, tree2, nil, input1, input2)
// TODO: check the difference properties
// Check that *each* T1 node is present either in Td or in T2
// Check that *each* T2 node is not present in Td
// Check that *each* Td node is present in T1 but not in T2
})
}
func BenchmarkNewTree23(b *testing.B) {
const dataCount = 1_000_000
data := KeyValues{make([]*Felt, dataCount), make([]*Felt, dataCount)}
for i := 0; i < dataCount; i++ {
key, value := Felt(i*2), Felt(i*2)
data.keys[i], data.values[i] = &key, &value
}
b.ResetTimer()
for i := 0; i < b.N; i++ {
NewTree23(data)
}
}
func BenchmarkUpsert(b *testing.B) {
dataCount := 5_000_000
data := KeyValues{make([]*Felt, dataCount), make([]*Felt, dataCount)}
for i := 0; i < dataCount; i++ {
key, value := Felt(i*2), Felt(i*2)
data.keys[i], data.values[i] = &key, &value
}
tree := NewTree23(data)
dataCount = 500_000
data = KeyValues{make([]*Felt, dataCount), make([]*Felt, dataCount)}
for i := 0; i < dataCount; i++ {
key, value := Felt(i*2+1), Felt(i*2+1)
data.keys[i], data.values[i] = &key, &value
}
b.ResetTimer()
for i := 0; i < b.N; i++ {
tree.Upsert(data)
}
}