github.com/onflow/atree@v0.6.0/map.go (about) 1 /* 2 * Atree - Scalable Arrays and Ordered Maps 3 * 4 * Copyright 2021 Dapper Labs, Inc. 5 * 6 * Licensed under the Apache License, Version 2.0 (the "License"); 7 * you may not use this file except in compliance with the License. 8 * You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, software 13 * distributed under the License is distributed on an "AS IS" BASIS, 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 * See the License for the specific language governing permissions and 16 * limitations under the License. 17 */ 18 19 package atree 20 21 import ( 22 "encoding/binary" 23 "errors" 24 "fmt" 25 "math" 26 "strings" 27 28 "github.com/fxamacker/cbor/v2" 29 "github.com/fxamacker/circlehash" 30 ) 31 32 const ( 33 digestSize = 8 34 35 // single element prefix size: CBOR array header (1 byte) 36 singleElementPrefixSize = 1 37 38 // inline collision group prefix size: CBOR tag number (2 bytes) 39 inlineCollisionGroupPrefixSize = 2 40 41 // external collision group prefix size: CBOR tag number (2 bytes) 42 externalCollisionGroupPrefixSize = 2 43 44 // hkey elements prefix size: 45 // CBOR array header (1 byte) + level (1 byte) + hkeys byte string header (9 bytes) + elements array header (9 bytes) 46 hkeyElementsPrefixSize = 1 + 1 + 9 + 9 47 48 // single elements prefix size: 49 // CBOR array header (1 byte) + encoded level (1 byte) + hkeys byte string header (1 bytes) + elements array header (9 bytes) 50 singleElementsPrefixSize = 1 + 1 + 1 + 9 51 52 // slab header size: storage id (16 bytes) + size (4 bytes) + first digest (8 bytes) 53 mapSlabHeaderSize = storageIDSize + 4 + digestSize 54 55 // meta data slab prefix size: version (1 byte) + flag (1 byte) + child header count (2 bytes) 56 mapMetaDataSlabPrefixSize = 1 + 1 + 2 57 58 // version (1 byte) + flag (1 byte) + next id (16 bytes) 59 mapDataSlabPrefixSize = 2 + storageIDSize 60 61 // version (1 byte) + flag (1 byte) 62 mapRootDataSlabPrefixSize = 2 63 64 // maxDigestLevel is max levels of 64-bit digests allowed 65 maxDigestLevel = 8 66 67 // typicalRandomConstant is a 64-bit value that has qualities 68 // of a typical random value (e.g. hamming weight, number of 69 // consecutive groups of 1-bits, etc.) so it can be useful as 70 // a const part of a seed, round constant inside a permutation, etc. 71 // CAUTION: We only store 64-bit seed, so some hashes with 64-bit seed like 72 // CircleHash64f don't use this const. However, other hashes such as 73 // CircleHash64fx and SipHash might use this const as part of their 74 // 128-bit seed (when they don't use 64-bit -> 128-bit seed expansion func). 75 typicalRandomConstant = uint64(0x1BD11BDAA9FC1A22) // DO NOT MODIFY 76 ) 77 78 // MaxCollisionLimitPerDigest is the noncryptographic hash collision limit 79 // (per digest per map) we enforce in the first level. In the same map 80 // for the same digest, having a non-intentional collision should be rare and 81 // several collisions should be extremely rare. The default limit should 82 // be high enough to ignore accidental collisions while mitigating attacks. 83 var MaxCollisionLimitPerDigest = uint32(255) 84 85 type MapKey Storable 86 87 type MapValue Storable 88 89 // element is one indivisible unit that must stay together (e.g. collision group) 90 type element interface { 91 fmt.Stringer 92 93 Get( 94 storage SlabStorage, 95 digester Digester, 96 level uint, 97 hkey Digest, 98 comparator ValueComparator, 99 key Value, 100 ) (MapValue, error) 101 102 // Set returns updated element, which may be a different type of element because of hash collision. 103 Set( 104 storage SlabStorage, 105 address Address, 106 b DigesterBuilder, 107 digester Digester, 108 level uint, 109 hkey Digest, 110 comparator ValueComparator, 111 hip HashInputProvider, 112 key Value, 113 value Value, 114 ) (newElem element, existingValue MapValue, err error) 115 116 // Remove returns matched key, value, and updated element. 117 // Updated element may be nil, modified, or a different type of element. 118 Remove( 119 storage SlabStorage, 120 digester Digester, 121 level uint, 122 hkey Digest, 123 comparator ValueComparator, 124 key Value, 125 ) (MapKey, MapValue, element, error) 126 127 Encode(*Encoder) error 128 129 HasPointer() bool 130 131 Size() uint32 132 133 Count(storage SlabStorage) (uint32, error) 134 135 PopIterate(SlabStorage, MapPopIterationFunc) error 136 } 137 138 // elementGroup is a group of elements that must stay together during splitting or rebalancing. 139 type elementGroup interface { 140 element 141 142 Inline() bool 143 144 // Elements returns underlying elements. 145 Elements(storage SlabStorage) (elements, error) 146 } 147 148 // elements is a list of elements. 149 type elements interface { 150 fmt.Stringer 151 152 Get(storage SlabStorage, digester Digester, level uint, hkey Digest, comparator ValueComparator, key Value) (MapValue, error) 153 Set(storage SlabStorage, address Address, b DigesterBuilder, digester Digester, level uint, hkey Digest, comparator ValueComparator, hip HashInputProvider, key Value, value Value) (existingValue MapValue, err error) 154 Remove(storage SlabStorage, digester Digester, level uint, hkey Digest, comparator ValueComparator, key Value) (MapKey, MapValue, error) 155 156 Merge(elements) error 157 Split() (elements, elements, error) 158 159 LendToRight(elements) error 160 BorrowFromRight(elements) error 161 162 CanLendToLeft(size uint32) bool 163 CanLendToRight(size uint32) bool 164 165 Element(int) (element, error) 166 167 Encode(*Encoder) error 168 169 HasPointer() bool 170 171 firstKey() Digest 172 173 Count() uint32 174 175 Size() uint32 176 177 PopIterate(SlabStorage, MapPopIterationFunc) error 178 } 179 180 type singleElement struct { 181 key MapKey 182 value MapValue 183 size uint32 184 keyPointer bool 185 valuePointer bool 186 } 187 188 var _ element = &singleElement{} 189 190 type inlineCollisionGroup struct { 191 elements 192 } 193 194 var _ element = &inlineCollisionGroup{} 195 var _ elementGroup = &inlineCollisionGroup{} 196 197 type externalCollisionGroup struct { 198 id StorageID 199 size uint32 200 } 201 202 var _ element = &externalCollisionGroup{} 203 var _ elementGroup = &externalCollisionGroup{} 204 205 type hkeyElements struct { 206 hkeys []Digest // sorted list of unique hashed keys 207 elems []element // elements corresponding to hkeys 208 size uint32 // total byte sizes 209 level uint 210 } 211 212 var _ elements = &hkeyElements{} 213 214 type singleElements struct { 215 elems []*singleElement // list of key+value pairs 216 size uint32 // total key+value byte sizes 217 level uint 218 } 219 220 var _ elements = &singleElements{} 221 222 type MapSlabHeader struct { 223 id StorageID // id is used to retrieve slab from storage 224 size uint32 // size is used to split and merge; leaf: size of all element; internal: size of all headers 225 firstKey Digest // firstKey (first hashed key) is used to lookup value 226 } 227 228 type MapExtraData struct { 229 TypeInfo TypeInfo 230 Count uint64 231 Seed uint64 232 } 233 234 // MapDataSlab is leaf node, implementing MapSlab. 235 // anySize is true for data slab that isn't restricted by size requirement. 236 type MapDataSlab struct { 237 next StorageID 238 header MapSlabHeader 239 240 elements 241 242 // extraData is data that is prepended to encoded slab data. 243 // It isn't included in slab size calculation for splitting and merging. 244 extraData *MapExtraData 245 246 anySize bool 247 collisionGroup bool 248 } 249 250 var _ MapSlab = &MapDataSlab{} 251 252 // MapMetaDataSlab is internal node, implementing MapSlab. 253 type MapMetaDataSlab struct { 254 header MapSlabHeader 255 childrenHeaders []MapSlabHeader 256 257 // extraData is data that is prepended to encoded slab data. 258 // It isn't included in slab size calculation for splitting and merging. 259 extraData *MapExtraData 260 } 261 262 var _ MapSlab = &MapMetaDataSlab{} 263 264 type MapSlab interface { 265 Slab 266 fmt.Stringer 267 268 Get(storage SlabStorage, digester Digester, level uint, hkey Digest, comparator ValueComparator, key Value) (MapValue, error) 269 Set(storage SlabStorage, b DigesterBuilder, digester Digester, level uint, hkey Digest, comparator ValueComparator, hip HashInputProvider, key Value, value Value) (existingValue MapValue, err error) 270 Remove(storage SlabStorage, digester Digester, level uint, hkey Digest, comparator ValueComparator, key Value) (MapKey, MapValue, error) 271 272 IsData() bool 273 274 IsFull() bool 275 IsUnderflow() (uint32, bool) 276 CanLendToLeft(size uint32) bool 277 CanLendToRight(size uint32) bool 278 279 SetID(StorageID) 280 281 Header() MapSlabHeader 282 283 ExtraData() *MapExtraData 284 RemoveExtraData() *MapExtraData 285 SetExtraData(*MapExtraData) 286 287 PopIterate(SlabStorage, MapPopIterationFunc) error 288 } 289 290 type OrderedMap struct { 291 Storage SlabStorage 292 root MapSlab 293 digesterBuilder DigesterBuilder 294 } 295 296 var _ Value = &OrderedMap{} 297 298 const mapExtraDataLength = 3 299 300 func newMapExtraDataFromData( 301 data []byte, 302 decMode cbor.DecMode, 303 decodeTypeInfo TypeInfoDecoder, 304 ) ( 305 *MapExtraData, 306 []byte, 307 error, 308 ) { 309 // Check data length 310 if len(data) < versionAndFlagSize { 311 return nil, data, NewDecodingError(errors.New("data is too short for map extra data")) 312 } 313 314 // Check flag 315 flag := data[1] 316 if !isRoot(flag) { 317 return nil, data, NewDecodingError(fmt.Errorf("data has invalid flag 0x%x, want root flag", flag)) 318 } 319 320 // Decode extra data 321 322 dec := decMode.NewByteStreamDecoder(data[versionAndFlagSize:]) 323 324 length, err := dec.DecodeArrayHead() 325 if err != nil { 326 return nil, data, NewDecodingError(err) 327 } 328 329 if length != mapExtraDataLength { 330 return nil, data, NewDecodingError( 331 fmt.Errorf( 332 "data has invalid length %d, want %d", 333 length, 334 mapExtraDataLength, 335 )) 336 } 337 338 typeInfo, err := decodeTypeInfo(dec) 339 if err != nil { 340 // Wrap err as external error (if needed) because err is returned by TypeInfoDecoder callback. 341 return nil, data, wrapErrorfAsExternalErrorIfNeeded(err, "failed to decode type info") 342 } 343 344 count, err := dec.DecodeUint64() 345 if err != nil { 346 return nil, data, NewDecodingError(err) 347 } 348 349 seed, err := dec.DecodeUint64() 350 if err != nil { 351 return nil, data, NewDecodingError(err) 352 } 353 354 // Reslice for remaining data 355 n := dec.NumBytesDecoded() 356 data = data[versionAndFlagSize+n:] 357 358 return &MapExtraData{ 359 TypeInfo: typeInfo, 360 Count: count, 361 Seed: seed, 362 }, data, nil 363 } 364 365 // Encode encodes extra data to the given encoder. 366 // 367 // Header (2 bytes): 368 // 369 // +-----------------------------+--------------------------+ 370 // | extra data version (1 byte) | extra data flag (1 byte) | 371 // +-----------------------------+--------------------------+ 372 // 373 // Content (for now): 374 // 375 // CBOR encoded array of extra data 376 // 377 // Extra data flag is the same as the slab flag it prepends. 378 func (m *MapExtraData) Encode(enc *Encoder, version byte, flag byte) error { 379 380 // Encode version 381 enc.Scratch[0] = version 382 383 // Encode flag 384 enc.Scratch[1] = flag 385 386 // Write scratch content to encoder 387 _, err := enc.Write(enc.Scratch[:versionAndFlagSize]) 388 if err != nil { 389 return NewEncodingError(err) 390 } 391 392 // Encode extra data 393 err = enc.CBOR.EncodeArrayHead(mapExtraDataLength) 394 if err != nil { 395 return NewEncodingError(err) 396 } 397 398 err = m.TypeInfo.Encode(enc.CBOR) 399 if err != nil { 400 // Wrap err as external error (if needed) because err is returned by TypeInfo interface. 401 return wrapErrorfAsExternalErrorIfNeeded(err, "failed to encode type info") 402 } 403 404 err = enc.CBOR.EncodeUint64(m.Count) 405 if err != nil { 406 return NewEncodingError(err) 407 } 408 409 err = enc.CBOR.EncodeUint64(m.Seed) 410 if err != nil { 411 return NewEncodingError(err) 412 } 413 414 err = enc.CBOR.Flush() 415 if err != nil { 416 return NewEncodingError(err) 417 } 418 419 return nil 420 } 421 422 func newElementFromData(cborDec *cbor.StreamDecoder, decodeStorable StorableDecoder) (element, error) { 423 nt, err := cborDec.NextType() 424 if err != nil { 425 return nil, NewDecodingError(err) 426 } 427 428 switch nt { 429 case cbor.ArrayType: 430 // Don't need to wrap error as external error because err is already categorized by newSingleElementFromData(). 431 return newSingleElementFromData(cborDec, decodeStorable) 432 433 case cbor.TagType: 434 tagNum, err := cborDec.DecodeTagNumber() 435 if err != nil { 436 return nil, NewDecodingError(err) 437 } 438 switch tagNum { 439 case CBORTagInlineCollisionGroup: 440 // Don't need to wrap error as external error because err is already categorized by newInlineCollisionGroupFromData(). 441 return newInlineCollisionGroupFromData(cborDec, decodeStorable) 442 case CBORTagExternalCollisionGroup: 443 // Don't need to wrap error as external error because err is already categorized by newExternalCollisionGroupFromData(). 444 return newExternalCollisionGroupFromData(cborDec, decodeStorable) 445 default: 446 return nil, NewDecodingError(fmt.Errorf("failed to decode element: unrecognized tag number %d", tagNum)) 447 } 448 449 default: 450 return nil, NewDecodingError(fmt.Errorf("failed to decode element: unrecognized CBOR type %s", nt)) 451 } 452 } 453 454 func newSingleElement(storage SlabStorage, address Address, key Value, value Value) (*singleElement, error) { 455 456 ks, err := key.Storable(storage, address, MaxInlineMapKeyOrValueSize) 457 if err != nil { 458 // Wrap err as external error (if needed) because err is returned by Value interface. 459 return nil, wrapErrorfAsExternalErrorIfNeeded(err, "failed to get key's storable") 460 } 461 462 vs, err := value.Storable(storage, address, MaxInlineMapKeyOrValueSize) 463 if err != nil { 464 // Wrap err as external error (if needed) because err is returned by Value interface. 465 return nil, wrapErrorfAsExternalErrorIfNeeded(err, "failed to get value's storable") 466 } 467 468 var keyPointer bool 469 if _, ok := ks.(StorageIDStorable); ok { 470 keyPointer = true 471 } 472 473 var valuePointer bool 474 if _, ok := vs.(StorageIDStorable); ok { 475 valuePointer = true 476 } 477 478 return &singleElement{ 479 key: ks, 480 value: vs, 481 size: singleElementPrefixSize + ks.ByteSize() + vs.ByteSize(), 482 keyPointer: keyPointer, 483 valuePointer: valuePointer, 484 }, nil 485 } 486 487 func newSingleElementFromData(cborDec *cbor.StreamDecoder, decodeStorable StorableDecoder) (*singleElement, error) { 488 elemCount, err := cborDec.DecodeArrayHead() 489 if err != nil { 490 return nil, NewDecodingError(err) 491 } 492 493 if elemCount != 2 { 494 return nil, NewDecodingError(fmt.Errorf("failed to decode single element: expect array of 2 elements, got %d elements", elemCount)) 495 } 496 497 key, err := decodeStorable(cborDec, StorageIDUndefined) 498 if err != nil { 499 // Wrap err as external error (if needed) because err is returned by StorableDecoder callback. 500 return nil, wrapErrorfAsExternalErrorIfNeeded(err, "failed to decode key's storable") 501 } 502 503 value, err := decodeStorable(cborDec, StorageIDUndefined) 504 if err != nil { 505 // Wrap err as external error (if needed) because err is returned by StorableDecoder callback. 506 return nil, wrapErrorfAsExternalErrorIfNeeded(err, "failed to decode value's storable") 507 } 508 509 var keyPointer bool 510 if _, ok := key.(StorageIDStorable); ok { 511 keyPointer = true 512 } 513 514 var valuePointer bool 515 if _, ok := value.(StorageIDStorable); ok { 516 valuePointer = true 517 } 518 519 return &singleElement{ 520 key: key, 521 value: value, 522 size: singleElementPrefixSize + key.ByteSize() + value.ByteSize(), 523 keyPointer: keyPointer, 524 valuePointer: valuePointer, 525 }, nil 526 } 527 528 // Encode encodes singleElement to the given encoder. 529 // 530 // CBOR encoded array of 2 elements (key, value). 531 func (e *singleElement) Encode(enc *Encoder) error { 532 533 // Encode CBOR array head for 2 elements 534 err := enc.CBOR.EncodeRawBytes([]byte{0x82}) 535 if err != nil { 536 return NewEncodingError(err) 537 } 538 539 // Encode key 540 err = e.key.Encode(enc) 541 if err != nil { 542 // Wrap err as external error (if needed) because err is returned by Storable interface. 543 return wrapErrorfAsExternalErrorIfNeeded(err, "failed to encode map key") 544 } 545 546 // Encode value 547 err = e.value.Encode(enc) 548 if err != nil { 549 // Wrap err as external error (if needed) because err is returned by Storable interface. 550 return wrapErrorfAsExternalErrorIfNeeded(err, "failed to encode map value") 551 } 552 553 err = enc.CBOR.Flush() 554 if err != nil { 555 return NewEncodingError(err) 556 } 557 558 return nil 559 } 560 561 func (e *singleElement) Get(storage SlabStorage, _ Digester, _ uint, _ Digest, comparator ValueComparator, key Value) (MapValue, error) { 562 equal, err := comparator(storage, key, e.key) 563 if err != nil { 564 // Wrap err as external error (if needed) because err is returned by ValueComparator callback. 565 return nil, wrapErrorfAsExternalErrorIfNeeded(err, "failed to compare keys") 566 } 567 if equal { 568 return e.value, nil 569 } 570 return nil, NewKeyNotFoundError(key) 571 } 572 573 // Set updates value if key matches, otherwise returns inlineCollisionGroup with existing and new elements. 574 // NOTE: Existing key needs to be rehashed because we store minimum digest for non-collision element. 575 // 576 // Rehashing only happens when we create new inlineCollisionGroup. 577 // Adding new element to existing inlineCollisionGroup doesn't require rehashing. 578 func (e *singleElement) Set( 579 storage SlabStorage, 580 address Address, 581 b DigesterBuilder, 582 digester Digester, 583 level uint, 584 hkey Digest, 585 comparator ValueComparator, 586 hip HashInputProvider, 587 key Value, 588 value Value, 589 ) (element, MapValue, error) { 590 591 equal, err := comparator(storage, key, e.key) 592 if err != nil { 593 // Wrap err as external error (if needed) because err is returned by ValueComparator callback. 594 return nil, nil, wrapErrorfAsExternalErrorIfNeeded(err, "failed to compare keys") 595 } 596 597 // Key matches, overwrite existing value 598 if equal { 599 existingValue := e.value 600 601 valueStorable, err := value.Storable(storage, address, MaxInlineMapKeyOrValueSize) 602 if err != nil { 603 // Wrap err as external error (if needed) because err is returned by Value interface. 604 return nil, nil, wrapErrorfAsExternalErrorIfNeeded(err, "failed to get value's storable") 605 } 606 607 valuePointer := false 608 if _, ok := valueStorable.(StorageIDStorable); ok { 609 valuePointer = true 610 } 611 612 e.value = valueStorable 613 e.size = singleElementPrefixSize + e.key.ByteSize() + e.value.ByteSize() 614 e.valuePointer = valuePointer 615 return e, existingValue, nil 616 } 617 618 // Hash collision detected 619 620 // Create collision group with existing and new elements 621 622 if level+1 == digester.Levels() { 623 624 // Create singleElements group 625 group := &inlineCollisionGroup{ 626 elements: newSingleElementsWithElement(level+1, e), 627 } 628 629 // Add new key and value to collision group 630 // Don't need to wrap error as external error because err is already categorized by inlineCollisionGroup.Set(). 631 return group.Set(storage, address, b, digester, level, hkey, comparator, hip, key, value) 632 633 } 634 635 // Generate digest for existing key (see function comment) 636 kv, err := e.key.StoredValue(storage) 637 if err != nil { 638 // Wrap err as external error (if needed) because err is returned by Storable interface. 639 return nil, nil, wrapErrorfAsExternalErrorIfNeeded(err, "failed to get key's stored value") 640 } 641 642 existingKeyDigest, err := b.Digest(hip, kv) 643 if err != nil { 644 // Wrap err as external error (if needed) because err is returned by DigestBuilder interface. 645 return nil, nil, wrapErrorfAsExternalErrorIfNeeded(err, "failed to get key's digester") 646 } 647 defer putDigester(existingKeyDigest) 648 649 d, err := existingKeyDigest.Digest(level + 1) 650 if err != nil { 651 // Wrap err as external error (if needed) because err is returned by Digester interface. 652 return nil, nil, wrapErrorfAsExternalErrorIfNeeded(err, fmt.Sprintf("failed to get key's digest at level %d", level+1)) 653 } 654 655 group := &inlineCollisionGroup{ 656 elements: newHkeyElementsWithElement(level+1, d, e), 657 } 658 659 // Add new key and value to collision group 660 // Don't need to wrap error as external error because err is already categorized by inlineCollisionGroup.Set(). 661 return group.Set(storage, address, b, digester, level, hkey, comparator, hip, key, value) 662 } 663 664 // Remove returns key, value, and nil element if key matches, otherwise returns error. 665 func (e *singleElement) Remove(storage SlabStorage, digester Digester, level uint, hkey Digest, comparator ValueComparator, key Value) (MapKey, MapValue, element, error) { 666 667 equal, err := comparator(storage, key, e.key) 668 if err != nil { 669 // Wrap err as external error (if needed) because err is returned by ValueComparator callback. 670 return nil, nil, nil, wrapErrorfAsExternalErrorIfNeeded(err, "failed to compare keys") 671 } 672 673 if equal { 674 return e.key, e.value, nil, nil 675 } 676 677 return nil, nil, nil, NewKeyNotFoundError(key) 678 } 679 680 func (e *singleElement) HasPointer() bool { 681 return e.keyPointer || e.valuePointer 682 } 683 684 func (e *singleElement) Size() uint32 { 685 return e.size 686 } 687 688 func (e *singleElement) Count(_ SlabStorage) (uint32, error) { 689 return 1, nil 690 } 691 692 func (e *singleElement) PopIterate(_ SlabStorage, fn MapPopIterationFunc) error { 693 fn(e.key, e.value) 694 return nil 695 } 696 697 func (e *singleElement) String() string { 698 return fmt.Sprintf("%s:%s", e.key, e.value) 699 } 700 701 func newInlineCollisionGroupFromData(cborDec *cbor.StreamDecoder, decodeStorable StorableDecoder) (*inlineCollisionGroup, error) { 702 elements, err := newElementsFromData(cborDec, decodeStorable) 703 if err != nil { 704 // Don't need to wrap error as external error because err is already categorized by newElementsFromData(). 705 return nil, err 706 } 707 708 return &inlineCollisionGroup{elements}, nil 709 } 710 711 // Encode encodes inlineCollisionGroup to the given encoder. 712 // 713 // CBOR tag (number: CBORTagInlineCollisionGroup, content: elements) 714 func (e *inlineCollisionGroup) Encode(enc *Encoder) error { 715 716 err := enc.CBOR.EncodeRawBytes([]byte{ 717 // tag number CBORTagInlineCollisionGroup 718 0xd8, CBORTagInlineCollisionGroup, 719 }) 720 if err != nil { 721 return NewEncodingError(err) 722 } 723 724 err = e.elements.Encode(enc) 725 if err != nil { 726 // Don't need to wrap error as external error because err is already categorized by elements.Encode(). 727 return err 728 } 729 730 // TODO: is Flush necessary? 731 err = enc.CBOR.Flush() 732 if err != nil { 733 return NewEncodingError(err) 734 } 735 736 return nil 737 } 738 739 func (e *inlineCollisionGroup) Get(storage SlabStorage, digester Digester, level uint, _ Digest, comparator ValueComparator, key Value) (MapValue, error) { 740 741 // Adjust level and hkey for collision group 742 level++ 743 if level > digester.Levels() { 744 return nil, NewHashLevelErrorf("inline collision group digest level is %d, want <= %d", level, digester.Levels()) 745 } 746 hkey, _ := digester.Digest(level) 747 748 // Search key in collision group with adjusted hkeyPrefix and hkey 749 // Don't need to wrap error as external error because err is already categorized by elements.Get(). 750 return e.elements.Get(storage, digester, level, hkey, comparator, key) 751 } 752 753 func (e *inlineCollisionGroup) Set( 754 storage SlabStorage, 755 address Address, 756 b DigesterBuilder, 757 digester Digester, 758 level uint, 759 _ Digest, 760 comparator ValueComparator, 761 hip HashInputProvider, 762 key Value, 763 value Value, 764 ) (element, MapValue, error) { 765 766 // Adjust level and hkey for collision group 767 level++ 768 if level > digester.Levels() { 769 return nil, nil, NewHashLevelErrorf("inline collision group digest level is %d, want <= %d", level, digester.Levels()) 770 } 771 hkey, _ := digester.Digest(level) 772 773 existingValue, err := e.elements.Set(storage, address, b, digester, level, hkey, comparator, hip, key, value) 774 if err != nil { 775 // Don't need to wrap error as external error because err is already categorized by elements.Set(). 776 return nil, nil, err 777 } 778 779 if level == 1 { 780 // Export oversized inline collision group to separate slab (external collision group) 781 // for first level collision. 782 if e.Size() > uint32(maxInlineMapElementSize) { 783 784 id, err := storage.GenerateStorageID(address) 785 if err != nil { 786 // Wrap err as external error (if needed) because err is returned by SlabStorage interface. 787 return nil, nil, wrapErrorfAsExternalErrorIfNeeded( 788 err, 789 fmt.Sprintf("failed to generate storage ID for address 0x%x", address)) 790 } 791 792 // Create MapDataSlab 793 slab := &MapDataSlab{ 794 header: MapSlabHeader{ 795 id: id, 796 size: mapDataSlabPrefixSize + e.elements.Size(), 797 firstKey: e.elements.firstKey(), 798 }, 799 elements: e.elements, // elems shouldn't be copied 800 anySize: true, 801 collisionGroup: true, 802 } 803 804 err = storage.Store(id, slab) 805 if err != nil { 806 // Wrap err as external error (if needed) because err is returned by SlabStorage interface. 807 return nil, nil, wrapErrorfAsExternalErrorIfNeeded(err, fmt.Sprintf("failed to store slab %s", id)) 808 } 809 810 // Create and return externalCollisionGroup (wrapper of newly created MapDataSlab) 811 return &externalCollisionGroup{ 812 id: id, 813 size: externalCollisionGroupPrefixSize + StorageIDStorable(id).ByteSize(), 814 }, existingValue, nil 815 } 816 } 817 818 return e, existingValue, nil 819 } 820 821 // Remove returns key, value, and updated element if key is found. 822 // Updated element can be modified inlineCollisionGroup, or singleElement. 823 func (e *inlineCollisionGroup) Remove(storage SlabStorage, digester Digester, level uint, _ Digest, comparator ValueComparator, key Value) (MapKey, MapValue, element, error) { 824 825 // Adjust level and hkey for collision group 826 level++ 827 if level > digester.Levels() { 828 return nil, nil, nil, NewHashLevelErrorf("inline collision group digest level is %d, want <= %d", level, digester.Levels()) 829 } 830 hkey, _ := digester.Digest(level) 831 832 k, v, err := e.elements.Remove(storage, digester, level, hkey, comparator, key) 833 if err != nil { 834 // Don't need to wrap error as external error because err is already categorized by elements.Remove(). 835 return nil, nil, nil, err 836 } 837 838 // If there is only one single element in this group, return the single element (no collision). 839 if e.elements.Count() == 1 { 840 elem, err := e.elements.Element(0) 841 if err != nil { 842 // Don't need to wrap error as external error because err is already categorized by elements.Element(). 843 return nil, nil, nil, err 844 } 845 if _, ok := elem.(elementGroup); !ok { 846 return k, v, elem, nil 847 } 848 } 849 850 return k, v, e, nil 851 } 852 853 func (e *inlineCollisionGroup) HasPointer() bool { 854 return e.elements.HasPointer() 855 } 856 857 func (e *inlineCollisionGroup) Size() uint32 { 858 return inlineCollisionGroupPrefixSize + e.elements.Size() 859 } 860 861 func (e *inlineCollisionGroup) Inline() bool { 862 return true 863 } 864 865 func (e *inlineCollisionGroup) Elements(_ SlabStorage) (elements, error) { 866 return e.elements, nil 867 } 868 869 func (e *inlineCollisionGroup) Count(_ SlabStorage) (uint32, error) { 870 return e.elements.Count(), nil 871 } 872 873 func (e *inlineCollisionGroup) PopIterate(storage SlabStorage, fn MapPopIterationFunc) error { 874 // Don't need to wrap error as external error because err is already categorized by elements.PopIterate(). 875 return e.elements.PopIterate(storage, fn) 876 } 877 878 func (e *inlineCollisionGroup) String() string { 879 return "inline[" + e.elements.String() + "]" 880 } 881 882 func newExternalCollisionGroupFromData(cborDec *cbor.StreamDecoder, decodeStorable StorableDecoder) (*externalCollisionGroup, error) { 883 884 storable, err := decodeStorable(cborDec, StorageIDUndefined) 885 if err != nil { 886 // Wrap err as external error (if needed) because err is returned by StorableDecoder callback. 887 return nil, wrapErrorfAsExternalErrorIfNeeded(err, "failed to decode Storable") 888 } 889 890 idStorable, ok := storable.(StorageIDStorable) 891 if !ok { 892 return nil, NewDecodingError(fmt.Errorf("failed to decode external collision group: expect storage id, got %T", storable)) 893 } 894 895 return &externalCollisionGroup{ 896 id: StorageID(idStorable), 897 size: externalCollisionGroupPrefixSize + idStorable.ByteSize(), 898 }, nil 899 } 900 901 // Encode encodes externalCollisionGroup to the given encoder. 902 // 903 // CBOR tag (number: CBORTagExternalCollisionGroup, content: storage ID) 904 func (e *externalCollisionGroup) Encode(enc *Encoder) error { 905 err := enc.CBOR.EncodeRawBytes([]byte{ 906 // tag number CBORTagExternalCollisionGroup 907 0xd8, CBORTagExternalCollisionGroup, 908 }) 909 if err != nil { 910 return NewEncodingError(err) 911 } 912 913 err = StorageIDStorable(e.id).Encode(enc) 914 if err != nil { 915 // Don't need to wrap error as external error because err is already categorized by StorageIDStorable.Encode(). 916 return err 917 } 918 919 // TODO: is Flush necessary? 920 err = enc.CBOR.Flush() 921 if err != nil { 922 return NewEncodingError(err) 923 } 924 925 return nil 926 } 927 928 func (e *externalCollisionGroup) Get(storage SlabStorage, digester Digester, level uint, _ Digest, comparator ValueComparator, key Value) (MapValue, error) { 929 slab, err := getMapSlab(storage, e.id) 930 if err != nil { 931 // Don't need to wrap error as external error because err is already categorized by getMapSlab(). 932 return nil, err 933 } 934 935 // Adjust level and hkey for collision group 936 level++ 937 if level > digester.Levels() { 938 return nil, NewHashLevelErrorf("external collision group digest level is %d, want <= %d", level, digester.Levels()) 939 } 940 hkey, _ := digester.Digest(level) 941 942 // Search key in collision group with adjusted hkeyPrefix and hkey 943 // Don't need to wrap error as external error because err is already categorized by MapSlab.Get(). 944 return slab.Get(storage, digester, level, hkey, comparator, key) 945 } 946 947 func (e *externalCollisionGroup) Set(storage SlabStorage, address Address, b DigesterBuilder, digester Digester, level uint, _ Digest, comparator ValueComparator, hip HashInputProvider, key Value, value Value) (element, MapValue, error) { 948 slab, err := getMapSlab(storage, e.id) 949 if err != nil { 950 // Don't need to wrap error as external error because err is already categorized by getMapSlab(). 951 return nil, nil, err 952 } 953 954 // Adjust level and hkey for collision group 955 level++ 956 if level > digester.Levels() { 957 return nil, nil, NewHashLevelErrorf("external collision group digest level is %d, want <= %d", level, digester.Levels()) 958 } 959 hkey, _ := digester.Digest(level) 960 961 existingValue, err := slab.Set(storage, b, digester, level, hkey, comparator, hip, key, value) 962 if err != nil { 963 // Don't need to wrap error as external error because err is already categorized by MapSlab.Set(). 964 return nil, nil, err 965 } 966 return e, existingValue, nil 967 } 968 969 // Remove returns key, value, and updated element if key is found. 970 // Updated element can be modified externalCollisionGroup, or singleElement. 971 // TODO: updated element can be inlineCollisionGroup if size < maxInlineMapElementSize. 972 func (e *externalCollisionGroup) Remove(storage SlabStorage, digester Digester, level uint, _ Digest, comparator ValueComparator, key Value) (MapKey, MapValue, element, error) { 973 974 slab, found, err := storage.Retrieve(e.id) 975 if err != nil { 976 // Wrap err as external error (if needed) because err is returned by SlabStorage interface. 977 return nil, nil, nil, wrapErrorfAsExternalErrorIfNeeded(err, fmt.Sprintf("failed to retrieve slab %s", e.id)) 978 } 979 if !found { 980 return nil, nil, nil, NewSlabNotFoundErrorf(e.id, "external collision slab not found") 981 } 982 983 dataSlab, ok := slab.(*MapDataSlab) 984 if !ok { 985 return nil, nil, nil, NewSlabDataErrorf("slab %s isn't MapDataSlab", e.id) 986 } 987 988 // Adjust level and hkey for collision group 989 level++ 990 if level > digester.Levels() { 991 return nil, nil, nil, NewHashLevelErrorf("external collision group digest level is %d, want <= %d", level, digester.Levels()) 992 } 993 hkey, _ := digester.Digest(level) 994 995 k, v, err := dataSlab.Remove(storage, digester, level, hkey, comparator, key) 996 if err != nil { 997 // Don't need to wrap error as external error because err is already categorized by MapDataSlab.Remove(). 998 return nil, nil, nil, err 999 } 1000 1001 // TODO: if element size < maxInlineMapElementSize, return inlineCollisionGroup 1002 1003 // If there is only one single element in this group, return the single element and remove external slab from storage. 1004 if dataSlab.elements.Count() == 1 { 1005 elem, err := dataSlab.elements.Element(0) 1006 if err != nil { 1007 // Don't need to wrap error as external error because err is already categorized by elements.Element(). 1008 return nil, nil, nil, err 1009 } 1010 if _, ok := elem.(elementGroup); !ok { 1011 err := storage.Remove(e.id) 1012 if err != nil { 1013 // Wrap err as external error (if needed) because err is returned by SlabStorage interface. 1014 return nil, nil, nil, wrapErrorfAsExternalErrorIfNeeded(err, fmt.Sprintf("failed to remove slab %s", e.id)) 1015 } 1016 return k, v, elem, nil 1017 } 1018 } 1019 1020 return k, v, e, nil 1021 } 1022 1023 func (e *externalCollisionGroup) HasPointer() bool { 1024 return true 1025 } 1026 1027 func (e *externalCollisionGroup) Size() uint32 { 1028 return e.size 1029 } 1030 1031 func (e *externalCollisionGroup) Inline() bool { 1032 return false 1033 } 1034 1035 func (e *externalCollisionGroup) Elements(storage SlabStorage) (elements, error) { 1036 slab, err := getMapSlab(storage, e.id) 1037 if err != nil { 1038 // Don't need to wrap error as external error because err is already categorized by getMapSlab(). 1039 return nil, err 1040 } 1041 dataSlab, ok := slab.(*MapDataSlab) 1042 if !ok { 1043 return nil, NewSlabDataErrorf("slab %s isn't MapDataSlab", e.id) 1044 } 1045 return dataSlab.elements, nil 1046 } 1047 1048 func (e *externalCollisionGroup) Count(storage SlabStorage) (uint32, error) { 1049 elements, err := e.Elements(storage) 1050 if err != nil { 1051 // Don't need to wrap error as external error because err is already categorized by externalCollisionGroup.Elements(). 1052 return 0, err 1053 } 1054 return elements.Count(), nil 1055 } 1056 1057 func (e *externalCollisionGroup) PopIterate(storage SlabStorage, fn MapPopIterationFunc) error { 1058 elements, err := e.Elements(storage) 1059 if err != nil { 1060 // Don't need to wrap error as external error because err is already categorized by externalCollisionGroup.Elements(). 1061 return err 1062 } 1063 1064 err = elements.PopIterate(storage, fn) 1065 if err != nil { 1066 // Don't need to wrap error as external error because err is already categorized by elements.PopIterate(). 1067 return err 1068 } 1069 1070 err = storage.Remove(e.id) 1071 if err != nil { 1072 // Wrap err as external error (if needed) because err is returned by SlabStorage interface. 1073 return wrapErrorfAsExternalErrorIfNeeded(err, fmt.Sprintf("failed to remove slab %s", e.id)) 1074 } 1075 return nil 1076 } 1077 1078 func (e *externalCollisionGroup) String() string { 1079 return fmt.Sprintf("external(%s)", e.id) 1080 } 1081 1082 func newElementsFromData(cborDec *cbor.StreamDecoder, decodeStorable StorableDecoder) (elements, error) { 1083 1084 arrayCount, err := cborDec.DecodeArrayHead() 1085 if err != nil { 1086 return nil, NewDecodingError(err) 1087 } 1088 1089 if arrayCount != 3 { 1090 return nil, NewDecodingError(fmt.Errorf("decoding elements failed: expect array of 3 elements, got %d elements", arrayCount)) 1091 } 1092 1093 level, err := cborDec.DecodeUint64() 1094 if err != nil { 1095 return nil, NewDecodingError(err) 1096 } 1097 1098 digestBytes, err := cborDec.DecodeBytes() 1099 if err != nil { 1100 return nil, NewDecodingError(err) 1101 } 1102 1103 if len(digestBytes)%digestSize != 0 { 1104 return nil, NewDecodingError(fmt.Errorf("decoding digests failed: number of bytes is not multiple of %d", digestSize)) 1105 } 1106 1107 digestCount := len(digestBytes) / digestSize 1108 hkeys := make([]Digest, digestCount) 1109 for i := 0; i < digestCount; i++ { 1110 hkeys[i] = Digest(binary.BigEndian.Uint64(digestBytes[i*digestSize:])) 1111 } 1112 1113 elemCount, err := cborDec.DecodeArrayHead() 1114 if err != nil { 1115 return nil, NewDecodingError(err) 1116 } 1117 1118 if digestCount != 0 && uint64(digestCount) != elemCount { 1119 return nil, NewDecodingError(fmt.Errorf("decoding elements failed: number of hkeys %d isn't the same as number of elements %d", digestCount, elemCount)) 1120 } 1121 1122 if digestCount == 0 && elemCount > 0 { 1123 // elements are singleElements 1124 1125 // Decode elements 1126 size := uint32(singleElementsPrefixSize) 1127 elems := make([]*singleElement, elemCount) 1128 for i := 0; i < int(elemCount); i++ { 1129 elem, err := newSingleElementFromData(cborDec, decodeStorable) 1130 if err != nil { 1131 // Don't need to wrap error as external error because err is already categorized by newSingleElementFromData(). 1132 return nil, err 1133 } 1134 1135 elems[i] = elem 1136 size += elem.Size() 1137 } 1138 1139 // Create singleElements 1140 elements := &singleElements{ 1141 elems: elems, 1142 level: uint(level), 1143 size: size, 1144 } 1145 1146 return elements, nil 1147 } 1148 1149 // elements are hkeyElements 1150 1151 // Decode elements 1152 size := uint32(hkeyElementsPrefixSize) 1153 elems := make([]element, elemCount) 1154 for i := 0; i < int(elemCount); i++ { 1155 elem, err := newElementFromData(cborDec, decodeStorable) 1156 if err != nil { 1157 // Don't need to wrap error as external error because err is already categorized by newElementFromData(). 1158 return nil, err 1159 } 1160 1161 elems[i] = elem 1162 size += digestSize + elem.Size() 1163 } 1164 1165 // Create hkeyElements 1166 elements := &hkeyElements{ 1167 hkeys: hkeys, 1168 elems: elems, 1169 level: uint(level), 1170 size: size, 1171 } 1172 1173 return elements, nil 1174 } 1175 1176 func newHkeyElements(level uint) *hkeyElements { 1177 return &hkeyElements{ 1178 level: level, 1179 size: hkeyElementsPrefixSize, 1180 } 1181 } 1182 1183 func newHkeyElementsWithElement(level uint, hkey Digest, elem element) *hkeyElements { 1184 return &hkeyElements{ 1185 hkeys: []Digest{hkey}, 1186 elems: []element{elem}, 1187 size: hkeyElementsPrefixSize + digestSize + elem.Size(), 1188 level: level, 1189 } 1190 } 1191 1192 // Encode encodes hkeyElements to the given encoder. 1193 // 1194 // CBOR encoded array [ 1195 // 0: level (uint) 1196 // 1: hkeys (byte string) 1197 // 2: elements (array) 1198 // ] 1199 func (e *hkeyElements) Encode(enc *Encoder) error { 1200 1201 if e.level > maxDigestLevel { 1202 return NewFatalError(fmt.Errorf("hash level %d exceeds max digest level %d", e.level, maxDigestLevel)) 1203 } 1204 1205 // Encode CBOR array head of 3 elements (level, hkeys, elements) 1206 enc.Scratch[0] = 0x83 1207 1208 // Encode hash level 1209 enc.Scratch[1] = byte(e.level) 1210 1211 // Encode hkeys as byte string 1212 1213 // Encode hkeys bytes header manually for fix-sized encoding 1214 // TODO: maybe make this header dynamic to reduce size 1215 enc.Scratch[2] = 0x5b 1216 binary.BigEndian.PutUint64(enc.Scratch[3:], uint64(len(e.hkeys)*8)) 1217 1218 // Write scratch content to encoder 1219 const totalSize = 11 1220 err := enc.CBOR.EncodeRawBytes(enc.Scratch[:totalSize]) 1221 if err != nil { 1222 return NewEncodingError(err) 1223 } 1224 1225 // Encode hkeys 1226 for i := 0; i < len(e.hkeys); i++ { 1227 binary.BigEndian.PutUint64(enc.Scratch[:], uint64(e.hkeys[i])) 1228 err = enc.CBOR.EncodeRawBytes(enc.Scratch[:digestSize]) 1229 if err != nil { 1230 return NewEncodingError(err) 1231 } 1232 } 1233 1234 // Encode elements 1235 1236 // Encode elements array header manually for fix-sized encoding 1237 // TODO: maybe make this header dynamic to reduce size 1238 enc.Scratch[0] = 0x9b 1239 binary.BigEndian.PutUint64(enc.Scratch[1:], uint64(len(e.elems))) 1240 err = enc.CBOR.EncodeRawBytes(enc.Scratch[:9]) 1241 if err != nil { 1242 return NewEncodingError(err) 1243 } 1244 1245 // Encode each element 1246 for _, e := range e.elems { 1247 err = e.Encode(enc) 1248 if err != nil { 1249 // Don't need to wrap error as external error because err is already categorized by element.Encode(). 1250 return err 1251 } 1252 } 1253 1254 // TODO: is Flush necessary 1255 err = enc.CBOR.Flush() 1256 if err != nil { 1257 return NewEncodingError(err) 1258 } 1259 1260 return nil 1261 } 1262 1263 func (e *hkeyElements) Get(storage SlabStorage, digester Digester, level uint, hkey Digest, comparator ValueComparator, key Value) (MapValue, error) { 1264 1265 if level >= digester.Levels() { 1266 return nil, NewHashLevelErrorf("hkey elements digest level is %d, want < %d", level, digester.Levels()) 1267 } 1268 1269 // binary search by hkey 1270 1271 // Find index that e.hkeys[h] == hkey 1272 equalIndex := -1 1273 i, j := 0, len(e.hkeys) 1274 for i < j { 1275 h := int(uint(i+j) >> 1) // avoid overflow when computing h 1276 if e.hkeys[h] > hkey { 1277 j = h 1278 } else if e.hkeys[h] < hkey { 1279 i = h + 1 1280 } else { 1281 equalIndex = h 1282 break 1283 } 1284 } 1285 1286 // No matching hkey 1287 if equalIndex == -1 { 1288 return nil, NewKeyNotFoundError(key) 1289 } 1290 1291 elem := e.elems[equalIndex] 1292 1293 // Don't need to wrap error as external error because err is already categorized by element.Get(). 1294 return elem.Get(storage, digester, level, hkey, comparator, key) 1295 } 1296 1297 func (e *hkeyElements) Set(storage SlabStorage, address Address, b DigesterBuilder, digester Digester, level uint, hkey Digest, comparator ValueComparator, hip HashInputProvider, key Value, value Value) (MapValue, error) { 1298 1299 // Check hkeys are not empty 1300 if level >= digester.Levels() { 1301 return nil, NewHashLevelErrorf("hkey elements digest level is %d, want < %d", level, digester.Levels()) 1302 } 1303 1304 if len(e.hkeys) == 0 { 1305 // first element 1306 1307 newElem, err := newSingleElement(storage, address, key, value) 1308 if err != nil { 1309 // Don't need to wrap error as external error because err is already categorized by newSingleElement(). 1310 return nil, err 1311 } 1312 1313 e.hkeys = []Digest{hkey} 1314 1315 e.elems = []element{newElem} 1316 1317 e.size += digestSize + newElem.Size() 1318 1319 return nil, nil 1320 } 1321 1322 if hkey < e.hkeys[0] { 1323 // prepend key and value 1324 1325 newElem, err := newSingleElement(storage, address, key, value) 1326 if err != nil { 1327 // Don't need to wrap error as external error because err is already categorized by newSingleElement(). 1328 return nil, err 1329 } 1330 1331 e.hkeys = append(e.hkeys, Digest(0)) 1332 copy(e.hkeys[1:], e.hkeys) 1333 e.hkeys[0] = hkey 1334 1335 e.elems = append(e.elems, nil) 1336 copy(e.elems[1:], e.elems) 1337 e.elems[0] = newElem 1338 1339 e.size += digestSize + newElem.Size() 1340 1341 return nil, nil 1342 } 1343 1344 if hkey > e.hkeys[len(e.hkeys)-1] { 1345 // append key and value 1346 1347 newElem, err := newSingleElement(storage, address, key, value) 1348 if err != nil { 1349 // Don't need to wrap error as external error because err is already categorized by newSingleElement(). 1350 return nil, err 1351 } 1352 1353 e.hkeys = append(e.hkeys, hkey) 1354 1355 e.elems = append(e.elems, newElem) 1356 1357 e.size += digestSize + newElem.Size() 1358 1359 return nil, nil 1360 } 1361 1362 equalIndex := -1 // first index that m.hkeys[h] == hkey 1363 lessThanIndex := 0 // last index that m.hkeys[h] > hkey 1364 i, j := 0, len(e.hkeys) 1365 for i < j { 1366 h := int(uint(i+j) >> 1) // avoid overflow when computing h 1367 if e.hkeys[h] > hkey { 1368 lessThanIndex = h 1369 j = h 1370 } else if e.hkeys[h] < hkey { 1371 i = h + 1 1372 } else { 1373 equalIndex = h 1374 break 1375 } 1376 } 1377 1378 // hkey digest has collision. 1379 if equalIndex != -1 { 1380 // New element has the same digest as existing elem. 1381 // elem is existing element before new element is inserted. 1382 elem := e.elems[equalIndex] 1383 1384 // Enforce MaxCollisionLimitPerDigest at the first level (noncryptographic hash). 1385 if e.level == 0 { 1386 1387 // Before new element with colliding digest is inserted, 1388 // existing elem is a single element or a collision group. 1389 // elem.Count() returns 1 for single element, 1390 // and returns > 1 for collision group. 1391 elementCount, err := elem.Count(storage) 1392 if err != nil { 1393 // Don't need to wrap error as external error because err is already categorized by element.Count(). 1394 return nil, err 1395 } 1396 if elementCount == 0 { 1397 return nil, NewMapElementCountError("expect element count > 0, got element count == 0") 1398 } 1399 1400 // collisionCount is elementCount-1 because: 1401 // - if elem is single element, collision count is 0 (no collsion yet) 1402 // - if elem is collision group, collision count is 1 less than number 1403 // of elements in collision group. 1404 collisionCount := elementCount - 1 1405 1406 // Check if existing collision count reached MaxCollisionLimitPerDigest 1407 if collisionCount >= MaxCollisionLimitPerDigest { 1408 // Enforce collision limit on inserts and ignore updates. 1409 _, err = elem.Get(storage, digester, level, hkey, comparator, key) 1410 if err != nil { 1411 var knfe *KeyNotFoundError 1412 if errors.As(err, &knfe) { 1413 // Don't allow any more collisions for a digest that 1414 // already reached MaxCollisionLimitPerDigest. 1415 return nil, NewCollisionLimitError(MaxCollisionLimitPerDigest) 1416 } 1417 } 1418 } 1419 } 1420 1421 oldElemSize := elem.Size() 1422 1423 elem, existingValue, err := elem.Set(storage, address, b, digester, level, hkey, comparator, hip, key, value) 1424 if err != nil { 1425 // Don't need to wrap error as external error because err is already categorized by element.Set(). 1426 return nil, err 1427 } 1428 1429 e.elems[equalIndex] = elem 1430 1431 e.size += elem.Size() - oldElemSize 1432 1433 return existingValue, nil 1434 } 1435 1436 // No matching hkey 1437 1438 newElem, err := newSingleElement(storage, address, key, value) 1439 if err != nil { 1440 // Don't need to wrap error as external error because err is already categorized by newSingleElement(). 1441 return nil, err 1442 } 1443 1444 // insert into sorted hkeys 1445 e.hkeys = append(e.hkeys, Digest(0)) 1446 copy(e.hkeys[lessThanIndex+1:], e.hkeys[lessThanIndex:]) 1447 e.hkeys[lessThanIndex] = hkey 1448 1449 // insert into sorted elements 1450 e.elems = append(e.elems, nil) 1451 copy(e.elems[lessThanIndex+1:], e.elems[lessThanIndex:]) 1452 e.elems[lessThanIndex] = newElem 1453 1454 e.size += digestSize + newElem.Size() 1455 1456 return nil, nil 1457 } 1458 1459 func (e *hkeyElements) Remove(storage SlabStorage, digester Digester, level uint, hkey Digest, comparator ValueComparator, key Value) (MapKey, MapValue, error) { 1460 1461 // Check digest level 1462 if level >= digester.Levels() { 1463 return nil, nil, NewHashLevelErrorf("hkey elements digest level is %d, want < %d", level, digester.Levels()) 1464 } 1465 1466 if len(e.hkeys) == 0 || hkey < e.hkeys[0] || hkey > e.hkeys[len(e.hkeys)-1] { 1467 return nil, nil, NewKeyNotFoundError(key) 1468 } 1469 1470 // binary search by hkey 1471 1472 // Find index that e.hkeys[h] == hkey 1473 equalIndex := -1 1474 i, j := 0, len(e.hkeys) 1475 for i < j { 1476 h := int(uint(i+j) >> 1) // avoid overflow when computing h 1477 if e.hkeys[h] > hkey { 1478 j = h 1479 } else if e.hkeys[h] < hkey { 1480 i = h + 1 1481 } else { 1482 equalIndex = h 1483 break 1484 } 1485 } 1486 1487 // No matching hkey 1488 if equalIndex == -1 { 1489 return nil, nil, NewKeyNotFoundError(key) 1490 } 1491 1492 elem := e.elems[equalIndex] 1493 1494 oldElemSize := elem.Size() 1495 1496 k, v, elem, err := elem.Remove(storage, digester, level, hkey, comparator, key) 1497 if err != nil { 1498 // Don't need to wrap error as external error because err is already categorized by element.Remove(). 1499 return nil, nil, err 1500 } 1501 1502 if elem == nil { 1503 // Remove this element 1504 copy(e.elems[equalIndex:], e.elems[equalIndex+1:]) 1505 // Zero out last element to prevent memory leak 1506 e.elems[len(e.elems)-1] = nil 1507 // Reslice elements 1508 e.elems = e.elems[:len(e.elems)-1] 1509 1510 // Remove hkey for this element 1511 copy(e.hkeys[equalIndex:], e.hkeys[equalIndex+1:]) 1512 e.hkeys = e.hkeys[:len(e.hkeys)-1] 1513 1514 // Adjust size 1515 e.size -= digestSize + oldElemSize 1516 1517 return k, v, nil 1518 } 1519 1520 e.elems[equalIndex] = elem 1521 1522 e.size += elem.Size() - oldElemSize 1523 1524 return k, v, nil 1525 } 1526 1527 func (e *hkeyElements) Element(i int) (element, error) { 1528 if i >= len(e.elems) { 1529 return nil, NewIndexOutOfBoundsError(uint64(i), 0, uint64(len(e.elems))) 1530 } 1531 return e.elems[i], nil 1532 } 1533 1534 func (e *hkeyElements) HasPointer() bool { 1535 for _, elem := range e.elems { 1536 if elem.HasPointer() { 1537 return true 1538 } 1539 } 1540 return false 1541 } 1542 1543 func (e *hkeyElements) Merge(elems elements) error { 1544 1545 rElems, ok := elems.(*hkeyElements) 1546 if !ok { 1547 return NewSlabMergeError(fmt.Errorf("cannot merge elements of different types (%T, %T)", e, elems)) 1548 } 1549 1550 e.hkeys = append(e.hkeys, rElems.hkeys...) 1551 e.elems = append(e.elems, rElems.elems...) 1552 e.size += rElems.Size() - hkeyElementsPrefixSize 1553 1554 // Set merged elements to nil to prevent memory leak 1555 for i := 0; i < len(rElems.elems); i++ { 1556 rElems.elems[i] = nil 1557 } 1558 1559 return nil 1560 } 1561 1562 func (e *hkeyElements) Split() (elements, elements, error) { 1563 1564 // This computes the ceil of split to give the first slab more elements. 1565 dataSize := e.Size() - hkeyElementsPrefixSize 1566 midPoint := (dataSize + 1) >> 1 1567 1568 leftSize := uint32(0) 1569 leftCount := 0 1570 for i, elem := range e.elems { 1571 elemSize := elem.Size() + digestSize 1572 if leftSize+elemSize >= midPoint { 1573 // i is mid point element. Place i on the small side. 1574 if leftSize <= dataSize-leftSize-elemSize { 1575 leftSize += elemSize 1576 leftCount = i + 1 1577 } else { 1578 leftCount = i 1579 } 1580 break 1581 } 1582 // left slab size < midPoint 1583 leftSize += elemSize 1584 } 1585 1586 rightCount := len(e.elems) - leftCount 1587 1588 // Create right slab elements 1589 rightElements := &hkeyElements{level: e.level} 1590 1591 rightElements.hkeys = make([]Digest, rightCount) 1592 copy(rightElements.hkeys, e.hkeys[leftCount:]) 1593 1594 rightElements.elems = make([]element, rightCount) 1595 copy(rightElements.elems, e.elems[leftCount:]) 1596 1597 rightElements.size = dataSize - leftSize + hkeyElementsPrefixSize 1598 1599 e.hkeys = e.hkeys[:leftCount] 1600 e.elems = e.elems[:leftCount] 1601 e.size = hkeyElementsPrefixSize + leftSize 1602 1603 // NOTE: prevent memory leak 1604 for i := leftCount; i < len(e.hkeys); i++ { 1605 e.elems[i] = nil 1606 } 1607 1608 return e, rightElements, nil 1609 } 1610 1611 // LendToRight rebalances elements by moving elements from left to right 1612 func (e *hkeyElements) LendToRight(re elements) error { 1613 1614 minSize := minThreshold - mapDataSlabPrefixSize - hkeyElementsPrefixSize 1615 1616 rightElements := re.(*hkeyElements) 1617 1618 if e.level != rightElements.level { 1619 return NewSlabRebalanceError( 1620 NewHashLevelErrorf("left slab digest level %d != right slab digest level %d", e.level, rightElements.level), 1621 ) 1622 } 1623 1624 count := len(e.elems) + len(rightElements.elems) 1625 size := e.Size() + rightElements.Size() - hkeyElementsPrefixSize*2 1626 1627 leftCount := len(e.elems) 1628 leftSize := e.Size() - hkeyElementsPrefixSize 1629 1630 midPoint := (size + 1) >> 1 1631 1632 // Left elements size is as close to midPoint as possible while right elements size >= minThreshold 1633 for i := len(e.elems) - 1; i >= 0; i-- { 1634 elemSize := e.elems[i].Size() + digestSize 1635 if leftSize-elemSize < midPoint && size-leftSize >= uint32(minSize) { 1636 break 1637 } 1638 leftSize -= elemSize 1639 leftCount-- 1640 } 1641 1642 // Update the right elements 1643 // 1644 // It is easier and less error-prone to realloc elements for the right elements. 1645 1646 hkeys := make([]Digest, count-leftCount) 1647 n := copy(hkeys, e.hkeys[leftCount:]) 1648 copy(hkeys[n:], rightElements.hkeys) 1649 1650 elements := make([]element, count-leftCount) 1651 n = copy(elements, e.elems[leftCount:]) 1652 copy(elements[n:], rightElements.elems) 1653 1654 rightElements.hkeys = hkeys 1655 rightElements.elems = elements 1656 rightElements.size = size - leftSize + hkeyElementsPrefixSize 1657 1658 // Update left slab 1659 // NOTE: prevent memory leak 1660 for i := leftCount; i < len(e.elems); i++ { 1661 e.elems[i] = nil 1662 } 1663 e.hkeys = e.hkeys[:leftCount] 1664 e.elems = e.elems[:leftCount] 1665 e.size = hkeyElementsPrefixSize + leftSize 1666 1667 return nil 1668 } 1669 1670 // BorrowFromRight rebalances slabs by moving elements from right slab to left slab. 1671 func (e *hkeyElements) BorrowFromRight(re elements) error { 1672 1673 minSize := minThreshold - mapDataSlabPrefixSize - hkeyElementsPrefixSize 1674 1675 rightElements := re.(*hkeyElements) 1676 1677 if e.level != rightElements.level { 1678 return NewSlabRebalanceError( 1679 NewHashLevelErrorf("left slab digest level %d != right slab digest level %d", e.level, rightElements.level), 1680 ) 1681 } 1682 1683 size := e.Size() + rightElements.Size() - hkeyElementsPrefixSize*2 1684 1685 leftCount := len(e.elems) 1686 leftSize := e.Size() - hkeyElementsPrefixSize 1687 1688 midPoint := (size + 1) >> 1 1689 1690 for _, elem := range rightElements.elems { 1691 elemSize := elem.Size() + digestSize 1692 if leftSize+elemSize > midPoint { 1693 if size-leftSize-elemSize >= uint32(minSize) { 1694 // Include this element in left elements 1695 leftSize += elemSize 1696 leftCount++ 1697 } 1698 break 1699 } 1700 leftSize += elemSize 1701 leftCount++ 1702 } 1703 1704 rightStartIndex := leftCount - len(e.elems) 1705 1706 // Update left elements 1707 e.hkeys = append(e.hkeys, rightElements.hkeys[:rightStartIndex]...) 1708 e.elems = append(e.elems, rightElements.elems[:rightStartIndex]...) 1709 e.size = leftSize + hkeyElementsPrefixSize 1710 1711 // Update right slab 1712 // TODO: copy elements to front instead? 1713 // NOTE: prevent memory leak 1714 for i := 0; i < rightStartIndex; i++ { 1715 rightElements.elems[i] = nil 1716 } 1717 rightElements.hkeys = rightElements.hkeys[rightStartIndex:] 1718 rightElements.elems = rightElements.elems[rightStartIndex:] 1719 rightElements.size = size - leftSize + hkeyElementsPrefixSize 1720 1721 return nil 1722 } 1723 1724 func (e *hkeyElements) CanLendToLeft(size uint32) bool { 1725 if len(e.elems) == 0 { 1726 return false 1727 } 1728 1729 if len(e.elems) < 2 { 1730 return false 1731 } 1732 1733 minSize := minThreshold - mapDataSlabPrefixSize 1734 if e.Size()-size < uint32(minSize) { 1735 return false 1736 } 1737 1738 lendSize := uint32(0) 1739 for i := 0; i < len(e.elems); i++ { 1740 lendSize += e.elems[i].Size() + digestSize 1741 if e.Size()-lendSize < uint32(minSize) { 1742 return false 1743 } 1744 if lendSize >= size { 1745 return true 1746 } 1747 } 1748 return false 1749 } 1750 1751 func (e *hkeyElements) CanLendToRight(size uint32) bool { 1752 if len(e.elems) == 0 { 1753 return false 1754 } 1755 1756 if len(e.elems) < 2 { 1757 return false 1758 } 1759 1760 minSize := minThreshold - mapDataSlabPrefixSize 1761 if e.Size()-size < uint32(minSize) { 1762 return false 1763 } 1764 1765 lendSize := uint32(0) 1766 for i := len(e.elems) - 1; i >= 0; i-- { 1767 lendSize += e.elems[i].Size() + digestSize 1768 if e.Size()-lendSize < uint32(minSize) { 1769 return false 1770 } 1771 if lendSize >= size { 1772 return true 1773 } 1774 } 1775 return false 1776 } 1777 1778 func (e *hkeyElements) Size() uint32 { 1779 return e.size 1780 } 1781 1782 func (e *hkeyElements) Count() uint32 { 1783 return uint32(len(e.elems)) 1784 } 1785 1786 func (e *hkeyElements) firstKey() Digest { 1787 if len(e.hkeys) > 0 { 1788 return e.hkeys[0] 1789 } 1790 return 0 1791 } 1792 1793 func (e *hkeyElements) PopIterate(storage SlabStorage, fn MapPopIterationFunc) error { 1794 1795 // Iterate and reset elements backwards 1796 for i := len(e.elems) - 1; i >= 0; i-- { 1797 elem := e.elems[i] 1798 1799 err := elem.PopIterate(storage, fn) 1800 if err != nil { 1801 // Don't need to wrap error as external error because err is already categorized by element.PopIterate(). 1802 return err 1803 } 1804 } 1805 1806 // Reset data slab 1807 e.hkeys = nil 1808 e.elems = nil 1809 e.size = hkeyElementsPrefixSize 1810 1811 return nil 1812 } 1813 1814 func (e *hkeyElements) String() string { 1815 var s []string 1816 1817 for i := 0; i < len(e.elems); i++ { 1818 s = append(s, fmt.Sprintf("%d:%s", e.hkeys[i], e.elems[i].String())) 1819 } 1820 1821 return strings.Join(s, " ") 1822 } 1823 1824 func newSingleElementsWithElement(level uint, elem *singleElement) *singleElements { 1825 return &singleElements{ 1826 level: level, 1827 size: singleElementsPrefixSize + elem.size, 1828 elems: []*singleElement{elem}, 1829 } 1830 } 1831 1832 // Encode encodes singleElements to the given encoder. 1833 // 1834 // CBOR encoded array [ 1835 // 0: level (uint) 1836 // 1: hkeys (0 length byte string) 1837 // 2: elements (array) 1838 // ] 1839 func (e *singleElements) Encode(enc *Encoder) error { 1840 1841 if e.level > maxDigestLevel { 1842 return NewFatalError(fmt.Errorf("digest level %d exceeds max digest level %d", e.level, maxDigestLevel)) 1843 } 1844 1845 // Encode CBOR array header for 3 elements (level, hkeys, elements) 1846 enc.Scratch[0] = 0x83 1847 1848 // Encode hash level 1849 enc.Scratch[1] = byte(e.level) 1850 1851 // Encode hkeys (empty byte string) 1852 enc.Scratch[2] = 0x40 1853 1854 // Encode elements 1855 1856 // Encode elements array header manually for fix-sized encoding 1857 // TODO: maybe make this header dynamic to reduce size 1858 enc.Scratch[3] = 0x9b 1859 binary.BigEndian.PutUint64(enc.Scratch[4:], uint64(len(e.elems))) 1860 1861 // Write scratch content to encoder 1862 const totalSize = 12 1863 err := enc.CBOR.EncodeRawBytes(enc.Scratch[:totalSize]) 1864 if err != nil { 1865 return NewEncodingError(err) 1866 } 1867 1868 // Encode each element 1869 for _, e := range e.elems { 1870 err = e.Encode(enc) 1871 if err != nil { 1872 // Don't need to wrap error as external error because err is already categorized by singleElement.Encode(). 1873 return err 1874 } 1875 } 1876 1877 // TODO: is Flush necessar? 1878 err = enc.CBOR.Flush() 1879 if err != nil { 1880 return NewEncodingError(err) 1881 } 1882 1883 return nil 1884 } 1885 1886 func (e *singleElements) Get(storage SlabStorage, digester Digester, level uint, _ Digest, comparator ValueComparator, key Value) (MapValue, error) { 1887 1888 if level != digester.Levels() { 1889 return nil, NewHashLevelErrorf("single elements digest level is %d, want %d", level, digester.Levels()) 1890 } 1891 1892 // linear search by key 1893 for _, elem := range e.elems { 1894 equal, err := comparator(storage, key, elem.key) 1895 if err != nil { 1896 // Wrap err as external error (if needed) because err is returned by ValueComparator callback. 1897 return nil, wrapErrorfAsExternalErrorIfNeeded(err, "failed to compare keys") 1898 } 1899 if equal { 1900 return elem.value, nil 1901 } 1902 } 1903 1904 return nil, NewKeyNotFoundError(key) 1905 } 1906 1907 func (e *singleElements) Set(storage SlabStorage, address Address, b DigesterBuilder, digester Digester, level uint, _ Digest, comparator ValueComparator, hip HashInputProvider, key Value, value Value) (MapValue, error) { 1908 1909 if level != digester.Levels() { 1910 return nil, NewHashLevelErrorf("single elements digest level is %d, want %d", level, digester.Levels()) 1911 } 1912 1913 // linear search key and update value 1914 for i := 0; i < len(e.elems); i++ { 1915 elem := e.elems[i] 1916 1917 equal, err := comparator(storage, key, elem.key) 1918 if err != nil { 1919 // Wrap err as external error (if needed) because err is returned by ValueComparator callback. 1920 return nil, wrapErrorfAsExternalErrorIfNeeded(err, "failed to compare keys") 1921 } 1922 1923 if equal { 1924 existingValue := elem.value 1925 1926 oldSize := elem.Size() 1927 1928 vs, err := value.Storable(storage, address, MaxInlineMapKeyOrValueSize) 1929 if err != nil { 1930 // Wrap err as external error (if needed) because err is returned by Value interface. 1931 return nil, wrapErrorfAsExternalErrorIfNeeded(err, "failed to get value's storable") 1932 } 1933 1934 elem.value = vs 1935 elem.size = singleElementPrefixSize + elem.key.ByteSize() + elem.value.ByteSize() 1936 1937 e.size += elem.Size() - oldSize 1938 1939 return existingValue, nil 1940 } 1941 } 1942 1943 // no matching key, append new element to the end. 1944 newElem, err := newSingleElement(storage, address, key, value) 1945 if err != nil { 1946 // Don't need to wrap error as external error because err is already categorized by newSingleElement(). 1947 return nil, err 1948 } 1949 e.elems = append(e.elems, newElem) 1950 e.size += newElem.size 1951 1952 return nil, nil 1953 } 1954 1955 func (e *singleElements) Remove(storage SlabStorage, digester Digester, level uint, hkey Digest, comparator ValueComparator, key Value) (MapKey, MapValue, error) { 1956 1957 if level != digester.Levels() { 1958 return nil, nil, NewHashLevelErrorf("single elements digest level is %d, want %d", level, digester.Levels()) 1959 } 1960 1961 // linear search by key 1962 for i, elem := range e.elems { 1963 1964 equal, err := comparator(storage, key, elem.key) 1965 if err != nil { 1966 // Wrap err as external error (if needed) because err is returned by ValueComparator callback. 1967 return nil, nil, wrapErrorfAsExternalErrorIfNeeded(err, "failed to compare keys") 1968 } 1969 1970 if equal { 1971 // Remove this element 1972 copy(e.elems[i:], e.elems[i+1:]) 1973 // Zero out last element to prevent memory leak 1974 e.elems[len(e.elems)-1] = nil 1975 // Reslice elements 1976 e.elems = e.elems[:len(e.elems)-1] 1977 1978 // Adjust size 1979 e.size -= elem.Size() 1980 1981 return elem.key, elem.value, nil 1982 } 1983 } 1984 1985 return nil, nil, NewKeyNotFoundError(key) 1986 } 1987 1988 func (e *singleElements) Element(i int) (element, error) { 1989 if i >= len(e.elems) { 1990 return nil, NewIndexOutOfBoundsError(uint64(i), 0, uint64(len(e.elems))) 1991 } 1992 return e.elems[i], nil 1993 } 1994 1995 func (e *singleElements) Merge(elems elements) error { 1996 return NewNotApplicableError("singleElements", "elements", "Merge") 1997 } 1998 1999 func (e *singleElements) Split() (elements, elements, error) { 2000 return nil, nil, NewNotApplicableError("singleElements", "elements", "Split") 2001 } 2002 2003 func (e *singleElements) LendToRight(re elements) error { 2004 return NewNotApplicableError("singleElements", "elements", "LendToRight") 2005 } 2006 2007 func (e *singleElements) BorrowFromRight(re elements) error { 2008 return NewNotApplicableError("singleElements", "elements", "BorrowFromRight") 2009 } 2010 2011 func (e *singleElements) CanLendToLeft(size uint32) bool { 2012 return false 2013 } 2014 2015 func (e *singleElements) CanLendToRight(size uint32) bool { 2016 return false 2017 } 2018 2019 func (e *singleElements) HasPointer() bool { 2020 for _, elem := range e.elems { 2021 if elem.HasPointer() { 2022 return true 2023 } 2024 } 2025 return false 2026 } 2027 2028 func (e *singleElements) Count() uint32 { 2029 return uint32(len(e.elems)) 2030 } 2031 2032 func (e *singleElements) firstKey() Digest { 2033 return 0 2034 } 2035 2036 func (e *singleElements) Size() uint32 { 2037 return e.size 2038 } 2039 2040 func (e *singleElements) PopIterate(storage SlabStorage, fn MapPopIterationFunc) error { 2041 2042 // Iterate and reset elements backwards 2043 for i := len(e.elems) - 1; i >= 0; i-- { 2044 elem := e.elems[i] 2045 2046 err := elem.PopIterate(storage, fn) 2047 if err != nil { 2048 // Don't need to wrap error as external error because err is already categorized by singleElement.PopIterate(). 2049 return err 2050 } 2051 } 2052 2053 // Reset data slab 2054 e.elems = nil 2055 e.size = singleElementsPrefixSize 2056 2057 return nil 2058 } 2059 2060 func (e *singleElements) String() string { 2061 var s []string 2062 2063 for i := 0; i < len(e.elems); i++ { 2064 s = append(s, fmt.Sprintf(":%s", e.elems[i].String())) 2065 } 2066 2067 return strings.Join(s, " ") 2068 } 2069 2070 func newMapDataSlabFromData( 2071 id StorageID, 2072 data []byte, 2073 decMode cbor.DecMode, 2074 decodeStorable StorableDecoder, 2075 decodeTypeInfo TypeInfoDecoder, 2076 ) ( 2077 *MapDataSlab, 2078 error, 2079 ) { 2080 // Check minimum data length 2081 if len(data) < versionAndFlagSize { 2082 return nil, NewDecodingErrorf("data is too short for map data slab") 2083 } 2084 2085 isRootSlab := isRoot(data[1]) 2086 2087 var extraData *MapExtraData 2088 2089 // Check flag for extra data 2090 if isRootSlab { 2091 // Decode extra data 2092 var err error 2093 extraData, data, err = newMapExtraDataFromData(data, decMode, decodeTypeInfo) 2094 if err != nil { 2095 // Don't need to wrap error as external error because err is already categorized by newMapExtraDataFromData(). 2096 return nil, err 2097 } 2098 } 2099 2100 minDataLength := mapDataSlabPrefixSize 2101 if isRootSlab { 2102 minDataLength = mapRootDataSlabPrefixSize 2103 } 2104 2105 // Check data length (after decoding extra data if present) 2106 if len(data) < minDataLength { 2107 return nil, NewDecodingErrorf("data is too short for map data slab") 2108 } 2109 2110 // Check flag 2111 flag := data[1] 2112 2113 mapType := getSlabMapType(flag) 2114 2115 if mapType != slabMapData && mapType != slabMapCollisionGroup { 2116 return nil, NewDecodingErrorf( 2117 "data has invalid flag 0x%x, want 0x%x or 0x%x", 2118 flag, 2119 maskMapData, 2120 maskCollisionGroup, 2121 ) 2122 } 2123 2124 var next StorageID 2125 2126 var contentOffset int 2127 2128 if !isRootSlab { 2129 2130 // Decode next storage ID 2131 const nextStorageIDOffset = versionAndFlagSize 2132 var err error 2133 next, err = NewStorageIDFromRawBytes(data[nextStorageIDOffset:]) 2134 if err != nil { 2135 // Don't need to wrap error as external error because err is already categorized by NewStorageIDFromRawBytes(). 2136 return nil, err 2137 } 2138 2139 contentOffset = nextStorageIDOffset + storageIDSize 2140 2141 } else { 2142 contentOffset = versionAndFlagSize 2143 } 2144 2145 // Decode elements 2146 cborDec := decMode.NewByteStreamDecoder(data[contentOffset:]) 2147 elements, err := newElementsFromData(cborDec, decodeStorable) 2148 if err != nil { 2149 // Don't need to wrap error as external error because err is already categorized by newElementsFromData(). 2150 return nil, err 2151 } 2152 2153 header := MapSlabHeader{ 2154 id: id, 2155 size: uint32(len(data)), 2156 firstKey: elements.firstKey(), 2157 } 2158 2159 return &MapDataSlab{ 2160 next: next, 2161 header: header, 2162 elements: elements, 2163 extraData: extraData, 2164 anySize: !hasSizeLimit(flag), 2165 collisionGroup: mapType == slabMapCollisionGroup, 2166 }, nil 2167 } 2168 2169 // Encode encodes this map data slab to the given encoder. 2170 // 2171 // Header (18 bytes): 2172 // 2173 // +-------------------------------+--------------------------------+ 2174 // | slab version + flag (2 bytes) | next sib storage ID (16 bytes) | 2175 // +-------------------------------+--------------------------------+ 2176 // 2177 // Content (for now): 2178 // 2179 // CBOR array of 3 elements (level, hkeys, elements) 2180 // 2181 // If this is root slab, extra data section is prepended to slab's encoded content. 2182 // See MapExtraData.Encode() for extra data section format. 2183 func (m *MapDataSlab) Encode(enc *Encoder) error { 2184 2185 version := byte(0) 2186 2187 flag := maskMapData 2188 2189 if m.collisionGroup { 2190 flag = maskCollisionGroup 2191 } 2192 2193 if m.hasPointer() { 2194 flag = setHasPointers(flag) 2195 } 2196 2197 if m.anySize { 2198 flag = setNoSizeLimit(flag) 2199 } 2200 2201 // Encode extra data if present 2202 if m.extraData != nil { 2203 flag = setRoot(flag) 2204 2205 err := m.extraData.Encode(enc, version, flag) 2206 if err != nil { 2207 // Don't need to wrap error as external error because err is already categorized by MapExtraData.Encode(). 2208 return err 2209 } 2210 } 2211 2212 // Encode version 2213 enc.Scratch[0] = version 2214 2215 // Encode flag 2216 enc.Scratch[1] = flag 2217 2218 var totalSize int 2219 2220 if m.extraData == nil { 2221 2222 // Encode next storage ID to scratch 2223 const nextStorageIDOffset = versionAndFlagSize 2224 _, err := m.next.ToRawBytes(enc.Scratch[nextStorageIDOffset:]) 2225 if err != nil { 2226 // Don't need to wrap error as external error because err is already categorized by StorageID.ToRawBytes(). 2227 return err 2228 } 2229 2230 totalSize = nextStorageIDOffset + storageIDSize 2231 2232 } else { 2233 2234 totalSize = versionAndFlagSize 2235 } 2236 2237 // Write scratch content to encoder 2238 _, err := enc.Write(enc.Scratch[:totalSize]) 2239 if err != nil { 2240 return NewEncodingError(err) 2241 } 2242 2243 // Encode elements 2244 err = m.elements.Encode(enc) 2245 if err != nil { 2246 // Don't need to wrap error as external error because err is already categorized by elements.Encode(). 2247 return err 2248 } 2249 2250 err = enc.CBOR.Flush() 2251 if err != nil { 2252 return NewEncodingError(err) 2253 } 2254 2255 return nil 2256 } 2257 2258 func (m *MapDataSlab) hasPointer() bool { 2259 return m.elements.HasPointer() 2260 } 2261 2262 func (m *MapDataSlab) ChildStorables() []Storable { 2263 return elementsStorables(m.elements, nil) 2264 } 2265 2266 func elementsStorables(elems elements, childStorables []Storable) []Storable { 2267 2268 switch v := elems.(type) { 2269 2270 case *hkeyElements: 2271 for i := 0; i < len(v.elems); i++ { 2272 childStorables = elementStorables(v.elems[i], childStorables) 2273 } 2274 2275 case *singleElements: 2276 for i := 0; i < len(v.elems); i++ { 2277 childStorables = elementStorables(v.elems[i], childStorables) 2278 } 2279 2280 } 2281 2282 return childStorables 2283 } 2284 2285 func elementStorables(e element, childStorables []Storable) []Storable { 2286 2287 switch v := e.(type) { 2288 2289 case *externalCollisionGroup: 2290 return append(childStorables, StorageIDStorable(v.id)) 2291 2292 case *inlineCollisionGroup: 2293 return elementsStorables(v.elements, childStorables) 2294 2295 case *singleElement: 2296 return append(childStorables, v.key, v.value) 2297 } 2298 2299 panic(NewUnreachableError()) 2300 } 2301 2302 func (m *MapDataSlab) StoredValue(storage SlabStorage) (Value, error) { 2303 if m.extraData == nil { 2304 return nil, NewNotValueError(m.ID()) 2305 } 2306 2307 digestBuilder := NewDefaultDigesterBuilder() 2308 2309 digestBuilder.SetSeed(m.extraData.Seed, typicalRandomConstant) 2310 2311 return &OrderedMap{ 2312 Storage: storage, 2313 root: m, 2314 digesterBuilder: digestBuilder, 2315 }, nil 2316 } 2317 2318 func (m *MapDataSlab) Set(storage SlabStorage, b DigesterBuilder, digester Digester, level uint, hkey Digest, comparator ValueComparator, hip HashInputProvider, key Value, value Value) (MapValue, error) { 2319 2320 existingValue, err := m.elements.Set(storage, m.ID().Address, b, digester, level, hkey, comparator, hip, key, value) 2321 if err != nil { 2322 // Don't need to wrap error as external error because err is already categorized by elements.Set(). 2323 return nil, err 2324 } 2325 2326 // Adjust header's first key 2327 m.header.firstKey = m.elements.firstKey() 2328 2329 // Adjust header's slab size 2330 if m.extraData == nil { 2331 m.header.size = mapDataSlabPrefixSize + m.elements.Size() 2332 } else { 2333 m.header.size = mapRootDataSlabPrefixSize + m.elements.Size() 2334 } 2335 2336 // Store modified slab 2337 err = storage.Store(m.header.id, m) 2338 if err != nil { 2339 // Wrap err as external error (if needed) because err is returned by SlabStorage interface. 2340 return nil, wrapErrorfAsExternalErrorIfNeeded(err, fmt.Sprintf("failed to store slab %s", m.header.id)) 2341 } 2342 2343 return existingValue, nil 2344 } 2345 2346 func (m *MapDataSlab) Remove(storage SlabStorage, digester Digester, level uint, hkey Digest, comparator ValueComparator, key Value) (MapKey, MapValue, error) { 2347 2348 k, v, err := m.elements.Remove(storage, digester, level, hkey, comparator, key) 2349 if err != nil { 2350 // Don't need to wrap error as external error because err is already categorized by elements.Remove(). 2351 return nil, nil, err 2352 } 2353 2354 // Adjust header's first key 2355 m.header.firstKey = m.elements.firstKey() 2356 2357 // Adjust header's slab size 2358 if m.extraData == nil { 2359 m.header.size = mapDataSlabPrefixSize + m.elements.Size() 2360 } else { 2361 m.header.size = mapRootDataSlabPrefixSize + m.elements.Size() 2362 } 2363 2364 // Store modified slab 2365 err = storage.Store(m.header.id, m) 2366 if err != nil { 2367 // Wrap err as external error (if needed) because err is returned by SlabStorage interface. 2368 return nil, nil, wrapErrorfAsExternalErrorIfNeeded(err, fmt.Sprintf("failed to store slab %s", m.header.id)) 2369 } 2370 2371 return k, v, nil 2372 } 2373 2374 func (m *MapDataSlab) Split(storage SlabStorage) (Slab, Slab, error) { 2375 if m.elements.Count() < 2 { 2376 // Can't split slab with less than two elements 2377 return nil, nil, NewSlabSplitErrorf("MapDataSlab (%s) has less than 2 elements", m.header.id) 2378 } 2379 2380 leftElements, rightElements, err := m.elements.Split() 2381 if err != nil { 2382 // Don't need to wrap error as external error because err is already categorized by elements.Split(). 2383 return nil, nil, err 2384 } 2385 2386 sID, err := storage.GenerateStorageID(m.ID().Address) 2387 if err != nil { 2388 // Wrap err as external error (if needed) because err is returned by SlabStorage interface. 2389 return nil, nil, wrapErrorfAsExternalErrorIfNeeded(err, fmt.Sprintf("failed to generate storage ID for address 0x%x", m.ID().Address)) 2390 } 2391 2392 // Create new right slab 2393 rightSlab := &MapDataSlab{ 2394 header: MapSlabHeader{ 2395 id: sID, 2396 size: mapDataSlabPrefixSize + rightElements.Size(), 2397 firstKey: rightElements.firstKey(), 2398 }, 2399 next: m.next, 2400 elements: rightElements, 2401 anySize: m.anySize, 2402 } 2403 2404 // Modify left (original) slab 2405 m.header.size = mapDataSlabPrefixSize + leftElements.Size() 2406 m.next = rightSlab.header.id 2407 m.elements = leftElements 2408 2409 return m, rightSlab, nil 2410 } 2411 2412 func (m *MapDataSlab) Merge(slab Slab) error { 2413 2414 rightSlab := slab.(*MapDataSlab) 2415 2416 err := m.elements.Merge(rightSlab.elements) 2417 if err != nil { 2418 // Don't need to wrap error as external error because err is already categorized by elements.Merge(). 2419 return err 2420 } 2421 2422 m.header.size = mapDataSlabPrefixSize + m.elements.Size() 2423 m.header.firstKey = m.elements.firstKey() 2424 2425 m.next = rightSlab.next 2426 2427 return nil 2428 } 2429 2430 func (m *MapDataSlab) LendToRight(slab Slab) error { 2431 rightSlab := slab.(*MapDataSlab) 2432 2433 if m.anySize || rightSlab.anySize { 2434 return NewSlabRebalanceErrorf("any sized data slab doesn't need to rebalance") 2435 } 2436 2437 rightElements := rightSlab.elements 2438 err := m.elements.LendToRight(rightElements) 2439 if err != nil { 2440 // Don't need to wrap error as external error because err is already categorized by elements.LendToRight(). 2441 return err 2442 } 2443 2444 // Update right slab 2445 rightSlab.elements = rightElements 2446 rightSlab.header.size = mapDataSlabPrefixSize + rightElements.Size() 2447 rightSlab.header.firstKey = rightElements.firstKey() 2448 2449 // Update left slab 2450 m.header.size = mapDataSlabPrefixSize + m.elements.Size() 2451 2452 return nil 2453 } 2454 2455 func (m *MapDataSlab) BorrowFromRight(slab Slab) error { 2456 2457 rightSlab := slab.(*MapDataSlab) 2458 2459 if m.anySize || rightSlab.anySize { 2460 return NewSlabRebalanceErrorf("any sized data slab doesn't need to rebalance") 2461 } 2462 2463 rightElements := rightSlab.elements 2464 err := m.elements.BorrowFromRight(rightElements) 2465 if err != nil { 2466 // Don't need to wrap error as external error because err is already categorized by elements.BorrowFromRight(). 2467 return err 2468 } 2469 2470 // Update right slab 2471 rightSlab.elements = rightElements 2472 rightSlab.header.size = mapDataSlabPrefixSize + rightElements.Size() 2473 rightSlab.header.firstKey = rightElements.firstKey() 2474 2475 // Update left slab 2476 m.header.size = mapDataSlabPrefixSize + m.elements.Size() 2477 m.header.firstKey = m.elements.firstKey() 2478 2479 return nil 2480 } 2481 2482 func (m *MapDataSlab) IsFull() bool { 2483 if m.anySize { 2484 return false 2485 } 2486 return m.header.size > uint32(maxThreshold) 2487 } 2488 2489 // IsUnderflow returns the number of bytes needed for the data slab 2490 // to reach the min threshold. 2491 // Returns true if the min threshold has not been reached yet. 2492 func (m *MapDataSlab) IsUnderflow() (uint32, bool) { 2493 if m.anySize { 2494 return 0, false 2495 } 2496 if uint32(minThreshold) > m.header.size { 2497 return uint32(minThreshold) - m.header.size, true 2498 } 2499 return 0, false 2500 } 2501 2502 // CanLendToLeft returns true if elements on the left of the slab could be removed 2503 // so that the slab still stores more than the min threshold. 2504 func (m *MapDataSlab) CanLendToLeft(size uint32) bool { 2505 if m.anySize { 2506 return false 2507 } 2508 return m.elements.CanLendToLeft(size) 2509 } 2510 2511 // CanLendToRight returns true if elements on the right of the slab could be removed 2512 // so that the slab still stores more than the min threshold. 2513 func (m *MapDataSlab) CanLendToRight(size uint32) bool { 2514 if m.anySize { 2515 return false 2516 } 2517 return m.elements.CanLendToRight(size) 2518 } 2519 2520 func (m *MapDataSlab) SetID(id StorageID) { 2521 m.header.id = id 2522 } 2523 2524 func (m *MapDataSlab) Header() MapSlabHeader { 2525 return m.header 2526 } 2527 2528 func (m *MapDataSlab) IsData() bool { 2529 return true 2530 } 2531 2532 func (m *MapDataSlab) ID() StorageID { 2533 return m.header.id 2534 } 2535 2536 func (m *MapDataSlab) ByteSize() uint32 { 2537 return m.header.size 2538 } 2539 2540 func (m *MapDataSlab) ExtraData() *MapExtraData { 2541 return m.extraData 2542 } 2543 2544 func (m *MapDataSlab) RemoveExtraData() *MapExtraData { 2545 extraData := m.extraData 2546 m.extraData = nil 2547 return extraData 2548 } 2549 2550 func (m *MapDataSlab) SetExtraData(extraData *MapExtraData) { 2551 m.extraData = extraData 2552 } 2553 2554 func (m *MapDataSlab) PopIterate(storage SlabStorage, fn MapPopIterationFunc) error { 2555 err := m.elements.PopIterate(storage, fn) 2556 if err != nil { 2557 // Don't need to wrap error as external error because err is already categorized by elements.PopIterate(). 2558 return err 2559 } 2560 2561 // Reset data slab 2562 m.header.size = mapDataSlabPrefixSize + hkeyElementsPrefixSize 2563 m.header.firstKey = 0 2564 return nil 2565 } 2566 2567 func (m *MapDataSlab) String() string { 2568 return fmt.Sprintf("MapDataSlab id:%s size:%d firstkey:%d elements: [%s]", 2569 m.header.id, 2570 m.header.size, 2571 m.header.firstKey, 2572 m.elements.String(), 2573 ) 2574 } 2575 2576 func newMapMetaDataSlabFromData( 2577 id StorageID, 2578 data []byte, 2579 decMode cbor.DecMode, 2580 decodeTypeInfo TypeInfoDecoder, 2581 ) (*MapMetaDataSlab, error) { 2582 // Check minimum data length 2583 if len(data) < versionAndFlagSize { 2584 return nil, NewDecodingErrorf("data is too short for map metadata slab") 2585 } 2586 2587 var extraData *MapExtraData 2588 2589 // Check flag for extra data 2590 if isRoot(data[1]) { 2591 // Decode extra data 2592 var err error 2593 extraData, data, err = newMapExtraDataFromData(data, decMode, decodeTypeInfo) 2594 if err != nil { 2595 // Don't need to wrap error as external error because err is already categorized by newMapExtraDataFromData(). 2596 return nil, err 2597 } 2598 } 2599 2600 // Check data length (after decoding extra data if present) 2601 if len(data) < mapMetaDataSlabPrefixSize { 2602 return nil, NewDecodingErrorf("data is too short for map metadata slab") 2603 } 2604 2605 // Check flag 2606 flag := data[1] 2607 if getSlabMapType(flag) != slabMapMeta { 2608 return nil, NewDecodingErrorf( 2609 "data has invalid flag 0x%x, want 0x%x", 2610 flag, 2611 maskMapMeta, 2612 ) 2613 } 2614 2615 // Decode number of child headers 2616 const childHeaderCountOffset = versionAndFlagSize 2617 childHeaderCount := binary.BigEndian.Uint16(data[childHeaderCountOffset:]) 2618 2619 expectedDataLength := mapMetaDataSlabPrefixSize + mapSlabHeaderSize*int(childHeaderCount) 2620 if len(data) != expectedDataLength { 2621 return nil, NewDecodingErrorf( 2622 "data has unexpected length %d, want %d", 2623 len(data), 2624 expectedDataLength, 2625 ) 2626 } 2627 2628 // Decode child headers 2629 childrenHeaders := make([]MapSlabHeader, childHeaderCount) 2630 offset := childHeaderCountOffset + 2 2631 2632 for i := 0; i < int(childHeaderCount); i++ { 2633 storageID, err := NewStorageIDFromRawBytes(data[offset:]) 2634 if err != nil { 2635 // Don't need to wrap error as external error because err is already categorized by NewStorageIDFromRawBytes(). 2636 return nil, err 2637 } 2638 2639 firstKeyOffset := offset + storageIDSize 2640 firstKey := binary.BigEndian.Uint64(data[firstKeyOffset:]) 2641 2642 sizeOffset := firstKeyOffset + digestSize 2643 size := binary.BigEndian.Uint32(data[sizeOffset:]) 2644 2645 childrenHeaders[i] = MapSlabHeader{ 2646 id: storageID, 2647 size: size, 2648 firstKey: Digest(firstKey), 2649 } 2650 2651 offset += mapSlabHeaderSize 2652 } 2653 2654 var firstKey Digest 2655 if len(childrenHeaders) > 0 { 2656 firstKey = childrenHeaders[0].firstKey 2657 } 2658 2659 header := MapSlabHeader{ 2660 id: id, 2661 size: uint32(len(data)), 2662 firstKey: firstKey, 2663 } 2664 2665 return &MapMetaDataSlab{ 2666 header: header, 2667 childrenHeaders: childrenHeaders, 2668 extraData: extraData, 2669 }, nil 2670 } 2671 2672 // Encode encodes this array meta-data slab to the given encoder. 2673 // 2674 // Header (4 bytes): 2675 // 2676 // +-----------------------+--------------------+------------------------------+ 2677 // | slab version (1 byte) | slab flag (1 byte) | child header count (2 bytes) | 2678 // +-----------------------+--------------------+------------------------------+ 2679 // 2680 // Content (n * 28 bytes): 2681 // 2682 // [[storage id, first key, size], ...] 2683 // 2684 // If this is root slab, extra data section is prepended to slab's encoded content. 2685 // See MapExtraData.Encode() for extra data section format. 2686 func (m *MapMetaDataSlab) Encode(enc *Encoder) error { 2687 2688 version := byte(0) 2689 2690 flag := maskMapMeta 2691 2692 // Encode extra data if present 2693 if m.extraData != nil { 2694 flag = setRoot(flag) 2695 2696 err := m.extraData.Encode(enc, version, flag) 2697 if err != nil { 2698 // Don't need to wrap error as external error because err is already categorized by MapExtraData.Encode(). 2699 return err 2700 } 2701 } 2702 2703 // Encode version 2704 enc.Scratch[0] = version 2705 2706 // Encode flag 2707 enc.Scratch[1] = flag 2708 2709 // Encode child header count to scratch 2710 const childHeaderCountOffset = versionAndFlagSize 2711 binary.BigEndian.PutUint16( 2712 enc.Scratch[childHeaderCountOffset:], 2713 uint16(len(m.childrenHeaders)), 2714 ) 2715 2716 // Write scratch content to encoder 2717 const totalSize = childHeaderCountOffset + 2 2718 _, err := enc.Write(enc.Scratch[:totalSize]) 2719 if err != nil { 2720 return NewEncodingError(err) 2721 } 2722 2723 // Encode children headers 2724 for _, h := range m.childrenHeaders { 2725 _, err := h.id.ToRawBytes(enc.Scratch[:]) 2726 if err != nil { 2727 // Don't need to wrap error as external error because err is already categorized by StorageID.ToRawBytes(). 2728 return err 2729 } 2730 2731 const firstKeyOffset = storageIDSize 2732 binary.BigEndian.PutUint64(enc.Scratch[firstKeyOffset:], uint64(h.firstKey)) 2733 2734 const sizeOffset = firstKeyOffset + digestSize 2735 binary.BigEndian.PutUint32(enc.Scratch[sizeOffset:], h.size) 2736 2737 const totalSize = sizeOffset + 4 2738 _, err = enc.Write(enc.Scratch[:totalSize]) 2739 if err != nil { 2740 return NewEncodingError(err) 2741 } 2742 } 2743 2744 return nil 2745 } 2746 2747 func (m *MapMetaDataSlab) StoredValue(storage SlabStorage) (Value, error) { 2748 if m.extraData == nil { 2749 return nil, NewNotValueError(m.ID()) 2750 } 2751 2752 digestBuilder := NewDefaultDigesterBuilder() 2753 2754 digestBuilder.SetSeed(m.extraData.Seed, typicalRandomConstant) 2755 2756 return &OrderedMap{ 2757 Storage: storage, 2758 root: m, 2759 digesterBuilder: digestBuilder, 2760 }, nil 2761 } 2762 2763 func (m *MapMetaDataSlab) ChildStorables() []Storable { 2764 childIDs := make([]Storable, len(m.childrenHeaders)) 2765 2766 for i, h := range m.childrenHeaders { 2767 childIDs[i] = StorageIDStorable(h.id) 2768 } 2769 2770 return childIDs 2771 } 2772 2773 func (m *MapMetaDataSlab) Get(storage SlabStorage, digester Digester, level uint, hkey Digest, comparator ValueComparator, key Value) (MapValue, error) { 2774 2775 ans := -1 2776 i, j := 0, len(m.childrenHeaders) 2777 for i < j { 2778 h := int(uint(i+j) >> 1) // avoid overflow when computing h 2779 if m.childrenHeaders[h].firstKey > hkey { 2780 j = h 2781 } else { 2782 ans = h 2783 i = h + 1 2784 } 2785 } 2786 2787 if ans == -1 { 2788 return nil, NewKeyNotFoundError(key) 2789 } 2790 2791 childHeaderIndex := ans 2792 2793 childID := m.childrenHeaders[childHeaderIndex].id 2794 2795 child, err := getMapSlab(storage, childID) 2796 if err != nil { 2797 // Don't need to wrap error as external error because err is already categorized by getMapSlab(). 2798 return nil, err 2799 } 2800 2801 // Don't need to wrap error as external error because err is already categorized by MapSlab.Get(). 2802 return child.Get(storage, digester, level, hkey, comparator, key) 2803 } 2804 2805 func (m *MapMetaDataSlab) Set(storage SlabStorage, b DigesterBuilder, digester Digester, level uint, hkey Digest, comparator ValueComparator, hip HashInputProvider, key Value, value Value) (MapValue, error) { 2806 2807 ans := 0 2808 i, j := 0, len(m.childrenHeaders) 2809 for i < j { 2810 h := int(uint(i+j) >> 1) // avoid overflow when computing h 2811 if m.childrenHeaders[h].firstKey > hkey { 2812 j = h 2813 } else { 2814 ans = h 2815 i = h + 1 2816 } 2817 } 2818 2819 childHeaderIndex := ans 2820 2821 childID := m.childrenHeaders[childHeaderIndex].id 2822 2823 child, err := getMapSlab(storage, childID) 2824 if err != nil { 2825 // Don't need to wrap error as external error because err is already categorized by getMapSlab(). 2826 return nil, err 2827 } 2828 2829 existingValue, err := child.Set(storage, b, digester, level, hkey, comparator, hip, key, value) 2830 if err != nil { 2831 // Don't need to wrap error as external error because err is already categorized by MapSlab.Set(). 2832 return nil, err 2833 } 2834 2835 m.childrenHeaders[childHeaderIndex] = child.Header() 2836 2837 if childHeaderIndex == 0 { 2838 // Update firstKey. May not be necessary. 2839 m.header.firstKey = m.childrenHeaders[childHeaderIndex].firstKey 2840 } 2841 2842 if child.IsFull() { 2843 err := m.SplitChildSlab(storage, child, childHeaderIndex) 2844 if err != nil { 2845 // Don't need to wrap error as external error because err is already categorized by MapMetaDataSlab.SplitChildSlab(). 2846 return nil, err 2847 } 2848 return existingValue, nil 2849 } 2850 2851 if underflowSize, underflow := child.IsUnderflow(); underflow { 2852 err := m.MergeOrRebalanceChildSlab(storage, child, childHeaderIndex, underflowSize) 2853 if err != nil { 2854 // Don't need to wrap error as external error because err is already categorized by MapMetaDataSlab.MergeOrRebalanceChildSlab(). 2855 return nil, err 2856 } 2857 return existingValue, nil 2858 } 2859 2860 err = storage.Store(m.header.id, m) 2861 if err != nil { 2862 // Wrap err as external error (if needed) because err is returned by SlabStorage interface. 2863 return nil, wrapErrorfAsExternalErrorIfNeeded(err, fmt.Sprintf("failed to store slab %s", m.header.id)) 2864 } 2865 return existingValue, nil 2866 } 2867 2868 func (m *MapMetaDataSlab) Remove(storage SlabStorage, digester Digester, level uint, hkey Digest, comparator ValueComparator, key Value) (MapKey, MapValue, error) { 2869 2870 ans := -1 2871 i, j := 0, len(m.childrenHeaders) 2872 for i < j { 2873 h := int(uint(i+j) >> 1) // avoid overflow when computing h 2874 if m.childrenHeaders[h].firstKey > hkey { 2875 j = h 2876 } else { 2877 ans = h 2878 i = h + 1 2879 } 2880 } 2881 2882 if ans == -1 { 2883 return nil, nil, NewKeyNotFoundError(key) 2884 } 2885 2886 childHeaderIndex := ans 2887 2888 childID := m.childrenHeaders[childHeaderIndex].id 2889 2890 child, err := getMapSlab(storage, childID) 2891 if err != nil { 2892 // Don't need to wrap error as external error because err is already categorized by getMapSlab(). 2893 return nil, nil, err 2894 } 2895 2896 k, v, err := child.Remove(storage, digester, level, hkey, comparator, key) 2897 if err != nil { 2898 // Don't need to wrap error as external error because err is already categorized by MapSlab.Remove(). 2899 return nil, nil, err 2900 } 2901 2902 m.childrenHeaders[childHeaderIndex] = child.Header() 2903 2904 if childHeaderIndex == 0 { 2905 // Update firstKey. May not be necessary. 2906 m.header.firstKey = m.childrenHeaders[childHeaderIndex].firstKey 2907 } 2908 2909 if child.IsFull() { 2910 err := m.SplitChildSlab(storage, child, childHeaderIndex) 2911 if err != nil { 2912 // Don't need to wrap error as external error because err is already categorized by MapMetaDataSlab.SplitChildSlab(). 2913 return nil, nil, err 2914 } 2915 return k, v, nil 2916 } 2917 2918 if underflowSize, underflow := child.IsUnderflow(); underflow { 2919 err := m.MergeOrRebalanceChildSlab(storage, child, childHeaderIndex, underflowSize) 2920 if err != nil { 2921 // Don't need to wrap error as external error because err is already categorized by MapMetaDataSlab.MergeOrRebalanceChildSlab(). 2922 return nil, nil, err 2923 } 2924 return k, v, nil 2925 } 2926 2927 err = storage.Store(m.header.id, m) 2928 if err != nil { 2929 // Wrap err as external error (if needed) because err is returned by SlabStorage interface. 2930 return nil, nil, wrapErrorfAsExternalErrorIfNeeded(err, fmt.Sprintf("failed to store slab %s", m.header.id)) 2931 } 2932 return k, v, nil 2933 } 2934 2935 func (m *MapMetaDataSlab) SplitChildSlab(storage SlabStorage, child MapSlab, childHeaderIndex int) error { 2936 leftSlab, rightSlab, err := child.Split(storage) 2937 if err != nil { 2938 // Don't need to wrap error as external error because err is already categorized by MapSlab.Split(). 2939 return err 2940 } 2941 2942 left := leftSlab.(MapSlab) 2943 right := rightSlab.(MapSlab) 2944 2945 // Add new child slab (right) to childrenHeaders 2946 m.childrenHeaders = append(m.childrenHeaders, MapSlabHeader{}) 2947 if childHeaderIndex < len(m.childrenHeaders)-2 { 2948 copy(m.childrenHeaders[childHeaderIndex+2:], m.childrenHeaders[childHeaderIndex+1:]) 2949 } 2950 m.childrenHeaders[childHeaderIndex] = left.Header() 2951 m.childrenHeaders[childHeaderIndex+1] = right.Header() 2952 2953 // Increase header size 2954 m.header.size += mapSlabHeaderSize 2955 2956 // Store modified slabs 2957 err = storage.Store(left.ID(), left) 2958 if err != nil { 2959 // Wrap err as external error (if needed) because err is returned by SlabStorage interface. 2960 return wrapErrorfAsExternalErrorIfNeeded(err, fmt.Sprintf("failed to store slab %s", left.ID())) 2961 } 2962 2963 err = storage.Store(right.ID(), right) 2964 if err != nil { 2965 // Wrap err as external error (if needed) because err is returned by SlabStorage interface. 2966 return wrapErrorfAsExternalErrorIfNeeded(err, fmt.Sprintf("failed to store slab %s", right.ID())) 2967 } 2968 2969 err = storage.Store(m.header.id, m) 2970 if err != nil { 2971 // Wrap err as external error (if needed) because err is returned by SlabStorage interface. 2972 return wrapErrorfAsExternalErrorIfNeeded(err, fmt.Sprintf("failed to store slab %s", m.header.id)) 2973 } 2974 2975 return nil 2976 } 2977 2978 // MergeOrRebalanceChildSlab merges or rebalances child slab. 2979 // parent slab's data is adjusted. 2980 // If merged, then parent slab's data is adjusted. 2981 // 2982 // +-----------------------+-----------------------+----------------------+-----------------------+ 2983 // | | no left sibling (sib) | left sib can't lend | left sib can lend | 2984 // +=======================+=======================+======================+=======================+ 2985 // | no right sib | panic | merge with left | rebalance with left | 2986 // +-----------------------+-----------------------+----------------------+-----------------------+ 2987 // | right sib can't lend | merge with right | merge with smaller | rebalance with left | 2988 // +-----------------------+-----------------------+----------------------+-----------------------+ 2989 // | right sib can lend | rebalance with right | rebalance with right | rebalance with bigger | 2990 // +-----------------------+-----------------------+----------------------+-----------------------+ 2991 func (m *MapMetaDataSlab) MergeOrRebalanceChildSlab( 2992 storage SlabStorage, 2993 child MapSlab, 2994 childHeaderIndex int, 2995 underflowSize uint32, 2996 ) error { 2997 2998 // Retrieve left sibling of the same parent. 2999 var leftSib MapSlab 3000 if childHeaderIndex > 0 { 3001 leftSibID := m.childrenHeaders[childHeaderIndex-1].id 3002 3003 var err error 3004 leftSib, err = getMapSlab(storage, leftSibID) 3005 if err != nil { 3006 // Don't need to wrap error as external error because err is already categorized by getMapSlab(). 3007 return err 3008 } 3009 } 3010 3011 // Retrieve right siblings of the same parent. 3012 var rightSib MapSlab 3013 if childHeaderIndex < len(m.childrenHeaders)-1 { 3014 rightSibID := m.childrenHeaders[childHeaderIndex+1].id 3015 3016 var err error 3017 rightSib, err = getMapSlab(storage, rightSibID) 3018 if err != nil { 3019 // Don't need to wrap error as external error because err is already categorized by getMapSlab(). 3020 return err 3021 } 3022 } 3023 3024 leftCanLend := leftSib != nil && leftSib.CanLendToRight(underflowSize) 3025 rightCanLend := rightSib != nil && rightSib.CanLendToLeft(underflowSize) 3026 3027 // Child can rebalance elements with at least one sibling. 3028 if leftCanLend || rightCanLend { 3029 3030 // Rebalance with right sib 3031 if !leftCanLend { 3032 3033 err := child.BorrowFromRight(rightSib) 3034 if err != nil { 3035 // Don't need to wrap error as external error because err is already categorized by MapSlab.BorrowFromRight(). 3036 return err 3037 } 3038 3039 m.childrenHeaders[childHeaderIndex] = child.Header() 3040 m.childrenHeaders[childHeaderIndex+1] = rightSib.Header() 3041 3042 // This is needed when child is at index 0 and it is empty. 3043 if childHeaderIndex == 0 { 3044 m.header.firstKey = child.Header().firstKey 3045 } 3046 3047 // Store modified slabs 3048 err = storage.Store(child.ID(), child) 3049 if err != nil { 3050 // Wrap err as external error (if needed) because err is returned by SlabStorage interface. 3051 return wrapErrorfAsExternalErrorIfNeeded(err, fmt.Sprintf("failed to store slab %s", child.ID())) 3052 } 3053 3054 err = storage.Store(rightSib.ID(), rightSib) 3055 if err != nil { 3056 // Wrap err as external error (if needed) because err is returned by SlabStorage interface. 3057 return wrapErrorfAsExternalErrorIfNeeded(err, fmt.Sprintf("failed to store slab %s", rightSib.ID())) 3058 } 3059 3060 err = storage.Store(m.header.id, m) 3061 if err != nil { 3062 // Wrap err as external error (if needed) because err is returned by SlabStorage interface. 3063 return wrapErrorfAsExternalErrorIfNeeded(err, fmt.Sprintf("failed to store slab %s", m.header.id)) 3064 } 3065 return nil 3066 } 3067 3068 // Rebalance with left sib 3069 if !rightCanLend { 3070 3071 err := leftSib.LendToRight(child) 3072 if err != nil { 3073 // Don't need to wrap error as external error because err is already categorized by MapSlab.LendToRight(). 3074 return err 3075 } 3076 3077 m.childrenHeaders[childHeaderIndex-1] = leftSib.Header() 3078 m.childrenHeaders[childHeaderIndex] = child.Header() 3079 3080 // Store modified slabs 3081 err = storage.Store(leftSib.ID(), leftSib) 3082 if err != nil { 3083 // Wrap err as external error (if needed) because err is returned by SlabStorage interface. 3084 return wrapErrorfAsExternalErrorIfNeeded(err, fmt.Sprintf("failed to store slab %s", leftSib.ID())) 3085 } 3086 3087 err = storage.Store(child.ID(), child) 3088 if err != nil { 3089 // Wrap err as external error (if needed) because err is returned by SlabStorage interface. 3090 return wrapErrorfAsExternalErrorIfNeeded(err, fmt.Sprintf("failed to store slab %s", child.ID())) 3091 } 3092 3093 err = storage.Store(m.header.id, m) 3094 if err != nil { 3095 // Wrap err as external error (if needed) because err is returned by SlabStorage interface. 3096 return wrapErrorfAsExternalErrorIfNeeded(err, fmt.Sprintf("failed to store slab %s", m.header.id)) 3097 } 3098 return nil 3099 } 3100 3101 // Rebalance with bigger sib 3102 if leftSib.ByteSize() > rightSib.ByteSize() { 3103 3104 err := leftSib.LendToRight(child) 3105 if err != nil { 3106 // Don't need to wrap error as external error because err is already categorized by MapSlab.LendToRight(). 3107 return err 3108 } 3109 3110 m.childrenHeaders[childHeaderIndex-1] = leftSib.Header() 3111 m.childrenHeaders[childHeaderIndex] = child.Header() 3112 3113 // Store modified slabs 3114 err = storage.Store(leftSib.ID(), leftSib) 3115 if err != nil { 3116 // Wrap err as external error (if needed) because err is returned by SlabStorage interface. 3117 return wrapErrorfAsExternalErrorIfNeeded(err, fmt.Sprintf("failed to store slab %s", leftSib.ID())) 3118 } 3119 3120 err = storage.Store(child.ID(), child) 3121 if err != nil { 3122 // Wrap err as external error (if needed) because err is returned by SlabStorage interface. 3123 return wrapErrorfAsExternalErrorIfNeeded(err, fmt.Sprintf("failed to store slab %s", child.ID())) 3124 } 3125 3126 err = storage.Store(m.header.id, m) 3127 if err != nil { 3128 // Wrap err as external error (if needed) because err is returned by SlabStorage interface. 3129 return wrapErrorfAsExternalErrorIfNeeded(err, fmt.Sprintf("failed to store slab %s", m.header.id)) 3130 } 3131 return nil 3132 } else { 3133 // leftSib.ByteSize() <= rightSib.ByteSize 3134 3135 err := child.BorrowFromRight(rightSib) 3136 if err != nil { 3137 // Don't need to wrap error as external error because err is already categorized by MapSlab.BorrowFromRight(). 3138 return err 3139 } 3140 3141 m.childrenHeaders[childHeaderIndex] = child.Header() 3142 m.childrenHeaders[childHeaderIndex+1] = rightSib.Header() 3143 3144 // This is needed when child is at index 0 and it is empty. 3145 if childHeaderIndex == 0 { 3146 m.header.firstKey = child.Header().firstKey 3147 } 3148 3149 // Store modified slabs 3150 err = storage.Store(child.ID(), child) 3151 if err != nil { 3152 // Wrap err as external error (if needed) because err is returned by SlabStorage interface. 3153 return wrapErrorfAsExternalErrorIfNeeded(err, fmt.Sprintf("failed to store slab %s", child.ID())) 3154 } 3155 3156 err = storage.Store(rightSib.ID(), rightSib) 3157 if err != nil { 3158 // Wrap err as external error (if needed) because err is returned by SlabStorage interface. 3159 return wrapErrorfAsExternalErrorIfNeeded(err, fmt.Sprintf("failed to store slab %s", rightSib.ID())) 3160 } 3161 3162 err = storage.Store(m.header.id, m) 3163 if err != nil { 3164 // Wrap err as external error (if needed) because err is returned by SlabStorage interface. 3165 return wrapErrorfAsExternalErrorIfNeeded(err, fmt.Sprintf("failed to store slab %s", m.header.id)) 3166 } 3167 return nil 3168 } 3169 } 3170 3171 // Child can't rebalance with any sibling. It must merge with one sibling. 3172 3173 if leftSib == nil { 3174 3175 // Merge with right 3176 err := child.Merge(rightSib) 3177 if err != nil { 3178 // Don't need to wrap error as external error because err is already categorized by MapSlab.Merge(). 3179 return err 3180 } 3181 3182 m.childrenHeaders[childHeaderIndex] = child.Header() 3183 3184 // Update MetaDataSlab's childrenHeaders 3185 copy(m.childrenHeaders[childHeaderIndex+1:], m.childrenHeaders[childHeaderIndex+2:]) 3186 m.childrenHeaders = m.childrenHeaders[:len(m.childrenHeaders)-1] 3187 3188 m.header.size -= mapSlabHeaderSize 3189 3190 // This is needed when child is at index 0 and it is empty. 3191 if childHeaderIndex == 0 { 3192 m.header.firstKey = child.Header().firstKey 3193 } 3194 3195 // Store modified slabs in storage 3196 err = storage.Store(child.ID(), child) 3197 if err != nil { 3198 // Wrap err as external error (if needed) because err is returned by SlabStorage interface. 3199 return wrapErrorfAsExternalErrorIfNeeded(err, fmt.Sprintf("failed to store slab %s", child.ID())) 3200 } 3201 err = storage.Store(m.header.id, m) 3202 if err != nil { 3203 // Wrap err as external error (if needed) because err is returned by SlabStorage interface. 3204 return wrapErrorfAsExternalErrorIfNeeded(err, fmt.Sprintf("failed to store slab %s", m.header.id)) 3205 } 3206 3207 // Remove right sib from storage 3208 err = storage.Remove(rightSib.ID()) 3209 if err != nil { 3210 // Wrap err as external error (if needed) because err is returned by SlabStorage interface. 3211 return wrapErrorfAsExternalErrorIfNeeded(err, fmt.Sprintf("failed to remove slab %s", rightSib.ID())) 3212 } 3213 return nil 3214 } 3215 3216 if rightSib == nil { 3217 3218 // Merge with left 3219 err := leftSib.Merge(child) 3220 if err != nil { 3221 // Don't need to wrap error as external error because err is already categorized by MapSlab.Merge(). 3222 return err 3223 } 3224 3225 m.childrenHeaders[childHeaderIndex-1] = leftSib.Header() 3226 3227 // Update MetaDataSlab's childrenHeaders 3228 copy(m.childrenHeaders[childHeaderIndex:], m.childrenHeaders[childHeaderIndex+1:]) 3229 m.childrenHeaders = m.childrenHeaders[:len(m.childrenHeaders)-1] 3230 3231 m.header.size -= mapSlabHeaderSize 3232 3233 // Store modified slabs in storage 3234 err = storage.Store(leftSib.ID(), leftSib) 3235 if err != nil { 3236 // Wrap err as external error (if needed) because err is returned by SlabStorage interface. 3237 return wrapErrorfAsExternalErrorIfNeeded(err, fmt.Sprintf("failed to store slab %s", leftSib.ID())) 3238 } 3239 err = storage.Store(m.header.id, m) 3240 if err != nil { 3241 // Wrap err as external error (if needed) because err is returned by SlabStorage interface. 3242 return wrapErrorfAsExternalErrorIfNeeded(err, fmt.Sprintf("failed to store slab %s", m.header.id)) 3243 } 3244 3245 // Remove child from storage 3246 err = storage.Remove(child.ID()) 3247 if err != nil { 3248 // Wrap err as external error (if needed) because err is returned by SlabStorage interface. 3249 return wrapErrorfAsExternalErrorIfNeeded(err, fmt.Sprintf("failed to remove slab %s", child.ID())) 3250 } 3251 return nil 3252 } 3253 3254 // Merge with smaller sib 3255 if leftSib.ByteSize() < rightSib.ByteSize() { 3256 err := leftSib.Merge(child) 3257 if err != nil { 3258 // Don't need to wrap error as external error because err is already categorized by MapSlab.Merge(). 3259 return err 3260 } 3261 3262 m.childrenHeaders[childHeaderIndex-1] = leftSib.Header() 3263 3264 // Update MetaDataSlab's childrenHeaders 3265 copy(m.childrenHeaders[childHeaderIndex:], m.childrenHeaders[childHeaderIndex+1:]) 3266 m.childrenHeaders = m.childrenHeaders[:len(m.childrenHeaders)-1] 3267 3268 m.header.size -= mapSlabHeaderSize 3269 3270 // Store modified slabs in storage 3271 err = storage.Store(leftSib.ID(), leftSib) 3272 if err != nil { 3273 // Wrap err as external error (if needed) because err is returned by SlabStorage interface. 3274 return wrapErrorfAsExternalErrorIfNeeded(err, fmt.Sprintf("failed to store slab %s", leftSib.ID())) 3275 } 3276 err = storage.Store(m.header.id, m) 3277 if err != nil { 3278 // Wrap err as external error (if needed) because err is returned by SlabStorage interface. 3279 return wrapErrorfAsExternalErrorIfNeeded(err, fmt.Sprintf("failed to store slab %s", m.header.id)) 3280 } 3281 3282 // Remove child from storage 3283 err = storage.Remove(child.ID()) 3284 if err != nil { 3285 // Wrap err as external error (if needed) because err is returned by SlabStorage interface. 3286 return wrapErrorfAsExternalErrorIfNeeded(err, fmt.Sprintf("failed to remove slab %s", child.ID())) 3287 } 3288 return nil 3289 } else { 3290 // leftSib.ByteSize() > rightSib.ByteSize 3291 3292 err := child.Merge(rightSib) 3293 if err != nil { 3294 // Don't need to wrap error as external error because err is already categorized by MapSlab.Merge(). 3295 return err 3296 } 3297 3298 m.childrenHeaders[childHeaderIndex] = child.Header() 3299 3300 // Update MetaDataSlab's childrenHeaders 3301 copy(m.childrenHeaders[childHeaderIndex+1:], m.childrenHeaders[childHeaderIndex+2:]) 3302 m.childrenHeaders = m.childrenHeaders[:len(m.childrenHeaders)-1] 3303 3304 m.header.size -= mapSlabHeaderSize 3305 3306 // This is needed when child is at index 0 and it is empty. 3307 if childHeaderIndex == 0 { 3308 m.header.firstKey = child.Header().firstKey 3309 } 3310 3311 // Store modified slabs in storage 3312 err = storage.Store(child.ID(), child) 3313 if err != nil { 3314 // Wrap err as external error (if needed) because err is returned by SlabStorage interface. 3315 return wrapErrorfAsExternalErrorIfNeeded(err, fmt.Sprintf("failed to store slab %s", child.ID())) 3316 } 3317 err = storage.Store(m.header.id, m) 3318 if err != nil { 3319 // Wrap err as external error (if needed) because err is returned by SlabStorage interface. 3320 return wrapErrorfAsExternalErrorIfNeeded(err, fmt.Sprintf("failed to store slab %s", m.header.id)) 3321 } 3322 3323 // Remove rightSib from storage 3324 err = storage.Remove(rightSib.ID()) 3325 if err != nil { 3326 // Wrap err as external error (if needed) because err is returned by SlabStorage interface. 3327 return wrapErrorfAsExternalErrorIfNeeded(err, fmt.Sprintf("failed to remove slab %s", rightSib.ID())) 3328 } 3329 return nil 3330 } 3331 } 3332 3333 func (m *MapMetaDataSlab) Merge(slab Slab) error { 3334 rightSlab := slab.(*MapMetaDataSlab) 3335 3336 m.childrenHeaders = append(m.childrenHeaders, rightSlab.childrenHeaders...) 3337 m.header.size += rightSlab.header.size - mapMetaDataSlabPrefixSize 3338 3339 return nil 3340 } 3341 3342 func (m *MapMetaDataSlab) Split(storage SlabStorage) (Slab, Slab, error) { 3343 if len(m.childrenHeaders) < 2 { 3344 // Can't split meta slab with less than 2 headers 3345 return nil, nil, NewSlabSplitErrorf("MapMetaDataSlab (%s) has less than 2 child headers", m.header.id) 3346 } 3347 3348 leftChildrenCount := int(math.Ceil(float64(len(m.childrenHeaders)) / 2)) 3349 leftSize := leftChildrenCount * mapSlabHeaderSize 3350 3351 sID, err := storage.GenerateStorageID(m.ID().Address) 3352 if err != nil { 3353 // Wrap err as external error (if needed) because err is returned by SlabStorage interface. 3354 return nil, nil, wrapErrorfAsExternalErrorIfNeeded(err, fmt.Sprintf("failed to generate storage ID for address 0x%x", m.ID().Address)) 3355 } 3356 3357 // Construct right slab 3358 rightSlab := &MapMetaDataSlab{ 3359 header: MapSlabHeader{ 3360 id: sID, 3361 size: m.header.size - uint32(leftSize), 3362 firstKey: m.childrenHeaders[leftChildrenCount].firstKey, 3363 }, 3364 } 3365 3366 rightSlab.childrenHeaders = make([]MapSlabHeader, len(m.childrenHeaders)-leftChildrenCount) 3367 copy(rightSlab.childrenHeaders, m.childrenHeaders[leftChildrenCount:]) 3368 3369 // Modify left (original) slab 3370 m.childrenHeaders = m.childrenHeaders[:leftChildrenCount] 3371 m.header.size = mapMetaDataSlabPrefixSize + uint32(leftSize) 3372 3373 return m, rightSlab, nil 3374 } 3375 3376 func (m *MapMetaDataSlab) LendToRight(slab Slab) error { 3377 rightSlab := slab.(*MapMetaDataSlab) 3378 3379 childrenHeadersLen := len(m.childrenHeaders) + len(rightSlab.childrenHeaders) 3380 leftChildrenHeadersLen := childrenHeadersLen / 2 3381 rightChildrenHeadersLen := childrenHeadersLen - leftChildrenHeadersLen 3382 3383 // Update right slab childrenHeaders by prepending borrowed children headers 3384 rightChildrenHeaders := make([]MapSlabHeader, rightChildrenHeadersLen) 3385 n := copy(rightChildrenHeaders, m.childrenHeaders[leftChildrenHeadersLen:]) 3386 copy(rightChildrenHeaders[n:], rightSlab.childrenHeaders) 3387 rightSlab.childrenHeaders = rightChildrenHeaders 3388 3389 // Update right slab header 3390 rightSlab.header.size = mapMetaDataSlabPrefixSize + uint32(rightChildrenHeadersLen)*mapSlabHeaderSize 3391 rightSlab.header.firstKey = rightSlab.childrenHeaders[0].firstKey 3392 3393 // Update left slab (original) 3394 m.childrenHeaders = m.childrenHeaders[:leftChildrenHeadersLen] 3395 3396 m.header.size = mapMetaDataSlabPrefixSize + uint32(leftChildrenHeadersLen)*mapSlabHeaderSize 3397 3398 return nil 3399 } 3400 3401 func (m *MapMetaDataSlab) BorrowFromRight(slab Slab) error { 3402 3403 rightSlab := slab.(*MapMetaDataSlab) 3404 3405 childrenHeadersLen := len(m.childrenHeaders) + len(rightSlab.childrenHeaders) 3406 leftSlabHeaderLen := childrenHeadersLen / 2 3407 rightSlabHeaderLen := childrenHeadersLen - leftSlabHeaderLen 3408 3409 // Update left slab (original) 3410 m.childrenHeaders = append(m.childrenHeaders, rightSlab.childrenHeaders[:leftSlabHeaderLen-len(m.childrenHeaders)]...) 3411 3412 m.header.size = mapMetaDataSlabPrefixSize + uint32(leftSlabHeaderLen)*mapSlabHeaderSize 3413 3414 // Update right slab 3415 rightSlab.childrenHeaders = rightSlab.childrenHeaders[len(rightSlab.childrenHeaders)-rightSlabHeaderLen:] 3416 3417 rightSlab.header.size = mapMetaDataSlabPrefixSize + uint32(rightSlabHeaderLen)*mapSlabHeaderSize 3418 rightSlab.header.firstKey = rightSlab.childrenHeaders[0].firstKey 3419 3420 return nil 3421 } 3422 3423 func (m MapMetaDataSlab) IsFull() bool { 3424 return m.header.size > uint32(maxThreshold) 3425 } 3426 3427 func (m MapMetaDataSlab) IsUnderflow() (uint32, bool) { 3428 if uint32(minThreshold) > m.header.size { 3429 return uint32(minThreshold) - m.header.size, true 3430 } 3431 return 0, false 3432 } 3433 3434 func (m *MapMetaDataSlab) CanLendToLeft(size uint32) bool { 3435 n := uint32(math.Ceil(float64(size) / mapSlabHeaderSize)) 3436 return m.header.size-mapSlabHeaderSize*n > uint32(minThreshold) 3437 } 3438 3439 func (m *MapMetaDataSlab) CanLendToRight(size uint32) bool { 3440 n := uint32(math.Ceil(float64(size) / mapSlabHeaderSize)) 3441 return m.header.size-mapSlabHeaderSize*n > uint32(minThreshold) 3442 } 3443 3444 func (m MapMetaDataSlab) IsData() bool { 3445 return false 3446 } 3447 3448 func (m *MapMetaDataSlab) SetID(id StorageID) { 3449 m.header.id = id 3450 } 3451 3452 func (m *MapMetaDataSlab) Header() MapSlabHeader { 3453 return m.header 3454 } 3455 3456 func (m *MapMetaDataSlab) ByteSize() uint32 { 3457 return m.header.size 3458 } 3459 3460 func (m *MapMetaDataSlab) ID() StorageID { 3461 return m.header.id 3462 } 3463 3464 func (m *MapMetaDataSlab) ExtraData() *MapExtraData { 3465 return m.extraData 3466 } 3467 3468 func (m *MapMetaDataSlab) RemoveExtraData() *MapExtraData { 3469 extraData := m.extraData 3470 m.extraData = nil 3471 return extraData 3472 } 3473 3474 func (m *MapMetaDataSlab) SetExtraData(extraData *MapExtraData) { 3475 m.extraData = extraData 3476 } 3477 3478 func (m *MapMetaDataSlab) PopIterate(storage SlabStorage, fn MapPopIterationFunc) error { 3479 3480 // Iterate child slabs backwards 3481 for i := len(m.childrenHeaders) - 1; i >= 0; i-- { 3482 3483 childID := m.childrenHeaders[i].id 3484 3485 child, err := getMapSlab(storage, childID) 3486 if err != nil { 3487 // Don't need to wrap error as external error because err is already categorized by getMapSlab(). 3488 return err 3489 } 3490 3491 err = child.PopIterate(storage, fn) 3492 if err != nil { 3493 // Don't need to wrap error as external error because err is already categorized by MapSlab.PopIterate(). 3494 return err 3495 } 3496 3497 // Remove child slab 3498 err = storage.Remove(childID) 3499 if err != nil { 3500 // Wrap err as external error (if needed) because err is returned by SlabStorage interface. 3501 return wrapErrorfAsExternalErrorIfNeeded(err, fmt.Sprintf("failed to remove slab %s", childID)) 3502 } 3503 } 3504 3505 // All child slabs are removed. 3506 3507 // Reset meta data slab 3508 m.childrenHeaders = nil 3509 m.header.firstKey = 0 3510 m.header.size = mapMetaDataSlabPrefixSize 3511 3512 return nil 3513 } 3514 3515 func (m *MapMetaDataSlab) String() string { 3516 var elemsStr []string 3517 for _, h := range m.childrenHeaders { 3518 elemsStr = append(elemsStr, fmt.Sprintf("{id:%s size:%d firstKey:%d}", h.id, h.size, h.firstKey)) 3519 } 3520 3521 return fmt.Sprintf("MapMetaDataSlab id:%s size:%d firstKey:%d children: [%s]", 3522 m.header.id, 3523 m.header.size, 3524 m.header.firstKey, 3525 strings.Join(elemsStr, " "), 3526 ) 3527 } 3528 3529 func NewMap(storage SlabStorage, address Address, digestBuilder DigesterBuilder, typeInfo TypeInfo) (*OrderedMap, error) { 3530 3531 // Create root storage id 3532 sID, err := storage.GenerateStorageID(address) 3533 if err != nil { 3534 // Wrap err as external error (if needed) because err is returned by SlabStorage interface. 3535 return nil, wrapErrorfAsExternalErrorIfNeeded(err, fmt.Sprintf("failed to generate storage ID for address 0x%x", address)) 3536 } 3537 3538 // Create seed for non-crypto hash algos (CircleHash64, SipHash) to use. 3539 // Ideally, seed should be a nondeterministic 128-bit secret because 3540 // these hashes rely on its key being secret for its security. Since 3541 // we handle collisions and based on other factors such as storage space, 3542 // the team decided we can use a 64-bit non-secret key instead of 3543 // a 128-bit secret key. And for performance reasons, we first use 3544 // noncrypto hash algos and fall back to crypto algo after collisions. 3545 // This is for creating the seed, so the seed used here is OK to be 0. 3546 // LittleEndian is needed for compatibility (same digest from []byte and 3547 // two uint64). 3548 a := binary.LittleEndian.Uint64(sID.Address[:]) 3549 b := binary.LittleEndian.Uint64(sID.Index[:]) 3550 k0 := circlehash.Hash64Uint64x2(a, b, uint64(0)) 3551 3552 // To save storage space, only store 64-bits of the seed. 3553 // Use a 64-bit const for the unstored half to create 128-bit seed. 3554 k1 := typicalRandomConstant 3555 3556 digestBuilder.SetSeed(k0, k1) 3557 3558 // Create extra data with type info and seed 3559 extraData := &MapExtraData{TypeInfo: typeInfo, Seed: k0} 3560 3561 root := &MapDataSlab{ 3562 header: MapSlabHeader{ 3563 id: sID, 3564 size: mapRootDataSlabPrefixSize + hkeyElementsPrefixSize, 3565 }, 3566 elements: newHkeyElements(0), 3567 extraData: extraData, 3568 } 3569 3570 err = storage.Store(root.header.id, root) 3571 if err != nil { 3572 // Wrap err as external error (if needed) because err is returned by SlabStorage interface. 3573 return nil, wrapErrorfAsExternalErrorIfNeeded(err, fmt.Sprintf("failed to store slab %s", root.header.id)) 3574 } 3575 3576 return &OrderedMap{ 3577 Storage: storage, 3578 root: root, 3579 digesterBuilder: digestBuilder, 3580 }, nil 3581 } 3582 3583 func NewMapWithRootID(storage SlabStorage, rootID StorageID, digestBuilder DigesterBuilder) (*OrderedMap, error) { 3584 if rootID == StorageIDUndefined { 3585 return nil, NewStorageIDErrorf("cannot create OrderedMap from undefined storage id") 3586 } 3587 3588 root, err := getMapSlab(storage, rootID) 3589 if err != nil { 3590 // Don't need to wrap error as external error because err is already categorized by getMapSlab(). 3591 return nil, err 3592 } 3593 3594 extraData := root.ExtraData() 3595 if extraData == nil { 3596 return nil, NewNotValueError(rootID) 3597 } 3598 3599 digestBuilder.SetSeed(extraData.Seed, typicalRandomConstant) 3600 3601 return &OrderedMap{ 3602 Storage: storage, 3603 root: root, 3604 digesterBuilder: digestBuilder, 3605 }, nil 3606 } 3607 3608 func (m *OrderedMap) Has(comparator ValueComparator, hip HashInputProvider, key Value) (bool, error) { 3609 _, err := m.Get(comparator, hip, key) 3610 if err != nil { 3611 var knf *KeyNotFoundError 3612 if errors.As(err, &knf) { 3613 return false, nil 3614 } 3615 // Don't need to wrap error as external error because err is already categorized by OrderedMap.Get(). 3616 return false, err 3617 } 3618 return true, nil 3619 } 3620 3621 func (m *OrderedMap) Get(comparator ValueComparator, hip HashInputProvider, key Value) (Storable, error) { 3622 3623 keyDigest, err := m.digesterBuilder.Digest(hip, key) 3624 if err != nil { 3625 // Wrap err as external error (if needed) because err is returned by DigesterBuilder interface. 3626 return nil, wrapErrorfAsExternalErrorIfNeeded(err, "failed to create map key digester") 3627 } 3628 defer putDigester(keyDigest) 3629 3630 level := uint(0) 3631 3632 hkey, err := keyDigest.Digest(level) 3633 if err != nil { 3634 // Wrap err as external error (if needed) because err is returned by Digesert interface. 3635 return nil, wrapErrorfAsExternalErrorIfNeeded(err, fmt.Sprintf("failed to get map key digest at level %d", level)) 3636 } 3637 3638 // Don't need to wrap error as external error because err is already categorized by MapSlab.Get(). 3639 return m.root.Get(m.Storage, keyDigest, level, hkey, comparator, key) 3640 } 3641 3642 func (m *OrderedMap) Set(comparator ValueComparator, hip HashInputProvider, key Value, value Value) (Storable, error) { 3643 3644 keyDigest, err := m.digesterBuilder.Digest(hip, key) 3645 if err != nil { 3646 // Wrap err as external error (if needed) because err is returned by DigesterBuilder interface. 3647 return nil, wrapErrorfAsExternalErrorIfNeeded(err, "failed to create map key digester") 3648 } 3649 defer putDigester(keyDigest) 3650 3651 level := uint(0) 3652 3653 hkey, err := keyDigest.Digest(level) 3654 if err != nil { 3655 // Wrap err as external error (if needed) because err is returned by Digesert interface. 3656 return nil, wrapErrorfAsExternalErrorIfNeeded(err, fmt.Sprintf("failed to get map key digest at level %d", level)) 3657 } 3658 3659 existingValue, err := m.root.Set(m.Storage, m.digesterBuilder, keyDigest, level, hkey, comparator, hip, key, value) 3660 if err != nil { 3661 // Don't need to wrap error as external error because err is already categorized by MapSlab.Set(). 3662 return nil, err 3663 } 3664 3665 if existingValue == nil { 3666 m.root.ExtraData().incrementCount() 3667 } 3668 3669 if !m.root.IsData() { 3670 // Set root to its child slab if root has one child slab. 3671 root := m.root.(*MapMetaDataSlab) 3672 if len(root.childrenHeaders) == 1 { 3673 err := m.promoteChildAsNewRoot(root.childrenHeaders[0].id) 3674 if err != nil { 3675 // Don't need to wrap error as external error because err is already categorized by OrderedMap.promoteChildAsNewRoot(). 3676 return nil, err 3677 } 3678 return existingValue, nil 3679 } 3680 } 3681 3682 if m.root.IsFull() { 3683 err := m.splitRoot() 3684 if err != nil { 3685 // Don't need to wrap error as external error because err is already categorized by OrderedMap.splitRoot(). 3686 return nil, err 3687 } 3688 } 3689 3690 return existingValue, nil 3691 } 3692 3693 func (m *OrderedMap) Remove(comparator ValueComparator, hip HashInputProvider, key Value) (Storable, Storable, error) { 3694 3695 keyDigest, err := m.digesterBuilder.Digest(hip, key) 3696 if err != nil { 3697 // Wrap err as external error (if needed) because err is returned by DigesterBuilder interface. 3698 return nil, nil, wrapErrorfAsExternalErrorIfNeeded(err, "failed to create map key digester") 3699 } 3700 defer putDigester(keyDigest) 3701 3702 level := uint(0) 3703 3704 hkey, err := keyDigest.Digest(level) 3705 if err != nil { 3706 // Wrap err as external error (if needed) because err is returned by Digesert interface. 3707 return nil, nil, wrapErrorfAsExternalErrorIfNeeded(err, fmt.Sprintf("failed to create map key digest at level %d", level)) 3708 } 3709 3710 k, v, err := m.root.Remove(m.Storage, keyDigest, level, hkey, comparator, key) 3711 if err != nil { 3712 // Don't need to wrap error as external error because err is already categorized by MapSlab.Remove(). 3713 return nil, nil, err 3714 } 3715 3716 m.root.ExtraData().decrementCount() 3717 3718 if !m.root.IsData() { 3719 // Set root to its child slab if root has one child slab. 3720 root := m.root.(*MapMetaDataSlab) 3721 if len(root.childrenHeaders) == 1 { 3722 err := m.promoteChildAsNewRoot(root.childrenHeaders[0].id) 3723 if err != nil { 3724 // Don't need to wrap error as external error because err is already categorized by OrderedMap.promoteChildAsNewRoot(). 3725 return nil, nil, err 3726 } 3727 return k, v, nil 3728 } 3729 } 3730 3731 if m.root.IsFull() { 3732 err := m.splitRoot() 3733 if err != nil { 3734 // Don't need to wrap error as external error because err is already categorized by OrderedMap.splitRoot(). 3735 return nil, nil, err 3736 } 3737 } 3738 3739 return k, v, nil 3740 } 3741 3742 func (m *OrderedMap) splitRoot() error { 3743 3744 if m.root.IsData() { 3745 // Adjust root data slab size before splitting 3746 dataSlab := m.root.(*MapDataSlab) 3747 dataSlab.header.size = dataSlab.header.size - mapRootDataSlabPrefixSize + mapDataSlabPrefixSize 3748 } 3749 3750 // Get old root's extra data and reset it to nil in old root 3751 extraData := m.root.RemoveExtraData() 3752 3753 // Save root node id 3754 rootID := m.root.ID() 3755 3756 // Assign a new storage id to old root before splitting it. 3757 sID, err := m.Storage.GenerateStorageID(m.Address()) 3758 if err != nil { 3759 // Wrap err as external error (if needed) because err is returned by SlabStorage interface. 3760 return wrapErrorfAsExternalErrorIfNeeded(err, fmt.Sprintf("failed to generate storage ID for address 0x%x", m.Address())) 3761 } 3762 3763 oldRoot := m.root 3764 oldRoot.SetID(sID) 3765 3766 // Split old root 3767 leftSlab, rightSlab, err := oldRoot.Split(m.Storage) 3768 if err != nil { 3769 // Don't need to wrap error as external error because err is already categorized by MapSlab.Split(). 3770 return err 3771 } 3772 3773 left := leftSlab.(MapSlab) 3774 right := rightSlab.(MapSlab) 3775 3776 // Create new MapMetaDataSlab with the old root's storage ID 3777 newRoot := &MapMetaDataSlab{ 3778 header: MapSlabHeader{ 3779 id: rootID, 3780 size: mapMetaDataSlabPrefixSize + mapSlabHeaderSize*2, 3781 firstKey: left.Header().firstKey, 3782 }, 3783 childrenHeaders: []MapSlabHeader{left.Header(), right.Header()}, 3784 extraData: extraData, 3785 } 3786 3787 m.root = newRoot 3788 3789 err = m.Storage.Store(left.ID(), left) 3790 if err != nil { 3791 // Wrap err as external error (if needed) because err is returned by SlabStorage interface. 3792 return wrapErrorfAsExternalErrorIfNeeded(err, fmt.Sprintf("failed to store slab %s", left.ID())) 3793 } 3794 err = m.Storage.Store(right.ID(), right) 3795 if err != nil { 3796 // Wrap err as external error (if needed) because err is returned by SlabStorage interface. 3797 return wrapErrorfAsExternalErrorIfNeeded(err, fmt.Sprintf("failed to store slab %s", right.ID())) 3798 } 3799 err = m.Storage.Store(m.root.ID(), m.root) 3800 if err != nil { 3801 // Wrap err as external error (if needed) because err is returned by SlabStorage interface. 3802 return wrapErrorfAsExternalErrorIfNeeded(err, fmt.Sprintf("failed to store slab %s", m.root.ID())) 3803 } 3804 return nil 3805 } 3806 3807 func (m *OrderedMap) promoteChildAsNewRoot(childID StorageID) error { 3808 3809 child, err := getMapSlab(m.Storage, childID) 3810 if err != nil { 3811 // Don't need to wrap error as external error because err is already categorized by getMapSlab(). 3812 return err 3813 } 3814 3815 if child.IsData() { 3816 // Adjust data slab size before promoting non-root data slab to root 3817 dataSlab := child.(*MapDataSlab) 3818 dataSlab.header.size = dataSlab.header.size - mapDataSlabPrefixSize + mapRootDataSlabPrefixSize 3819 } 3820 3821 extraData := m.root.RemoveExtraData() 3822 3823 rootID := m.root.ID() 3824 3825 m.root = child 3826 3827 m.root.SetID(rootID) 3828 3829 m.root.SetExtraData(extraData) 3830 3831 err = m.Storage.Store(rootID, m.root) 3832 if err != nil { 3833 // Wrap err as external error (if needed) because err is returned by SlabStorage interface. 3834 return wrapErrorfAsExternalErrorIfNeeded(err, fmt.Sprintf("failed to store slab %s", rootID)) 3835 } 3836 3837 err = m.Storage.Remove(childID) 3838 if err != nil { 3839 // Wrap err as external error (if needed) because err is returned by SlabStorage interface. 3840 return wrapErrorfAsExternalErrorIfNeeded(err, fmt.Sprintf("failed to remove slab %s", childID)) 3841 } 3842 return nil 3843 } 3844 3845 func (m *OrderedMap) StorageID() StorageID { 3846 return m.root.Header().id 3847 } 3848 3849 func (m *OrderedMap) StoredValue(_ SlabStorage) (Value, error) { 3850 return m, nil 3851 } 3852 3853 func (m *OrderedMap) Storable(_ SlabStorage, _ Address, _ uint64) (Storable, error) { 3854 return StorageIDStorable(m.StorageID()), nil 3855 } 3856 3857 func (m *OrderedMap) Count() uint64 { 3858 return m.root.ExtraData().Count 3859 } 3860 3861 func (m *OrderedMap) Address() Address { 3862 return m.root.ID().Address 3863 } 3864 3865 func (m *OrderedMap) Type() TypeInfo { 3866 if extraData := m.root.ExtraData(); extraData != nil { 3867 return extraData.TypeInfo 3868 } 3869 return nil 3870 } 3871 3872 func (m *OrderedMap) String() string { 3873 iterator, err := m.Iterator() 3874 if err != nil { 3875 return err.Error() 3876 } 3877 3878 var elemsStr []string 3879 for { 3880 k, v, err := iterator.Next() 3881 if err != nil { 3882 return err.Error() 3883 } 3884 if k == nil { 3885 break 3886 } 3887 elemsStr = append(elemsStr, fmt.Sprintf("%s:%s", k, v)) 3888 } 3889 3890 return fmt.Sprintf("[%s]", strings.Join(elemsStr, " ")) 3891 } 3892 3893 func getMapSlab(storage SlabStorage, id StorageID) (MapSlab, error) { 3894 slab, found, err := storage.Retrieve(id) 3895 if err != nil { 3896 // Wrap err as external error (if needed) because err is returned by SlabStorage interface. 3897 return nil, wrapErrorfAsExternalErrorIfNeeded(err, fmt.Sprintf("failed to retrieve slab %s", id)) 3898 } 3899 if !found { 3900 return nil, NewSlabNotFoundErrorf(id, "map slab not found") 3901 } 3902 mapSlab, ok := slab.(MapSlab) 3903 if !ok { 3904 return nil, NewSlabDataErrorf("slab %s isn't MapSlab", id) 3905 } 3906 return mapSlab, nil 3907 } 3908 3909 func firstMapDataSlab(storage SlabStorage, slab MapSlab) (MapSlab, error) { 3910 if slab.IsData() { 3911 return slab, nil 3912 } 3913 meta := slab.(*MapMetaDataSlab) 3914 firstChildID := meta.childrenHeaders[0].id 3915 firstChild, err := getMapSlab(storage, firstChildID) 3916 if err != nil { 3917 // Don't need to wrap error as external error because err is already categorized by getMapSlab(). 3918 return nil, err 3919 } 3920 // Don't need to wrap error as external error because err is already categorized by firstMapDataSlab(). 3921 return firstMapDataSlab(storage, firstChild) 3922 } 3923 3924 func (m *MapExtraData) incrementCount() { 3925 m.Count++ 3926 } 3927 3928 func (m *MapExtraData) decrementCount() { 3929 m.Count-- 3930 } 3931 3932 type MapElementIterator struct { 3933 storage SlabStorage 3934 elements elements 3935 index int 3936 nestedIterator *MapElementIterator 3937 } 3938 3939 func (i *MapElementIterator) Next() (key MapKey, value MapValue, err error) { 3940 3941 if i.nestedIterator != nil { 3942 key, value, err = i.nestedIterator.Next() 3943 if err != nil { 3944 // Don't need to wrap error as external error because err is already categorized by MapElementIterator.Next(). 3945 return nil, nil, err 3946 } 3947 if key != nil { 3948 return key, value, nil 3949 } 3950 i.nestedIterator = nil 3951 } 3952 3953 if i.index >= int(i.elements.Count()) { 3954 return nil, nil, nil 3955 } 3956 3957 e, err := i.elements.Element(i.index) 3958 if err != nil { 3959 // Don't need to wrap error as external error because err is already categorized by elements.Element(). 3960 return nil, nil, err 3961 } 3962 3963 switch elm := e.(type) { 3964 case *singleElement: 3965 i.index++ 3966 return elm.key, elm.value, nil 3967 3968 case elementGroup: 3969 elems, err := elm.Elements(i.storage) 3970 if err != nil { 3971 // Don't need to wrap error as external error because err is already categorized by elementGroup.Elements(). 3972 return nil, nil, err 3973 } 3974 3975 i.nestedIterator = &MapElementIterator{ 3976 storage: i.storage, 3977 elements: elems, 3978 } 3979 3980 i.index++ 3981 // Don't need to wrap error as external error because err is already categorized by MapElementIterator.Next(). 3982 return i.nestedIterator.Next() 3983 3984 default: 3985 return nil, nil, NewSlabDataError(fmt.Errorf("unexpected element type %T during map iteration", e)) 3986 } 3987 } 3988 3989 type MapEntryIterationFunc func(Value, Value) (resume bool, err error) 3990 type MapElementIterationFunc func(Value) (resume bool, err error) 3991 3992 type MapIterator struct { 3993 storage SlabStorage 3994 id StorageID 3995 elemIterator *MapElementIterator 3996 } 3997 3998 func (i *MapIterator) Next() (key Value, value Value, err error) { 3999 if i.elemIterator == nil { 4000 if i.id == StorageIDUndefined { 4001 return nil, nil, nil 4002 } 4003 4004 err = i.advance() 4005 if err != nil { 4006 // Don't need to wrap error as external error because err is already categorized by MapIterator.advance(). 4007 return nil, nil, err 4008 } 4009 } 4010 4011 var ks, vs Storable 4012 ks, vs, err = i.elemIterator.Next() 4013 if err != nil { 4014 // Don't need to wrap error as external error because err is already categorized by MapElementIterator.Next(). 4015 return nil, nil, err 4016 } 4017 if ks != nil { 4018 key, err = ks.StoredValue(i.storage) 4019 if err != nil { 4020 // Wrap err as external error (if needed) because err is returned by Storable interface. 4021 return nil, nil, wrapErrorfAsExternalErrorIfNeeded(err, "failed to get map key's stored value") 4022 } 4023 4024 value, err = vs.StoredValue(i.storage) 4025 if err != nil { 4026 // Wrap err as external error (if needed) because err is returned by Storable interface. 4027 return nil, nil, wrapErrorfAsExternalErrorIfNeeded(err, "failed to get map value's stored value") 4028 } 4029 4030 return key, value, nil 4031 } 4032 4033 i.elemIterator = nil 4034 4035 // Don't need to wrap error as external error because err is already categorized by MapIterator.Next(). 4036 return i.Next() 4037 } 4038 4039 func (i *MapIterator) NextKey() (key Value, err error) { 4040 if i.elemIterator == nil { 4041 if i.id == StorageIDUndefined { 4042 return nil, nil 4043 } 4044 4045 err = i.advance() 4046 if err != nil { 4047 // Don't need to wrap error as external error because err is already categorized by MapIterator.advance(). 4048 return nil, err 4049 } 4050 } 4051 4052 var ks Storable 4053 ks, _, err = i.elemIterator.Next() 4054 if err != nil { 4055 // Don't need to wrap error as external error because err is already categorized by MapElementIterator.Next(). 4056 return nil, err 4057 } 4058 if ks != nil { 4059 key, err = ks.StoredValue(i.storage) 4060 if err != nil { 4061 // Wrap err as external error (if needed) because err is returned by Storable interface. 4062 return nil, wrapErrorfAsExternalErrorIfNeeded(err, "failed to get map key's stored value") 4063 } 4064 4065 return key, nil 4066 } 4067 4068 i.elemIterator = nil 4069 4070 // Don't need to wrap error as external error because err is already categorized by MapIterator.NextKey(). 4071 return i.NextKey() 4072 } 4073 4074 func (i *MapIterator) NextValue() (value Value, err error) { 4075 if i.elemIterator == nil { 4076 if i.id == StorageIDUndefined { 4077 return nil, nil 4078 } 4079 4080 err = i.advance() 4081 if err != nil { 4082 // Don't need to wrap error as external error because err is already categorized by MapIterator.advance(). 4083 return nil, err 4084 } 4085 } 4086 4087 var vs Storable 4088 _, vs, err = i.elemIterator.Next() 4089 if err != nil { 4090 // Don't need to wrap error as external error because err is already categorized by MapElementIterator.Next(). 4091 return nil, err 4092 } 4093 if vs != nil { 4094 value, err = vs.StoredValue(i.storage) 4095 if err != nil { 4096 // Wrap err as external error (if needed) because err is returned by Storable interface. 4097 return nil, wrapErrorfAsExternalErrorIfNeeded(err, "failed to get map value's stored value") 4098 } 4099 4100 return value, nil 4101 } 4102 4103 i.elemIterator = nil 4104 4105 // Don't need to wrap error as external error because err is already categorized by MapIterator.NextValue(). 4106 return i.NextValue() 4107 } 4108 4109 func (i *MapIterator) advance() error { 4110 slab, found, err := i.storage.Retrieve(i.id) 4111 if err != nil { 4112 // Wrap err as external error (if needed) because err is returned by SlabStorage interface. 4113 return wrapErrorfAsExternalErrorIfNeeded(err, fmt.Sprintf("failed to retrieve slab %s", i.id)) 4114 } 4115 if !found { 4116 return NewSlabNotFoundErrorf(i.id, "slab not found during map iteration") 4117 } 4118 4119 dataSlab, ok := slab.(*MapDataSlab) 4120 if !ok { 4121 return NewSlabDataErrorf("slab %s isn't MapDataSlab", i.id) 4122 } 4123 4124 i.id = dataSlab.next 4125 4126 i.elemIterator = &MapElementIterator{ 4127 storage: i.storage, 4128 elements: dataSlab.elements, 4129 } 4130 4131 return nil 4132 } 4133 4134 func (m *OrderedMap) Iterator() (*MapIterator, error) { 4135 slab, err := firstMapDataSlab(m.Storage, m.root) 4136 if err != nil { 4137 // Don't need to wrap error as external error because err is already categorized by firstMapDataSlab(). 4138 return nil, err 4139 } 4140 4141 dataSlab := slab.(*MapDataSlab) 4142 4143 return &MapIterator{ 4144 storage: m.Storage, 4145 id: dataSlab.next, 4146 elemIterator: &MapElementIterator{ 4147 storage: m.Storage, 4148 elements: dataSlab.elements, 4149 }, 4150 }, nil 4151 } 4152 4153 func (m *OrderedMap) Iterate(fn MapEntryIterationFunc) error { 4154 4155 iterator, err := m.Iterator() 4156 if err != nil { 4157 // Don't need to wrap error as external error because err is already categorized by OrderedMap.Iterator(). 4158 return err 4159 } 4160 4161 var key, value Value 4162 for { 4163 key, value, err = iterator.Next() 4164 if err != nil { 4165 // Don't need to wrap error as external error because err is already categorized by MapIterator.Next(). 4166 return err 4167 } 4168 if key == nil { 4169 return nil 4170 } 4171 resume, err := fn(key, value) 4172 if err != nil { 4173 // Wrap err as external error (if needed) because err is returned by MapEntryIterationFunc callback. 4174 return wrapErrorAsExternalErrorIfNeeded(err) 4175 } 4176 if !resume { 4177 return nil 4178 } 4179 } 4180 } 4181 4182 func (m *OrderedMap) IterateKeys(fn MapElementIterationFunc) error { 4183 4184 iterator, err := m.Iterator() 4185 if err != nil { 4186 // Don't need to wrap error as external error because err is already categorized by OrderedMap.Iterator(). 4187 return err 4188 } 4189 4190 var key Value 4191 for { 4192 key, err = iterator.NextKey() 4193 if err != nil { 4194 // Don't need to wrap error as external error because err is already categorized by MapIterator.NextKey(). 4195 return err 4196 } 4197 if key == nil { 4198 return nil 4199 } 4200 resume, err := fn(key) 4201 if err != nil { 4202 // Wrap err as external error (if needed) because err is returned by MapElementIterationFunc callback. 4203 return wrapErrorAsExternalErrorIfNeeded(err) 4204 } 4205 if !resume { 4206 return nil 4207 } 4208 } 4209 } 4210 4211 func (m *OrderedMap) IterateValues(fn MapElementIterationFunc) error { 4212 4213 iterator, err := m.Iterator() 4214 if err != nil { 4215 // Don't need to wrap error as external error because err is already categorized by OrderedMap.Iterator(). 4216 return err 4217 } 4218 4219 var value Value 4220 for { 4221 value, err = iterator.NextValue() 4222 if err != nil { 4223 // Don't need to wrap error as external error because err is already categorized by MapIterator.NextValue(). 4224 return err 4225 } 4226 if value == nil { 4227 return nil 4228 } 4229 resume, err := fn(value) 4230 if err != nil { 4231 // Wrap err as external error (if needed) because err is returned by MapElementIterationFunc callback. 4232 return wrapErrorAsExternalErrorIfNeeded(err) 4233 } 4234 if !resume { 4235 return nil 4236 } 4237 } 4238 } 4239 4240 type MapPopIterationFunc func(Storable, Storable) 4241 4242 // PopIterate iterates and removes elements backward. 4243 // Each element is passed to MapPopIterationFunc callback before removal. 4244 func (m *OrderedMap) PopIterate(fn MapPopIterationFunc) error { 4245 4246 err := m.root.PopIterate(m.Storage, fn) 4247 if err != nil { 4248 // Don't need to wrap error as external error because err is already categorized by MapSlab.PopIterate(). 4249 return err 4250 } 4251 4252 rootID := m.root.ID() 4253 4254 // Set map count to 0 in extraData 4255 extraData := m.root.ExtraData() 4256 extraData.Count = 0 4257 4258 // Set root to empty data slab 4259 m.root = &MapDataSlab{ 4260 header: MapSlabHeader{ 4261 id: rootID, 4262 size: mapRootDataSlabPrefixSize + hkeyElementsPrefixSize, 4263 }, 4264 elements: newHkeyElements(0), 4265 extraData: extraData, 4266 } 4267 4268 // Save root slab 4269 err = m.Storage.Store(m.root.ID(), m.root) 4270 if err != nil { 4271 // Wrap err as external error (if needed) because err is returned by SlabStorage interface. 4272 return wrapErrorfAsExternalErrorIfNeeded(err, fmt.Sprintf("failed to store slab %s", m.root.ID())) 4273 } 4274 return nil 4275 } 4276 4277 func (m *OrderedMap) Seed() uint64 { 4278 return m.root.ExtraData().Seed 4279 } 4280 4281 type MapElementProvider func() (Value, Value, error) 4282 4283 // NewMapFromBatchData returns a new map with elements provided by fn callback. 4284 // Provided seed must be the same seed used to create the original map. 4285 // And callback function must return elements in the same order as the original map. 4286 // New map uses and stores the same seed as the original map. 4287 // This function should only be used for copying a map. 4288 func NewMapFromBatchData( 4289 storage SlabStorage, 4290 address Address, 4291 digesterBuilder DigesterBuilder, 4292 typeInfo TypeInfo, 4293 comparator ValueComparator, 4294 hip HashInputProvider, 4295 seed uint64, 4296 fn MapElementProvider, 4297 ) ( 4298 *OrderedMap, 4299 error, 4300 ) { 4301 4302 const defaultElementCountInSlab = 32 4303 4304 if seed == 0 { 4305 return nil, NewHashSeedUninitializedError() 4306 } 4307 4308 // Seed digester 4309 digesterBuilder.SetSeed(seed, typicalRandomConstant) 4310 4311 var slabs []MapSlab 4312 4313 id, err := storage.GenerateStorageID(address) 4314 if err != nil { 4315 // Wrap err as external error (if needed) because err is returned by SlabStorage interface. 4316 return nil, wrapErrorfAsExternalErrorIfNeeded(err, fmt.Sprintf("failed to generate storage ID for address 0x%x", address)) 4317 } 4318 4319 elements := &hkeyElements{ 4320 level: 0, 4321 size: hkeyElementsPrefixSize, 4322 hkeys: make([]Digest, 0, defaultElementCountInSlab), 4323 elems: make([]element, 0, defaultElementCountInSlab), 4324 } 4325 4326 count := uint64(0) 4327 4328 var prevHkey Digest 4329 4330 // Appends all elements 4331 for { 4332 key, value, err := fn() 4333 if err != nil { 4334 // Wrap err as external error (if needed) because err is returned by MapElementProvider callback. 4335 return nil, wrapErrorAsExternalErrorIfNeeded(err) 4336 } 4337 if key == nil { 4338 break 4339 } 4340 4341 digester, err := digesterBuilder.Digest(hip, key) 4342 if err != nil { 4343 // Wrap err as external error (if needed) because err is returned by DigesterBuilder interface. 4344 return nil, wrapErrorfAsExternalErrorIfNeeded(err, "failed to create map key digester") 4345 } 4346 4347 hkey, err := digester.Digest(0) 4348 if err != nil { 4349 // Wrap err as external error (if needed) because err is returned by Digester interface. 4350 return nil, wrapErrorfAsExternalErrorIfNeeded(err, "failed to generate map key digest for level 0") 4351 } 4352 4353 if hkey < prevHkey { 4354 // a valid map will always have sorted digests 4355 return nil, NewHashError(fmt.Errorf("digest isn't sorted (found %d before %d)", prevHkey, hkey)) 4356 } 4357 4358 if hkey == prevHkey && count > 0 { 4359 // found collision 4360 4361 lastElementIndex := len(elements.elems) - 1 4362 4363 prevElem := elements.elems[lastElementIndex] 4364 prevElemSize := prevElem.Size() 4365 4366 elem, existingValue, err := prevElem.Set(storage, address, digesterBuilder, digester, 0, hkey, comparator, hip, key, value) 4367 if err != nil { 4368 // Don't need to wrap error as external error because err is already categorized by element.Set(). 4369 return nil, err 4370 } 4371 if existingValue != nil { 4372 return nil, NewDuplicateKeyError(key) 4373 } 4374 4375 elements.elems[lastElementIndex] = elem 4376 elements.size += elem.Size() - prevElemSize 4377 4378 putDigester(digester) 4379 4380 count++ 4381 4382 continue 4383 } 4384 4385 // no collision 4386 4387 putDigester(digester) 4388 4389 elem, err := newSingleElement(storage, address, key, value) 4390 if err != nil { 4391 // Don't need to wrap error as external error because err is already categorized by newSingleElememt(). 4392 return nil, err 4393 } 4394 4395 // Finalize data slab 4396 currentSlabSize := mapDataSlabPrefixSize + elements.Size() 4397 newElementSize := digestSize + elem.Size() 4398 if currentSlabSize >= uint32(targetThreshold) || 4399 currentSlabSize+newElementSize > uint32(maxThreshold) { 4400 4401 // Generate storge id for next data slab 4402 nextID, err := storage.GenerateStorageID(address) 4403 if err != nil { 4404 // Wrap err as external error (if needed) because err is returned by SlabStorage interface. 4405 return nil, wrapErrorfAsExternalErrorIfNeeded(err, fmt.Sprintf("failed to generate storage ID for address 0x%x", address)) 4406 } 4407 4408 // Create data slab 4409 dataSlab := &MapDataSlab{ 4410 header: MapSlabHeader{ 4411 id: id, 4412 size: mapDataSlabPrefixSize + elements.Size(), 4413 firstKey: elements.firstKey(), 4414 }, 4415 elements: elements, 4416 next: nextID, 4417 } 4418 4419 // Append data slab to dataSlabs 4420 slabs = append(slabs, dataSlab) 4421 4422 // Save id 4423 id = nextID 4424 4425 // Create new elements for next data slab 4426 elements = &hkeyElements{ 4427 level: 0, 4428 size: hkeyElementsPrefixSize, 4429 hkeys: make([]Digest, 0, defaultElementCountInSlab), 4430 elems: make([]element, 0, defaultElementCountInSlab), 4431 } 4432 } 4433 4434 elements.hkeys = append(elements.hkeys, hkey) 4435 elements.elems = append(elements.elems, elem) 4436 elements.size += digestSize + elem.Size() 4437 4438 prevHkey = hkey 4439 4440 count++ 4441 } 4442 4443 // Create last data slab 4444 dataSlab := &MapDataSlab{ 4445 header: MapSlabHeader{ 4446 id: id, 4447 size: mapDataSlabPrefixSize + elements.Size(), 4448 firstKey: elements.firstKey(), 4449 }, 4450 elements: elements, 4451 } 4452 4453 // Append last data slab to slabs 4454 slabs = append(slabs, dataSlab) 4455 4456 for len(slabs) > 1 { 4457 4458 lastSlab := slabs[len(slabs)-1] 4459 4460 // Rebalance last slab if needed 4461 if underflowSize, underflow := lastSlab.IsUnderflow(); underflow { 4462 4463 leftSib := slabs[len(slabs)-2] 4464 4465 if leftSib.CanLendToRight(underflowSize) { 4466 4467 // Rebalance with left 4468 err := leftSib.LendToRight(lastSlab) 4469 if err != nil { 4470 // Don't need to wrap error as external error because err is already categorized by MapSlab.LendToRight(). 4471 return nil, err 4472 } 4473 4474 } else { 4475 4476 // Merge with left 4477 err := leftSib.Merge(lastSlab) 4478 if err != nil { 4479 // Don't need to wrap error as external error because err is already categorized by MapSlab.Merge(). 4480 return nil, err 4481 } 4482 4483 // Remove last slab from slabs 4484 slabs[len(slabs)-1] = nil 4485 slabs = slabs[:len(slabs)-1] 4486 } 4487 } 4488 4489 // All slabs are within target size range. 4490 4491 if len(slabs) == 1 { 4492 // This happens when there were exactly two slabs and 4493 // last slab has merged with the first slab. 4494 break 4495 } 4496 4497 // Store all slabs 4498 for _, slab := range slabs { 4499 err = storage.Store(slab.ID(), slab) 4500 if err != nil { 4501 // Wrap err as external error (if needed) because err is returned by SlabStorage interface. 4502 return nil, wrapErrorfAsExternalErrorIfNeeded(err, fmt.Sprintf("failed to store slab %s", slab.ID())) 4503 } 4504 } 4505 4506 // Get next level meta slabs 4507 slabs, err = nextLevelMapSlabs(storage, address, slabs) 4508 if err != nil { 4509 // Don't need to wrap error as external error because err is already categorized by nextLevelMapSlabs(). 4510 return nil, err 4511 } 4512 4513 } 4514 4515 // found root slab 4516 root := slabs[0] 4517 4518 // root is data slab, adjust its size 4519 if dataSlab, ok := root.(*MapDataSlab); ok { 4520 dataSlab.header.size = dataSlab.header.size - mapDataSlabPrefixSize + mapRootDataSlabPrefixSize 4521 } 4522 4523 extraData := &MapExtraData{TypeInfo: typeInfo, Count: count, Seed: seed} 4524 4525 // Set extra data in root 4526 root.SetExtraData(extraData) 4527 4528 // Store root 4529 err = storage.Store(root.ID(), root) 4530 if err != nil { 4531 // Wrap err as external error (if needed) because err is returned by SlabStorage interface. 4532 return nil, wrapErrorfAsExternalErrorIfNeeded(err, fmt.Sprintf("failed to store slab %s", root.ID())) 4533 } 4534 4535 return &OrderedMap{ 4536 Storage: storage, 4537 root: root, 4538 digesterBuilder: digesterBuilder, 4539 }, nil 4540 } 4541 4542 // nextLevelMapSlabs returns next level meta data slabs from slabs. 4543 // slabs must have at least 2 elements. It is reused and returned as next level slabs. 4544 // Caller is responsible for rebalance last slab and storing returned slabs in storage. 4545 func nextLevelMapSlabs(storage SlabStorage, address Address, slabs []MapSlab) ([]MapSlab, error) { 4546 4547 maxNumberOfHeadersInMetaSlab := (maxThreshold - mapMetaDataSlabPrefixSize) / mapSlabHeaderSize 4548 4549 nextLevelSlabsIndex := 0 4550 4551 // Generate storge id 4552 id, err := storage.GenerateStorageID(address) 4553 if err != nil { 4554 // Wrap err as external error (if needed) because err is returned by SlabStorage interface. 4555 return nil, wrapErrorfAsExternalErrorIfNeeded(err, fmt.Sprintf("failed to generate storage ID for address 0x%x", address)) 4556 } 4557 4558 childrenCount := maxNumberOfHeadersInMetaSlab 4559 if uint64(len(slabs)) < maxNumberOfHeadersInMetaSlab { 4560 childrenCount = uint64(len(slabs)) 4561 } 4562 4563 metaSlab := &MapMetaDataSlab{ 4564 header: MapSlabHeader{ 4565 id: id, 4566 size: mapMetaDataSlabPrefixSize, 4567 firstKey: slabs[0].Header().firstKey, 4568 }, 4569 childrenHeaders: make([]MapSlabHeader, 0, childrenCount), 4570 } 4571 4572 for i, slab := range slabs { 4573 4574 if len(metaSlab.childrenHeaders) == int(maxNumberOfHeadersInMetaSlab) { 4575 4576 slabs[nextLevelSlabsIndex] = metaSlab 4577 nextLevelSlabsIndex++ 4578 4579 // compute number of children for next meta data slab 4580 childrenCount = maxNumberOfHeadersInMetaSlab 4581 if uint64(len(slabs)-i) < maxNumberOfHeadersInMetaSlab { 4582 childrenCount = uint64(len(slabs) - i) 4583 } 4584 4585 // Generate storge id for next meta data slab 4586 id, err = storage.GenerateStorageID(address) 4587 if err != nil { 4588 // Wrap err as external error (if needed) because err is returned by SlabStorage interface. 4589 return nil, wrapErrorfAsExternalErrorIfNeeded(err, fmt.Sprintf("failed to generate storage ID for address 0x%x", address)) 4590 } 4591 4592 metaSlab = &MapMetaDataSlab{ 4593 header: MapSlabHeader{ 4594 id: id, 4595 size: mapMetaDataSlabPrefixSize, 4596 firstKey: slab.Header().firstKey, 4597 }, 4598 childrenHeaders: make([]MapSlabHeader, 0, childrenCount), 4599 } 4600 } 4601 4602 metaSlab.header.size += mapSlabHeaderSize 4603 4604 metaSlab.childrenHeaders = append(metaSlab.childrenHeaders, slab.Header()) 4605 } 4606 4607 // Append last meta slab to slabs 4608 slabs[nextLevelSlabsIndex] = metaSlab 4609 nextLevelSlabsIndex++ 4610 4611 return slabs[:nextLevelSlabsIndex], nil 4612 }