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 }