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 }