github.com/onflow/atree@v0.6.0/array.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 "fmt" 24 "math" 25 "strings" 26 27 "github.com/fxamacker/cbor/v2" 28 ) 29 30 const ( 31 storageIDSize = 16 32 33 // version and flag size: version (1 byte) + flag (1 byte) 34 versionAndFlagSize = 2 35 36 // slab header size: storage id (16 bytes) + count (4 bytes) + size (4 bytes) 37 arraySlabHeaderSize = storageIDSize + 4 + 4 38 39 // meta data slab prefix size: version (1 byte) + flag (1 byte) + child header count (2 bytes) 40 arrayMetaDataSlabPrefixSize = versionAndFlagSize + 2 41 42 // version (1 byte) + flag (1 byte) + next id (16 bytes) + CBOR array size (3 bytes) 43 // up to 65535 array elements are supported 44 arrayDataSlabPrefixSize = versionAndFlagSize + storageIDSize + 3 45 46 // version (1 byte) + flag (1 byte) + CBOR array size (3 bytes) 47 // up to 65535 array elements are supported 48 arrayRootDataSlabPrefixSize = versionAndFlagSize + 3 49 50 // 32 is faster than 24 and 40. 51 linearScanThreshold = 32 52 ) 53 54 type ArraySlabHeader struct { 55 id StorageID // id is used to retrieve slab from storage 56 size uint32 // size is used to split and merge; leaf: size of all element; internal: size of all headers 57 count uint32 // count is used to lookup element; leaf: number of elements; internal: number of elements in all its headers 58 } 59 60 type ArrayExtraData struct { 61 TypeInfo TypeInfo // array type 62 } 63 64 // ArrayDataSlab is leaf node, implementing ArraySlab. 65 type ArrayDataSlab struct { 66 next StorageID 67 header ArraySlabHeader 68 elements []Storable 69 70 // extraData is data that is prepended to encoded slab data. 71 // It isn't included in slab size calculation for splitting and merging. 72 extraData *ArrayExtraData 73 } 74 75 func (a *ArrayDataSlab) StoredValue(storage SlabStorage) (Value, error) { 76 if a.extraData == nil { 77 return nil, NewNotValueError(a.ID()) 78 } 79 return &Array{ 80 Storage: storage, 81 root: a, 82 }, nil 83 } 84 85 var _ ArraySlab = &ArrayDataSlab{} 86 87 // ArrayMetaDataSlab is internal node, implementing ArraySlab. 88 type ArrayMetaDataSlab struct { 89 header ArraySlabHeader 90 childrenHeaders []ArraySlabHeader 91 // Cumulative counts in the children. 92 // For example, if the counts in childrenHeaders are [10, 15, 12], 93 // childrenCountSum is [10, 25, 37] 94 childrenCountSum []uint32 95 96 // extraData is data that is prepended to encoded slab data. 97 // It isn't included in slab size calculation for splitting and merging. 98 extraData *ArrayExtraData 99 } 100 101 var _ ArraySlab = &ArrayMetaDataSlab{} 102 103 func (a *ArrayMetaDataSlab) StoredValue(storage SlabStorage) (Value, error) { 104 if a.extraData == nil { 105 return nil, NewNotValueError(a.ID()) 106 } 107 return &Array{ 108 Storage: storage, 109 root: a, 110 }, nil 111 } 112 113 type ArraySlab interface { 114 Slab 115 fmt.Stringer 116 117 Get(storage SlabStorage, index uint64) (Storable, error) 118 Set(storage SlabStorage, address Address, index uint64, value Value) (Storable, error) 119 Insert(storage SlabStorage, address Address, index uint64, value Value) error 120 Remove(storage SlabStorage, index uint64) (Storable, error) 121 122 IsData() bool 123 124 IsFull() bool 125 IsUnderflow() (uint32, bool) 126 CanLendToLeft(size uint32) bool 127 CanLendToRight(size uint32) bool 128 129 SetID(StorageID) 130 131 Header() ArraySlabHeader 132 133 ExtraData() *ArrayExtraData 134 RemoveExtraData() *ArrayExtraData 135 SetExtraData(*ArrayExtraData) 136 137 PopIterate(SlabStorage, ArrayPopIterationFunc) error 138 } 139 140 // Array is tree 141 type Array struct { 142 Storage SlabStorage 143 root ArraySlab 144 } 145 146 var _ Value = &Array{} 147 148 func (a *Array) Address() Address { 149 return a.root.ID().Address 150 } 151 152 func (a *Array) Storable(_ SlabStorage, _ Address, _ uint64) (Storable, error) { 153 return StorageIDStorable(a.StorageID()), nil 154 } 155 156 const arrayExtraDataLength = 1 157 158 func newArrayExtraDataFromData( 159 data []byte, 160 decMode cbor.DecMode, 161 decodeTypeInfo TypeInfoDecoder, 162 ) ( 163 *ArrayExtraData, 164 []byte, 165 error, 166 ) { 167 // Check data length 168 if len(data) < versionAndFlagSize { 169 return nil, data, NewDecodingErrorf("data is too short for array extra data") 170 } 171 172 // Check flag 173 flag := data[1] 174 if !isRoot(flag) { 175 return nil, data, NewDecodingErrorf("array extra data has invalid flag 0x%x, want root flag", flag) 176 } 177 178 // Decode extra data 179 180 dec := decMode.NewByteStreamDecoder(data[versionAndFlagSize:]) 181 182 length, err := dec.DecodeArrayHead() 183 if err != nil { 184 return nil, data, NewDecodingError(err) 185 } 186 187 if length != arrayExtraDataLength { 188 return nil, data, NewDecodingError( 189 fmt.Errorf( 190 "data has invalid length %d, want %d", 191 length, 192 arrayExtraDataLength, 193 )) 194 } 195 196 typeInfo, err := decodeTypeInfo(dec) 197 if err != nil { 198 // Wrap err as external error (if needed) because err is returned by TypeInfoDecoder callback. 199 return nil, data, wrapErrorfAsExternalErrorIfNeeded(err, "failed to decode type info") 200 } 201 202 // Reslice for remaining data 203 n := dec.NumBytesDecoded() 204 data = data[versionAndFlagSize+n:] 205 206 return &ArrayExtraData{ 207 TypeInfo: typeInfo, 208 }, data, nil 209 } 210 211 // Encode encodes extra data to the given encoder. 212 // 213 // Header (2 bytes): 214 // 215 // +-----------------------------+--------------------------+ 216 // | extra data version (1 byte) | extra data flag (1 byte) | 217 // +-----------------------------+--------------------------+ 218 // 219 // Content (for now): 220 // 221 // CBOR encoded array of extra data: cborArray{type info} 222 // 223 // Extra data flag is the same as the slab flag it prepends. 224 func (a *ArrayExtraData) Encode(enc *Encoder, flag byte) error { 225 // Encode version 226 enc.Scratch[0] = 0 227 228 // Encode flag 229 enc.Scratch[1] = flag 230 231 // Write scratch content to encoder 232 _, err := enc.Write(enc.Scratch[:versionAndFlagSize]) 233 if err != nil { 234 return NewEncodingError(err) 235 } 236 237 // Encode extra data 238 err = enc.CBOR.EncodeArrayHead(arrayExtraDataLength) 239 if err != nil { 240 return NewEncodingError(err) 241 } 242 243 err = a.TypeInfo.Encode(enc.CBOR) 244 if err != nil { 245 // Wrap err as external error (if needed) because err is returned by TypeInfo interface. 246 return wrapErrorfAsExternalErrorIfNeeded(err, "failed to encode type info") 247 } 248 249 err = enc.CBOR.Flush() 250 if err != nil { 251 return NewEncodingError(err) 252 } 253 254 return nil 255 } 256 257 func newArrayDataSlabFromData( 258 id StorageID, 259 data []byte, 260 decMode cbor.DecMode, 261 decodeStorable StorableDecoder, 262 decodeTypeInfo TypeInfoDecoder, 263 ) ( 264 *ArrayDataSlab, 265 error, 266 ) { 267 // Check minimum data length 268 if len(data) < versionAndFlagSize { 269 return nil, NewDecodingErrorf("data is too short for array data slab") 270 } 271 272 isRootSlab := isRoot(data[1]) 273 274 var extraData *ArrayExtraData 275 276 // Check flag for extra data 277 if isRootSlab { 278 // Decode extra data 279 var err error 280 extraData, data, err = newArrayExtraDataFromData(data, decMode, decodeTypeInfo) 281 if err != nil { 282 // err is categorized already by newArrayExtraDataFromData. 283 return nil, err 284 } 285 } 286 287 minDataLength := arrayDataSlabPrefixSize 288 if isRootSlab { 289 minDataLength = arrayRootDataSlabPrefixSize 290 } 291 292 // Check data length (after decoding extra data if present) 293 if len(data) < minDataLength { 294 return nil, NewDecodingErrorf("data is too short for array data slab") 295 } 296 297 // Check flag 298 flag := data[1] 299 300 if getSlabArrayType(flag) != slabArrayData { 301 return nil, NewDecodingErrorf( 302 "data has invalid flag 0x%x, want 0x%x", 303 flag, 304 maskArrayData, 305 ) 306 } 307 308 var next StorageID 309 310 var contentOffset int 311 312 if !isRootSlab { 313 314 // Decode next storage ID 315 const nextStorageIDOffset = versionAndFlagSize 316 var err error 317 next, err = NewStorageIDFromRawBytes(data[nextStorageIDOffset:]) 318 if err != nil { 319 // error returned from NewStorageIDFromRawBytes is categorized already. 320 return nil, err 321 } 322 323 contentOffset = nextStorageIDOffset + storageIDSize 324 325 } else { 326 contentOffset = versionAndFlagSize 327 } 328 329 // Decode content (CBOR array) 330 cborDec := decMode.NewByteStreamDecoder(data[contentOffset:]) 331 332 elemCount, err := cborDec.DecodeArrayHead() 333 if err != nil { 334 return nil, NewDecodingError(err) 335 } 336 337 elements := make([]Storable, elemCount) 338 for i := 0; i < int(elemCount); i++ { 339 storable, err := decodeStorable(cborDec, StorageIDUndefined) 340 if err != nil { 341 // Wrap err as external error (if needed) because err is returned by StorableDecoder callback. 342 return nil, wrapErrorfAsExternalErrorIfNeeded(err, "failed to decode array element") 343 } 344 elements[i] = storable 345 } 346 347 header := ArraySlabHeader{ 348 id: id, 349 size: uint32(len(data)), 350 count: uint32(elemCount), 351 } 352 353 return &ArrayDataSlab{ 354 next: next, 355 header: header, 356 elements: elements, 357 extraData: extraData, 358 }, nil 359 } 360 361 // Encode encodes this array data slab to the given encoder. 362 // 363 // Header (18 bytes): 364 // 365 // +-------------------------------+--------------------------------+ 366 // | slab version + flag (2 bytes) | next sib storage ID (16 bytes) | 367 // +-------------------------------+--------------------------------+ 368 // 369 // Content (for now): 370 // 371 // CBOR encoded array of elements 372 // 373 // If this is root slab, extra data section is prepended to slab's encoded content. 374 // See ArrayExtraData.Encode() for extra data section format. 375 func (a *ArrayDataSlab) Encode(enc *Encoder) error { 376 377 flag := maskArrayData 378 379 if a.hasPointer() { 380 flag = setHasPointers(flag) 381 } 382 383 // Encode extra data if present 384 if a.extraData != nil { 385 flag = setRoot(flag) 386 387 err := a.extraData.Encode(enc, flag) 388 if err != nil { 389 // err is already categorized by ArrayExtraData.Encode(). 390 return err 391 } 392 } 393 394 // Encode version 395 enc.Scratch[0] = 0 396 397 // Encode flag 398 enc.Scratch[1] = flag 399 400 var contentOffset int 401 402 // Encode next storage ID for non-root data slabs 403 if a.extraData == nil { 404 405 // Encode next storage ID to scratch 406 const nextStorageIDOffset = versionAndFlagSize 407 _, err := a.next.ToRawBytes(enc.Scratch[nextStorageIDOffset:]) 408 if err != nil { 409 // Don't need to wrap because err is already categorized by StorageID.ToRawBytes(). 410 return err 411 } 412 413 contentOffset = nextStorageIDOffset + storageIDSize 414 } else { 415 contentOffset = versionAndFlagSize 416 } 417 418 // Encode CBOR array size manually for fix-sized encoding 419 420 enc.Scratch[contentOffset] = 0x80 | 25 421 422 countOffset := contentOffset + 1 423 const countSize = 2 424 binary.BigEndian.PutUint16( 425 enc.Scratch[countOffset:], 426 uint16(len(a.elements)), 427 ) 428 429 // Write scratch content to encoder 430 totalSize := countOffset + countSize 431 _, err := enc.Write(enc.Scratch[:totalSize]) 432 if err != nil { 433 return NewEncodingError(err) 434 } 435 436 // Encode data slab content (array of elements) 437 for _, e := range a.elements { 438 err = e.Encode(enc) 439 if err != nil { 440 // Wrap err as external error (if needed) because err is returned by Storable interface. 441 return wrapErrorfAsExternalErrorIfNeeded(err, "failed to encode array element") 442 } 443 } 444 445 err = enc.CBOR.Flush() 446 if err != nil { 447 return NewEncodingError(err) 448 } 449 450 return nil 451 } 452 453 func (a *ArrayDataSlab) hasPointer() bool { 454 for _, e := range a.elements { 455 if _, ok := e.(StorageIDStorable); ok { 456 return true 457 } 458 } 459 return false 460 } 461 462 func (a *ArrayDataSlab) ChildStorables() []Storable { 463 s := make([]Storable, len(a.elements)) 464 copy(s, a.elements) 465 return s 466 } 467 468 func (a *ArrayDataSlab) Get(_ SlabStorage, index uint64) (Storable, error) { 469 if index >= uint64(len(a.elements)) { 470 return nil, NewIndexOutOfBoundsError(index, 0, uint64(len(a.elements))) 471 } 472 return a.elements[index], nil 473 } 474 475 func (a *ArrayDataSlab) Set(storage SlabStorage, address Address, index uint64, value Value) (Storable, error) { 476 if index >= uint64(len(a.elements)) { 477 return nil, NewIndexOutOfBoundsError(index, 0, uint64(len(a.elements))) 478 } 479 480 oldElem := a.elements[index] 481 oldSize := oldElem.ByteSize() 482 483 storable, err := value.Storable(storage, address, MaxInlineArrayElementSize) 484 if err != nil { 485 // Wrap err as external error (if needed) because err is returned by Value interface. 486 return nil, wrapErrorfAsExternalErrorIfNeeded(err, "failed to get value's storable") 487 } 488 489 a.elements[index] = storable 490 a.header.size = a.header.size - oldSize + storable.ByteSize() 491 492 err = storage.Store(a.header.id, a) 493 if err != nil { 494 // Wrap err as external error (if needed) because err is returned by SlabStorage interface. 495 return nil, wrapErrorfAsExternalErrorIfNeeded(err, fmt.Sprintf("failed to store slab %s", a.header.id)) 496 } 497 498 return oldElem, nil 499 } 500 501 func (a *ArrayDataSlab) Insert(storage SlabStorage, address Address, index uint64, value Value) error { 502 if index > uint64(len(a.elements)) { 503 return NewIndexOutOfBoundsError(index, 0, uint64(len(a.elements))) 504 } 505 506 storable, err := value.Storable(storage, address, MaxInlineArrayElementSize) 507 if err != nil { 508 // Wrap err as external error (if needed) because err is returned by Value interface. 509 return wrapErrorfAsExternalErrorIfNeeded(err, "failed to get value's storable") 510 } 511 512 if index == uint64(len(a.elements)) { 513 a.elements = append(a.elements, storable) 514 } else { 515 a.elements = append(a.elements, nil) 516 copy(a.elements[index+1:], a.elements[index:]) 517 a.elements[index] = storable 518 } 519 520 a.header.count++ 521 a.header.size += storable.ByteSize() 522 523 err = storage.Store(a.header.id, a) 524 if err != nil { 525 // Wrap err as external error (if needed) because err is returned by SlabStorage interface. 526 return wrapErrorfAsExternalErrorIfNeeded(err, fmt.Sprintf("failed to store slab %s", a.header.id)) 527 } 528 529 return nil 530 } 531 532 func (a *ArrayDataSlab) Remove(storage SlabStorage, index uint64) (Storable, error) { 533 if index >= uint64(len(a.elements)) { 534 return nil, NewIndexOutOfBoundsError(index, 0, uint64(len(a.elements))) 535 } 536 537 v := a.elements[index] 538 539 lastIndex := len(a.elements) - 1 540 541 if index != uint64(lastIndex) { 542 copy(a.elements[index:], a.elements[index+1:]) 543 } 544 545 // NOTE: prevent memory leak 546 a.elements[lastIndex] = nil 547 548 a.elements = a.elements[:lastIndex] 549 550 a.header.count-- 551 a.header.size -= v.ByteSize() 552 553 err := storage.Store(a.header.id, a) 554 if err != nil { 555 // Wrap err as external error (if needed) because err is returned by SlabStorage interface. 556 return nil, wrapErrorfAsExternalErrorIfNeeded(err, fmt.Sprintf("failed to store slab %s", a.header.id)) 557 } 558 559 return v, nil 560 } 561 562 func (a *ArrayDataSlab) Split(storage SlabStorage) (Slab, Slab, error) { 563 if len(a.elements) < 2 { 564 // Can't split slab with less than two elements 565 return nil, nil, NewSlabSplitErrorf("ArrayDataSlab (%s) has less than 2 elements", a.header.id) 566 } 567 568 // This computes the ceil of split to give the first slab with more elements. 569 dataSize := a.header.size - arrayDataSlabPrefixSize 570 midPoint := (dataSize + 1) >> 1 571 572 leftSize := uint32(0) 573 leftCount := 0 574 for i, e := range a.elements { 575 elemSize := e.ByteSize() 576 if leftSize+elemSize >= midPoint { 577 // i is mid point element. Place i on the small side. 578 if leftSize <= dataSize-leftSize-elemSize { 579 leftSize += elemSize 580 leftCount = i + 1 581 } else { 582 leftCount = i 583 } 584 break 585 } 586 // left slab size < midPoint 587 leftSize += elemSize 588 } 589 590 // Construct right slab 591 sID, err := storage.GenerateStorageID(a.header.id.Address) 592 if err != nil { 593 // Wrap err as external error (if needed) because err is returned by SlabStorage interface. 594 return nil, nil, wrapErrorfAsExternalErrorIfNeeded( 595 err, 596 fmt.Sprintf( 597 "failed to generate storage ID for address 0x%x", 598 a.header.id.Address, 599 ), 600 ) 601 } 602 rightSlabCount := len(a.elements) - leftCount 603 rightSlab := &ArrayDataSlab{ 604 header: ArraySlabHeader{ 605 id: sID, 606 size: arrayDataSlabPrefixSize + dataSize - leftSize, 607 count: uint32(rightSlabCount), 608 }, 609 next: a.next, 610 } 611 612 rightSlab.elements = make([]Storable, rightSlabCount) 613 copy(rightSlab.elements, a.elements[leftCount:]) 614 615 // Modify left (original) slab 616 // NOTE: prevent memory leak 617 for i := leftCount; i < len(a.elements); i++ { 618 a.elements[i] = nil 619 } 620 a.elements = a.elements[:leftCount] 621 a.header.size = arrayDataSlabPrefixSize + leftSize 622 a.header.count = uint32(leftCount) 623 a.next = rightSlab.header.id 624 625 return a, rightSlab, nil 626 } 627 628 func (a *ArrayDataSlab) Merge(slab Slab) error { 629 rightSlab := slab.(*ArrayDataSlab) 630 a.elements = append(a.elements, rightSlab.elements...) 631 a.header.size = a.header.size + rightSlab.header.size - arrayDataSlabPrefixSize 632 a.header.count += rightSlab.header.count 633 a.next = rightSlab.next 634 return nil 635 } 636 637 // LendToRight rebalances slabs by moving elements from left slab to right slab 638 func (a *ArrayDataSlab) LendToRight(slab Slab) error { 639 640 rightSlab := slab.(*ArrayDataSlab) 641 642 count := a.header.count + rightSlab.header.count 643 size := a.header.size + rightSlab.header.size 644 645 leftCount := a.header.count 646 leftSize := a.header.size 647 648 midPoint := (size + 1) >> 1 649 650 // Left slab size is as close to midPoint as possible while right slab size >= minThreshold 651 for i := len(a.elements) - 1; i >= 0; i-- { 652 elemSize := a.elements[i].ByteSize() 653 if leftSize-elemSize < midPoint && size-leftSize >= uint32(minThreshold) { 654 break 655 } 656 leftSize -= elemSize 657 leftCount-- 658 } 659 660 // Update the right slab 661 // 662 // It is easier and less error-prone to realloc elements for the right slab. 663 664 elements := make([]Storable, count-leftCount) 665 n := copy(elements, a.elements[leftCount:]) 666 copy(elements[n:], rightSlab.elements) 667 668 rightSlab.elements = elements 669 rightSlab.header.size = size - leftSize 670 rightSlab.header.count = count - leftCount 671 672 // Update left slab 673 // NOTE: prevent memory leak 674 for i := leftCount; i < uint32(len(a.elements)); i++ { 675 a.elements[i] = nil 676 } 677 a.elements = a.elements[:leftCount] 678 a.header.size = leftSize 679 a.header.count = leftCount 680 681 return nil 682 } 683 684 // BorrowFromRight rebalances slabs by moving elements from right slab to left slab. 685 func (a *ArrayDataSlab) BorrowFromRight(slab Slab) error { 686 rightSlab := slab.(*ArrayDataSlab) 687 688 count := a.header.count + rightSlab.header.count 689 size := a.header.size + rightSlab.header.size 690 691 leftCount := a.header.count 692 leftSize := a.header.size 693 694 midPoint := (size + 1) >> 1 695 696 for _, e := range rightSlab.elements { 697 elemSize := e.ByteSize() 698 if leftSize+elemSize > midPoint { 699 if size-leftSize-elemSize >= uint32(minThreshold) { 700 // Include this element in left slab 701 leftSize += elemSize 702 leftCount++ 703 } 704 break 705 } 706 leftSize += elemSize 707 leftCount++ 708 } 709 710 rightStartIndex := leftCount - a.header.count 711 712 // Update left slab 713 a.elements = append(a.elements, rightSlab.elements[:rightStartIndex]...) 714 a.header.size = leftSize 715 a.header.count = leftCount 716 717 // Update right slab 718 // TODO: copy elements to front instead? 719 // NOTE: prevent memory leak 720 for i := uint32(0); i < rightStartIndex; i++ { 721 rightSlab.elements[i] = nil 722 } 723 rightSlab.elements = rightSlab.elements[rightStartIndex:] 724 rightSlab.header.size = size - leftSize 725 rightSlab.header.count = count - leftCount 726 727 return nil 728 } 729 730 func (a *ArrayDataSlab) IsFull() bool { 731 return a.header.size > uint32(maxThreshold) 732 } 733 734 // IsUnderflow returns the number of bytes needed for the data slab 735 // to reach the min threshold. 736 // Returns true if the min threshold has not been reached yet. 737 func (a *ArrayDataSlab) IsUnderflow() (uint32, bool) { 738 if uint32(minThreshold) > a.header.size { 739 return uint32(minThreshold) - a.header.size, true 740 } 741 return 0, false 742 } 743 744 // CanLendToLeft returns true if elements on the left of the slab could be removed 745 // so that the slab still stores more than the min threshold. 746 func (a *ArrayDataSlab) CanLendToLeft(size uint32) bool { 747 if len(a.elements) < 2 { 748 return false 749 } 750 if a.header.size-size < uint32(minThreshold) { 751 return false 752 } 753 lendSize := uint32(0) 754 for i := 0; i < len(a.elements); i++ { 755 lendSize += a.elements[i].ByteSize() 756 if a.header.size-lendSize < uint32(minThreshold) { 757 return false 758 } 759 if lendSize >= size { 760 return true 761 } 762 } 763 return false 764 } 765 766 // CanLendToRight returns true if elements on the right of the slab could be removed 767 // so that the slab still stores more than the min threshold. 768 func (a *ArrayDataSlab) CanLendToRight(size uint32) bool { 769 if len(a.elements) < 2 { 770 return false 771 } 772 if a.header.size-size < uint32(minThreshold) { 773 return false 774 } 775 lendSize := uint32(0) 776 for i := len(a.elements) - 1; i >= 0; i-- { 777 lendSize += a.elements[i].ByteSize() 778 if a.header.size-lendSize < uint32(minThreshold) { 779 return false 780 } 781 if lendSize >= size { 782 return true 783 } 784 } 785 return false 786 } 787 788 func (a *ArrayDataSlab) SetID(id StorageID) { 789 a.header.id = id 790 } 791 792 func (a *ArrayDataSlab) Header() ArraySlabHeader { 793 return a.header 794 } 795 796 func (a *ArrayDataSlab) IsData() bool { 797 return true 798 } 799 800 func (a *ArrayDataSlab) ID() StorageID { 801 return a.header.id 802 } 803 804 func (a *ArrayDataSlab) ByteSize() uint32 { 805 return a.header.size 806 } 807 808 func (a *ArrayDataSlab) ExtraData() *ArrayExtraData { 809 return a.extraData 810 } 811 812 func (a *ArrayDataSlab) RemoveExtraData() *ArrayExtraData { 813 extraData := a.extraData 814 a.extraData = nil 815 return extraData 816 } 817 818 func (a *ArrayDataSlab) SetExtraData(extraData *ArrayExtraData) { 819 a.extraData = extraData 820 } 821 822 func (a *ArrayDataSlab) PopIterate(storage SlabStorage, fn ArrayPopIterationFunc) error { 823 824 // Iterate and reset elements backwards 825 for i := len(a.elements) - 1; i >= 0; i-- { 826 fn(a.elements[i]) 827 } 828 829 // Reset data slab 830 a.elements = nil 831 a.header.count = 0 832 a.header.size = arrayDataSlabPrefixSize 833 834 return nil 835 } 836 837 func (a *ArrayDataSlab) String() string { 838 var elemsStr []string 839 for _, e := range a.elements { 840 elemsStr = append(elemsStr, fmt.Sprint(e)) 841 } 842 843 return fmt.Sprintf("ArrayDataSlab id:%s size:%d count:%d elements: [%s]", 844 a.header.id, 845 a.header.size, 846 a.header.count, 847 strings.Join(elemsStr, " "), 848 ) 849 } 850 851 func newArrayMetaDataSlabFromData( 852 id StorageID, 853 data []byte, 854 decMode cbor.DecMode, 855 decodeTypeInfo TypeInfoDecoder, 856 ) ( 857 *ArrayMetaDataSlab, 858 error, 859 ) { 860 // Check minimum data length 861 if len(data) < versionAndFlagSize { 862 return nil, NewDecodingErrorf("data is too short for array metadata slab") 863 } 864 865 var extraData *ArrayExtraData 866 867 // Check flag for extra data 868 if isRoot(data[1]) { 869 // Decode extra data 870 var err error 871 extraData, data, err = newArrayExtraDataFromData(data, decMode, decodeTypeInfo) 872 if err != nil { 873 // Don't need to wrap because err is already categorized by newArrayExtraDataFromData(). 874 return nil, err 875 } 876 } 877 878 // Check data length (after decoding extra data if present) 879 if len(data) < arrayMetaDataSlabPrefixSize { 880 return nil, NewDecodingErrorf("data is too short for array metadata slab") 881 } 882 883 // Check flag 884 flag := data[1] 885 if getSlabArrayType(flag) != slabArrayMeta { 886 return nil, NewDecodingErrorf( 887 "data has invalid flag 0x%x, want 0x%x", 888 flag, 889 maskArrayMeta, 890 ) 891 } 892 893 // Decode number of child headers 894 const childHeaderCountOffset = versionAndFlagSize 895 childHeaderCount := binary.BigEndian.Uint16(data[childHeaderCountOffset:]) 896 897 expectedDataLength := arrayMetaDataSlabPrefixSize + arraySlabHeaderSize*int(childHeaderCount) 898 if len(data) != expectedDataLength { 899 return nil, NewDecodingErrorf( 900 "data has unexpected length %d, want %d", 901 len(data), 902 expectedDataLength, 903 ) 904 } 905 906 // Decode child headers 907 childrenHeaders := make([]ArraySlabHeader, childHeaderCount) 908 childrenCountSum := make([]uint32, childHeaderCount) 909 totalCount := uint32(0) 910 offset := childHeaderCountOffset + 2 911 912 for i := 0; i < int(childHeaderCount); i++ { 913 storageID, err := NewStorageIDFromRawBytes(data[offset:]) 914 if err != nil { 915 // Don't need to wrap because err is already categorized by NewStorageIDFromRawBytes(). 916 return nil, err 917 } 918 919 countOffset := offset + storageIDSize 920 count := binary.BigEndian.Uint32(data[countOffset:]) 921 922 sizeOffset := countOffset + 4 923 size := binary.BigEndian.Uint32(data[sizeOffset:]) 924 925 totalCount += count 926 927 childrenHeaders[i] = ArraySlabHeader{ 928 id: storageID, 929 count: count, 930 size: size, 931 } 932 childrenCountSum[i] = totalCount 933 934 offset += arraySlabHeaderSize 935 } 936 937 header := ArraySlabHeader{ 938 id: id, 939 size: uint32(len(data)), 940 count: totalCount, 941 } 942 943 return &ArrayMetaDataSlab{ 944 header: header, 945 childrenHeaders: childrenHeaders, 946 childrenCountSum: childrenCountSum, 947 extraData: extraData, 948 }, nil 949 } 950 951 // Encode encodes this array meta-data slab to the given encoder. 952 // 953 // Header (4 bytes): 954 // 955 // +-----------------------+--------------------+------------------------------+ 956 // | slab version (1 byte) | slab flag (1 byte) | child header count (2 bytes) | 957 // +-----------------------+--------------------+------------------------------+ 958 // 959 // Content (n * 16 bytes): 960 // 961 // [[count, size, storage id], ...] 962 // 963 // If this is root slab, extra data section is prepended to slab's encoded content. 964 // See ArrayExtraData.Encode() for extra data section format. 965 func (a *ArrayMetaDataSlab) Encode(enc *Encoder) error { 966 967 flag := maskArrayMeta 968 969 // Encode extra data if present 970 if a.extraData != nil { 971 flag = setRoot(flag) 972 973 err := a.extraData.Encode(enc, flag) 974 if err != nil { 975 // Don't need to wrap because err is already categorized by ArrayExtraData.Encode(). 976 return err 977 } 978 } 979 980 // Encode version 981 enc.Scratch[0] = 0 982 983 // Encode flag 984 enc.Scratch[1] = flag 985 986 // Encode child header count to scratch 987 const childHeaderCountOffset = versionAndFlagSize 988 binary.BigEndian.PutUint16( 989 enc.Scratch[childHeaderCountOffset:], 990 uint16(len(a.childrenHeaders)), 991 ) 992 993 // Write scratch content to encoder 994 const totalSize = childHeaderCountOffset + 2 995 _, err := enc.Write(enc.Scratch[:totalSize]) 996 if err != nil { 997 return NewEncodingError(err) 998 } 999 1000 // Encode children headers 1001 for _, h := range a.childrenHeaders { 1002 _, err := h.id.ToRawBytes(enc.Scratch[:]) 1003 if err != nil { 1004 // Don't need to wrap because err is already categorized by StorageID.ToRawBytes(). 1005 return err 1006 } 1007 1008 const countOffset = storageIDSize 1009 binary.BigEndian.PutUint32(enc.Scratch[countOffset:], h.count) 1010 1011 const sizeOffset = countOffset + 4 1012 binary.BigEndian.PutUint32(enc.Scratch[sizeOffset:], h.size) 1013 1014 const totalSize = sizeOffset + 4 1015 _, err = enc.Write(enc.Scratch[:totalSize]) 1016 if err != nil { 1017 return NewEncodingError(err) 1018 } 1019 } 1020 1021 return nil 1022 } 1023 1024 func (a *ArrayMetaDataSlab) ChildStorables() []Storable { 1025 1026 childIDs := make([]Storable, len(a.childrenHeaders)) 1027 1028 for i, h := range a.childrenHeaders { 1029 childIDs[i] = StorageIDStorable(h.id) 1030 } 1031 1032 return childIDs 1033 } 1034 1035 // TODO: improve naming 1036 func (a *ArrayMetaDataSlab) childSlabIndexInfo( 1037 index uint64, 1038 ) ( 1039 childHeaderIndex int, 1040 adjustedIndex uint64, 1041 childID StorageID, 1042 err error, 1043 ) { 1044 if index >= uint64(a.header.count) { 1045 return 0, 0, StorageID{}, NewIndexOutOfBoundsError(index, 0, uint64(a.header.count)) 1046 } 1047 1048 // Either perform a linear scan (for small number of children), 1049 // or a binary search 1050 1051 count := len(a.childrenCountSum) 1052 1053 if count < linearScanThreshold { 1054 for i, countSum := range a.childrenCountSum { 1055 if index < uint64(countSum) { 1056 childHeaderIndex = i 1057 break 1058 } 1059 } 1060 } else { 1061 low, high := 0, count 1062 for low < high { 1063 // The following line is borrowed from Go runtime . 1064 mid := int(uint(low+high) >> 1) // avoid overflow when computing mid 1065 midCountSum := uint64(a.childrenCountSum[mid]) 1066 1067 if midCountSum < index { 1068 low = mid + 1 1069 } else if midCountSum > index { 1070 high = mid 1071 } else { 1072 low = mid + 1 1073 break 1074 1075 } 1076 } 1077 childHeaderIndex = low 1078 } 1079 1080 childHeader := a.childrenHeaders[childHeaderIndex] 1081 adjustedIndex = index + uint64(childHeader.count) - uint64(a.childrenCountSum[childHeaderIndex]) 1082 childID = childHeader.id 1083 1084 return childHeaderIndex, adjustedIndex, childID, nil 1085 } 1086 1087 func (a *ArrayMetaDataSlab) Get(storage SlabStorage, index uint64) (Storable, error) { 1088 1089 _, adjustedIndex, childID, err := a.childSlabIndexInfo(index) 1090 if err != nil { 1091 // Don't need to wrap error as external error because err is already categorized by ArrayMetadataSlab.childSlabIndexInfo(). 1092 return nil, err 1093 } 1094 1095 child, err := getArraySlab(storage, childID) 1096 if err != nil { 1097 // Don't need to wrap error as external error because err is already categorized by getArraySlab(). 1098 return nil, err 1099 } 1100 1101 // Don't need to wrap error as external error because err is already categorized by ArraySlab.Get(). 1102 return child.Get(storage, adjustedIndex) 1103 } 1104 1105 func (a *ArrayMetaDataSlab) Set(storage SlabStorage, address Address, index uint64, value Value) (Storable, error) { 1106 1107 childHeaderIndex, adjustedIndex, childID, err := a.childSlabIndexInfo(index) 1108 if err != nil { 1109 // Don't need to wrap error as external error because err is already categorized by ArrayMetadataSlab.childSlabIndexInfo(). 1110 return nil, err 1111 } 1112 1113 child, err := getArraySlab(storage, childID) 1114 if err != nil { 1115 // Don't need to wrap error as external error because err is already categorized by getArraySlab(). 1116 return nil, err 1117 } 1118 1119 existingElem, err := child.Set(storage, address, adjustedIndex, value) 1120 if err != nil { 1121 // Don't need to wrap error as external error because err is already categorized by ArraySlab.Set(). 1122 return nil, err 1123 } 1124 1125 a.childrenHeaders[childHeaderIndex] = child.Header() 1126 1127 // Update may increase or decrease the size, 1128 // check if full and for underflow 1129 1130 if child.IsFull() { 1131 err = a.SplitChildSlab(storage, child, childHeaderIndex) 1132 if err != nil { 1133 // Don't need to wrap error as external error because err is already categorized by ArrayMetaDataSlab.SplitChildSlab(). 1134 return nil, err 1135 } 1136 return existingElem, nil 1137 } 1138 1139 if underflowSize, underflow := child.IsUnderflow(); underflow { 1140 err = a.MergeOrRebalanceChildSlab(storage, child, childHeaderIndex, underflowSize) 1141 if err != nil { 1142 // Don't need to wrap error as external error because err is already categorized by ArrayMetaDataSlab.MergeOrRebalanceChildSlab(). 1143 return nil, err 1144 } 1145 return existingElem, nil 1146 } 1147 1148 err = storage.Store(a.header.id, a) 1149 if err != nil { 1150 // Wrap err as external error (if needed) because err is returned by SlabStorage interface. 1151 return nil, wrapErrorfAsExternalErrorIfNeeded(err, fmt.Sprintf("failed to store slab %s", a.header.id)) 1152 } 1153 return existingElem, nil 1154 } 1155 1156 // Insert inserts v into the correct child slab. 1157 // index must be >=0 and <= a.header.count. 1158 // If index == a.header.count, Insert appends v to the end of underlying slab. 1159 func (a *ArrayMetaDataSlab) Insert(storage SlabStorage, address Address, index uint64, value Value) error { 1160 if index > uint64(a.header.count) { 1161 return NewIndexOutOfBoundsError(index, 0, uint64(a.header.count)) 1162 } 1163 1164 var childID StorageID 1165 var childHeaderIndex int 1166 var adjustedIndex uint64 1167 if index == uint64(a.header.count) { 1168 childHeaderIndex = len(a.childrenHeaders) - 1 1169 h := a.childrenHeaders[childHeaderIndex] 1170 childID = h.id 1171 adjustedIndex = uint64(h.count) 1172 } else { 1173 var err error 1174 childHeaderIndex, adjustedIndex, childID, err = a.childSlabIndexInfo(index) 1175 if err != nil { 1176 // Don't need to wrap error as external error because err is already categorized by ArrayMetadataSlab.childSlabIndexInfo(). 1177 return err 1178 } 1179 } 1180 1181 child, err := getArraySlab(storage, childID) 1182 if err != nil { 1183 // Don't need to wrap error as external error because err is already categorized by getArraySlab(). 1184 return err 1185 } 1186 1187 err = child.Insert(storage, address, adjustedIndex, value) 1188 if err != nil { 1189 // Don't need to wrap error as external error because err is already categorized by ArraySlab.Insert(). 1190 return err 1191 } 1192 1193 a.header.count++ 1194 1195 // Increment childrenCountSum from childHeaderIndex 1196 for i := childHeaderIndex; i < len(a.childrenCountSum); i++ { 1197 a.childrenCountSum[i]++ 1198 } 1199 1200 a.childrenHeaders[childHeaderIndex] = child.Header() 1201 1202 // Insertion increases the size, 1203 // check if full 1204 1205 if child.IsFull() { 1206 // Don't need to wrap error as external error because err is already categorized by ArrayMetaDataSlab.SplitChildSlab(). 1207 return a.SplitChildSlab(storage, child, childHeaderIndex) 1208 } 1209 1210 // Insertion always increases the size, 1211 // so there is no need to check underflow 1212 1213 err = storage.Store(a.header.id, a) 1214 if err != nil { 1215 // Wrap err as external error (if needed) because err is returned by SlabStorage interface. 1216 return wrapErrorfAsExternalErrorIfNeeded(err, fmt.Sprintf("failed to store slab %s", a.header.id)) 1217 } 1218 1219 return nil 1220 } 1221 1222 func (a *ArrayMetaDataSlab) Remove(storage SlabStorage, index uint64) (Storable, error) { 1223 1224 if index >= uint64(a.header.count) { 1225 return nil, NewIndexOutOfBoundsError(index, 0, uint64(a.header.count)) 1226 } 1227 1228 childHeaderIndex, adjustedIndex, childID, err := a.childSlabIndexInfo(index) 1229 if err != nil { 1230 // Don't need to wrap error as external error because err is already categorized by ArrayMetadataSlab.childSlabIndexInfo(). 1231 return nil, err 1232 } 1233 1234 child, err := getArraySlab(storage, childID) 1235 if err != nil { 1236 // Don't need to wrap error as external error because err is already categorized by getArraySlab(). 1237 return nil, err 1238 } 1239 1240 v, err := child.Remove(storage, adjustedIndex) 1241 if err != nil { 1242 // Don't need to wrap error as external error because err is already categorized by ArraySlab.Remove(). 1243 return nil, err 1244 } 1245 1246 a.header.count-- 1247 1248 // Decrement childrenCountSum from childHeaderIndex 1249 for i := childHeaderIndex; i < len(a.childrenCountSum); i++ { 1250 a.childrenCountSum[i]-- 1251 } 1252 1253 a.childrenHeaders[childHeaderIndex] = child.Header() 1254 1255 // Removal decreases the size, 1256 // check for underflow 1257 1258 if underflowSize, isUnderflow := child.IsUnderflow(); isUnderflow { 1259 err = a.MergeOrRebalanceChildSlab(storage, child, childHeaderIndex, underflowSize) 1260 if err != nil { 1261 // Don't need to wrap error as external error because err is already categorized by ArrayMetaDataSlab.MergeOrRebalanceChildSlab(). 1262 return nil, err 1263 } 1264 } 1265 1266 // Removal always decreases the size, 1267 // so there is no need to check isFull 1268 1269 err = storage.Store(a.header.id, a) 1270 if err != nil { 1271 // Wrap err as external error (if needed) because err is returned by SlabStorage interface. 1272 return nil, wrapErrorfAsExternalErrorIfNeeded(err, fmt.Sprintf("failed to store slab %s", a.header.id)) 1273 } 1274 1275 return v, nil 1276 } 1277 1278 func (a *ArrayMetaDataSlab) SplitChildSlab(storage SlabStorage, child ArraySlab, childHeaderIndex int) error { 1279 leftSlab, rightSlab, err := child.Split(storage) 1280 if err != nil { 1281 // Don't need to wrap error as external error because err is already categorized by ArraySlab.Split(). 1282 return err 1283 } 1284 1285 left := leftSlab.(ArraySlab) 1286 right := rightSlab.(ArraySlab) 1287 1288 // Add new child slab (right) to childrenHeaders 1289 a.childrenHeaders = append(a.childrenHeaders, ArraySlabHeader{}) 1290 if childHeaderIndex < len(a.childrenHeaders)-2 { 1291 copy(a.childrenHeaders[childHeaderIndex+2:], a.childrenHeaders[childHeaderIndex+1:]) 1292 } 1293 a.childrenHeaders[childHeaderIndex] = left.Header() 1294 a.childrenHeaders[childHeaderIndex+1] = right.Header() 1295 1296 // Adjust childrenCountSum 1297 a.childrenCountSum = append(a.childrenCountSum, uint32(0)) 1298 copy(a.childrenCountSum[childHeaderIndex+1:], a.childrenCountSum[childHeaderIndex:]) 1299 a.childrenCountSum[childHeaderIndex] -= right.Header().count 1300 1301 // Increase header size 1302 a.header.size += arraySlabHeaderSize 1303 1304 // Store modified slabs 1305 err = storage.Store(left.ID(), left) 1306 if err != nil { 1307 // Wrap err as external error (if needed) because err is returned by SlabStorage interface. 1308 return wrapErrorfAsExternalErrorIfNeeded(err, fmt.Sprintf("failed to store slab %s", left.ID())) 1309 } 1310 1311 err = storage.Store(right.ID(), right) 1312 if err != nil { 1313 // Wrap err as external error (if needed) because err is returned by SlabStorage interface. 1314 return wrapErrorfAsExternalErrorIfNeeded(err, fmt.Sprintf("failed to store slab %s", right.ID())) 1315 } 1316 1317 err = storage.Store(a.header.id, a) 1318 if err != nil { 1319 // Wrap err as external error (if needed) because err is returned by SlabStorage interface. 1320 return wrapErrorfAsExternalErrorIfNeeded(err, fmt.Sprintf("failed to store slab %s", a.header.id)) 1321 } 1322 1323 return nil 1324 } 1325 1326 // MergeOrRebalanceChildSlab merges or rebalances child slab. 1327 // If merged, then parent slab's data is adjusted. 1328 // 1329 // +-----------------------+-----------------------+----------------------+-----------------------+ 1330 // | | no left sibling (sib) | left sib can't lend | left sib can lend | 1331 // +=======================+=======================+======================+=======================+ 1332 // | no right sib | panic | merge with left | rebalance with left | 1333 // +-----------------------+-----------------------+----------------------+-----------------------+ 1334 // | right sib can't lend | merge with right | merge with smaller | rebalance with left | 1335 // +-----------------------+-----------------------+----------------------+-----------------------+ 1336 // | right sib can lend | rebalance with right | rebalance with right | rebalance with bigger | 1337 // +-----------------------+-----------------------+----------------------+-----------------------+ 1338 func (a *ArrayMetaDataSlab) MergeOrRebalanceChildSlab( 1339 storage SlabStorage, 1340 child ArraySlab, 1341 childHeaderIndex int, 1342 underflowSize uint32, 1343 ) error { 1344 1345 // Retrieve left and right siblings of the same parent. 1346 var leftSib, rightSib ArraySlab 1347 if childHeaderIndex > 0 { 1348 leftSibID := a.childrenHeaders[childHeaderIndex-1].id 1349 1350 var err error 1351 leftSib, err = getArraySlab(storage, leftSibID) 1352 if err != nil { 1353 // Don't need to wrap error as external error because err is already categorized by getArraySlab(). 1354 return err 1355 } 1356 } 1357 if childHeaderIndex < len(a.childrenHeaders)-1 { 1358 rightSibID := a.childrenHeaders[childHeaderIndex+1].id 1359 1360 var err error 1361 rightSib, err = getArraySlab(storage, rightSibID) 1362 if err != nil { 1363 // Don't need to wrap error as external error because err is already categorized by getArraySlab(). 1364 return err 1365 } 1366 } 1367 1368 leftCanLend := leftSib != nil && leftSib.CanLendToRight(underflowSize) 1369 rightCanLend := rightSib != nil && rightSib.CanLendToLeft(underflowSize) 1370 1371 // Child can rebalance elements with at least one sibling. 1372 if leftCanLend || rightCanLend { 1373 1374 // Rebalance with right sib 1375 if !leftCanLend { 1376 baseCountSum := a.childrenCountSum[childHeaderIndex] - child.Header().count 1377 1378 err := child.BorrowFromRight(rightSib) 1379 if err != nil { 1380 // Don't need to wrap error as external error because err is already categorized by ArraySlab.BorrowFromRight(). 1381 return err 1382 } 1383 1384 a.childrenHeaders[childHeaderIndex] = child.Header() 1385 a.childrenHeaders[childHeaderIndex+1] = rightSib.Header() 1386 1387 // Adjust childrenCountSum 1388 a.childrenCountSum[childHeaderIndex] = baseCountSum + child.Header().count 1389 1390 // Store modified slabs 1391 err = storage.Store(child.ID(), child) 1392 if err != nil { 1393 // Wrap err as external error (if needed) because err is returned by SlabStorage interface. 1394 return wrapErrorfAsExternalErrorIfNeeded(err, fmt.Sprintf("failed to store slab %s", child.ID())) 1395 } 1396 err = storage.Store(rightSib.ID(), rightSib) 1397 if err != nil { 1398 // Wrap err as external error (if needed) because err is returned by SlabStorage interface. 1399 return wrapErrorfAsExternalErrorIfNeeded(err, fmt.Sprintf("failed to store slab %s", rightSib.ID())) 1400 } 1401 err = storage.Store(a.header.id, a) 1402 if err != nil { 1403 // Wrap err as external error (if needed) because err is returned by SlabStorage interface. 1404 return wrapErrorfAsExternalErrorIfNeeded(err, fmt.Sprintf("failed to store slab %s", a.header.id)) 1405 } 1406 return nil 1407 } 1408 1409 // Rebalance with left sib 1410 if !rightCanLend { 1411 baseCountSum := a.childrenCountSum[childHeaderIndex-1] - leftSib.Header().count 1412 1413 err := leftSib.LendToRight(child) 1414 if err != nil { 1415 // Don't need to wrap error as external error because err is already categorized by ArraySlab.LendToRight(). 1416 return err 1417 } 1418 1419 a.childrenHeaders[childHeaderIndex-1] = leftSib.Header() 1420 a.childrenHeaders[childHeaderIndex] = child.Header() 1421 1422 // Adjust childrenCountSum 1423 a.childrenCountSum[childHeaderIndex-1] = baseCountSum + leftSib.Header().count 1424 1425 // Store modified slabs 1426 err = storage.Store(leftSib.ID(), leftSib) 1427 if err != nil { 1428 // Wrap err as external error (if needed) because err is returned by SlabStorage interface. 1429 return wrapErrorfAsExternalErrorIfNeeded(err, fmt.Sprintf("failed to store slab %s", leftSib.ID())) 1430 } 1431 err = storage.Store(child.ID(), child) 1432 if err != nil { 1433 // Wrap err as external error (if needed) because err is returned by SlabStorage interface. 1434 return wrapErrorfAsExternalErrorIfNeeded(err, fmt.Sprintf("failed to store slab %s", child.ID())) 1435 } 1436 err = storage.Store(a.header.id, a) 1437 if err != nil { 1438 // Wrap err as external error (if needed) because err is returned by SlabStorage interface. 1439 return wrapErrorfAsExternalErrorIfNeeded(err, fmt.Sprintf("failed to store slab %s", a.header.id)) 1440 } 1441 return nil 1442 } 1443 1444 // Rebalance with bigger sib 1445 if leftSib.ByteSize() > rightSib.ByteSize() { 1446 baseCountSum := a.childrenCountSum[childHeaderIndex-1] - leftSib.Header().count 1447 1448 err := leftSib.LendToRight(child) 1449 if err != nil { 1450 // Don't need to wrap error as external error because err is already categorized by ArraySlab.LendToRight(). 1451 return err 1452 } 1453 1454 a.childrenHeaders[childHeaderIndex-1] = leftSib.Header() 1455 a.childrenHeaders[childHeaderIndex] = child.Header() 1456 1457 // Adjust childrenCountSum 1458 a.childrenCountSum[childHeaderIndex-1] = baseCountSum + leftSib.Header().count 1459 1460 // Store modified slabs 1461 err = storage.Store(leftSib.ID(), leftSib) 1462 if err != nil { 1463 // Wrap err as external error (if needed) because err is returned by SlabStorage interface. 1464 return wrapErrorfAsExternalErrorIfNeeded(err, fmt.Sprintf("failed to store slab %s", leftSib.ID())) 1465 } 1466 err = storage.Store(child.ID(), child) 1467 if err != nil { 1468 // Wrap err as external error (if needed) because err is returned by SlabStorage interface. 1469 return wrapErrorfAsExternalErrorIfNeeded(err, fmt.Sprintf("failed to store slab %s", child.ID())) 1470 } 1471 err = storage.Store(a.header.id, a) 1472 if err != nil { 1473 // Wrap err as external error (if needed) because err is returned by SlabStorage interface. 1474 return wrapErrorfAsExternalErrorIfNeeded(err, fmt.Sprintf("failed to store slab %s", a.header.id)) 1475 } 1476 return nil 1477 } else { 1478 // leftSib.ByteSize() <= rightSib.ByteSize 1479 1480 baseCountSum := a.childrenCountSum[childHeaderIndex] - child.Header().count 1481 1482 err := child.BorrowFromRight(rightSib) 1483 if err != nil { 1484 // Don't need to wrap error as external error because err is already categorized by ArraySlab.BorrowFromRight(). 1485 return err 1486 } 1487 1488 a.childrenHeaders[childHeaderIndex] = child.Header() 1489 a.childrenHeaders[childHeaderIndex+1] = rightSib.Header() 1490 1491 // Adjust childrenCountSum 1492 a.childrenCountSum[childHeaderIndex] = baseCountSum + child.Header().count 1493 1494 // Store modified slabs 1495 err = storage.Store(child.ID(), child) 1496 if err != nil { 1497 // Wrap err as external error (if needed) because err is returned by SlabStorage interface. 1498 return wrapErrorfAsExternalErrorIfNeeded(err, fmt.Sprintf("failed to store slab %s", child.ID())) 1499 } 1500 err = storage.Store(rightSib.ID(), rightSib) 1501 if err != nil { 1502 // Wrap err as external error (if needed) because err is returned by SlabStorage interface. 1503 return wrapErrorfAsExternalErrorIfNeeded(err, fmt.Sprintf("failed to store slab %s", rightSib.ID())) 1504 } 1505 err = storage.Store(a.header.id, a) 1506 if err != nil { 1507 // Wrap err as external error (if needed) because err is returned by SlabStorage interface. 1508 return wrapErrorfAsExternalErrorIfNeeded(err, fmt.Sprintf("failed to store slab %s", a.header.id)) 1509 } 1510 return nil 1511 } 1512 } 1513 1514 // Child can't rebalance with any sibling. It must merge with one sibling. 1515 1516 if leftSib == nil { 1517 1518 // Merge with right 1519 err := child.Merge(rightSib) 1520 if err != nil { 1521 // Don't need to wrap error as external error because err is already categorized by ArraySlab.Merge(). 1522 return err 1523 } 1524 1525 a.childrenHeaders[childHeaderIndex] = child.Header() 1526 1527 // Update MetaDataSlab's childrenHeaders 1528 copy(a.childrenHeaders[childHeaderIndex+1:], a.childrenHeaders[childHeaderIndex+2:]) 1529 a.childrenHeaders = a.childrenHeaders[:len(a.childrenHeaders)-1] 1530 1531 // Adjust childrenCountSum 1532 copy(a.childrenCountSum[childHeaderIndex:], a.childrenCountSum[childHeaderIndex+1:]) 1533 a.childrenCountSum = a.childrenCountSum[:len(a.childrenCountSum)-1] 1534 1535 a.header.size -= arraySlabHeaderSize 1536 1537 // Store modified slabs in storage 1538 err = storage.Store(child.ID(), child) 1539 if err != nil { 1540 // Wrap err as external error (if needed) because err is returned by SlabStorage interface. 1541 return wrapErrorfAsExternalErrorIfNeeded(err, fmt.Sprintf("failed to store slab %s", child.ID())) 1542 } 1543 1544 err = storage.Store(a.header.id, a) 1545 if err != nil { 1546 // Wrap err as external error (if needed) because err is returned by SlabStorage interface. 1547 return wrapErrorfAsExternalErrorIfNeeded(err, fmt.Sprintf("failed to store slab %s", a.header.id)) 1548 } 1549 1550 // Remove right sib from storage 1551 err = storage.Remove(rightSib.ID()) 1552 if err != nil { 1553 // Wrap err as external error (if needed) because err is returned by SlabStorage interface. 1554 return wrapErrorfAsExternalErrorIfNeeded(err, fmt.Sprintf("failed to remove slab %s", rightSib.ID())) 1555 } 1556 1557 return nil 1558 } 1559 1560 if rightSib == nil { 1561 1562 // Merge with left 1563 err := leftSib.Merge(child) 1564 if err != nil { 1565 // Don't need to wrap error as external error because err is already categorized by ArraySlab.Merge(). 1566 return err 1567 } 1568 1569 a.childrenHeaders[childHeaderIndex-1] = leftSib.Header() 1570 1571 // Update MetaDataSlab's childrenHeaders 1572 copy(a.childrenHeaders[childHeaderIndex:], a.childrenHeaders[childHeaderIndex+1:]) 1573 a.childrenHeaders = a.childrenHeaders[:len(a.childrenHeaders)-1] 1574 1575 // Adjust childrenCountSum 1576 copy(a.childrenCountSum[childHeaderIndex-1:], a.childrenCountSum[childHeaderIndex:]) 1577 a.childrenCountSum = a.childrenCountSum[:len(a.childrenCountSum)-1] 1578 1579 a.header.size -= arraySlabHeaderSize 1580 1581 // Store modified slabs in storage 1582 err = storage.Store(leftSib.ID(), leftSib) 1583 if err != nil { 1584 // Wrap err as external error (if needed) because err is returned by SlabStorage interface. 1585 return wrapErrorfAsExternalErrorIfNeeded(err, fmt.Sprintf("failed to store slab %s", leftSib.ID())) 1586 } 1587 1588 err = storage.Store(a.header.id, a) 1589 if err != nil { 1590 // Wrap err as external error (if needed) because err is returned by SlabStorage interface. 1591 return wrapErrorfAsExternalErrorIfNeeded(err, fmt.Sprintf("failed to store slab %s", a.header.id)) 1592 } 1593 1594 // Remove child from storage 1595 err = storage.Remove(child.ID()) 1596 if err != nil { 1597 // Wrap err as external error (if needed) because err is returned by SlabStorage interface. 1598 return wrapErrorfAsExternalErrorIfNeeded(err, fmt.Sprintf("failed to remove slab %s", child.ID())) 1599 } 1600 1601 return nil 1602 } 1603 1604 // Merge with smaller sib 1605 if leftSib.ByteSize() < rightSib.ByteSize() { 1606 err := leftSib.Merge(child) 1607 if err != nil { 1608 // Don't need to wrap error as external error because err is already categorized by ArraySlab.Merge(). 1609 return err 1610 } 1611 1612 a.childrenHeaders[childHeaderIndex-1] = leftSib.Header() 1613 1614 // Update MetaDataSlab's childrenHeaders 1615 copy(a.childrenHeaders[childHeaderIndex:], a.childrenHeaders[childHeaderIndex+1:]) 1616 a.childrenHeaders = a.childrenHeaders[:len(a.childrenHeaders)-1] 1617 1618 // Adjust childrenCountSum 1619 copy(a.childrenCountSum[childHeaderIndex-1:], a.childrenCountSum[childHeaderIndex:]) 1620 a.childrenCountSum = a.childrenCountSum[:len(a.childrenCountSum)-1] 1621 1622 a.header.size -= arraySlabHeaderSize 1623 1624 // Store modified slabs in storage 1625 err = storage.Store(leftSib.ID(), leftSib) 1626 if err != nil { 1627 // Wrap err as external error (if needed) because err is returned by SlabStorage interface. 1628 return wrapErrorfAsExternalErrorIfNeeded(err, fmt.Sprintf("failed to store slab %s", leftSib.ID())) 1629 } 1630 err = storage.Store(a.header.id, a) 1631 if err != nil { 1632 // Wrap err as external error (if needed) because err is returned by SlabStorage interface. 1633 return wrapErrorfAsExternalErrorIfNeeded(err, fmt.Sprintf("failed to store slab %s", a.header.id)) 1634 } 1635 1636 // Remove child from storage 1637 err = storage.Remove(child.ID()) 1638 if err != nil { 1639 // Wrap err as external error (if needed) because err is returned by SlabStorage interface. 1640 return wrapErrorfAsExternalErrorIfNeeded(err, fmt.Sprintf("failed to remove slab %s", child.ID())) 1641 } 1642 return nil 1643 1644 } else { 1645 // leftSib.ByteSize > rightSib.ByteSize 1646 1647 err := child.Merge(rightSib) 1648 if err != nil { 1649 // Don't need to wrap error as external error because err is already categorized by ArraySlab.Merge(). 1650 return err 1651 } 1652 1653 a.childrenHeaders[childHeaderIndex] = child.Header() 1654 1655 // Update MetaDataSlab's childrenHeaders 1656 copy(a.childrenHeaders[childHeaderIndex+1:], a.childrenHeaders[childHeaderIndex+2:]) 1657 a.childrenHeaders = a.childrenHeaders[:len(a.childrenHeaders)-1] 1658 1659 // Adjust childrenCountSum 1660 copy(a.childrenCountSum[childHeaderIndex:], a.childrenCountSum[childHeaderIndex+1:]) 1661 a.childrenCountSum = a.childrenCountSum[:len(a.childrenCountSum)-1] 1662 1663 a.header.size -= arraySlabHeaderSize 1664 1665 // Store modified slabs in storage 1666 err = storage.Store(child.ID(), child) 1667 if err != nil { 1668 // Wrap err as external error (if needed) because err is returned by SlabStorage interface. 1669 return wrapErrorfAsExternalErrorIfNeeded(err, fmt.Sprintf("failed to store slab %s", child.ID())) 1670 } 1671 err = storage.Store(a.header.id, a) 1672 if err != nil { 1673 // Wrap err as external error (if needed) because err is returned by SlabStorage interface. 1674 return wrapErrorfAsExternalErrorIfNeeded(err, fmt.Sprintf("failed to store slab %s", a.header.id)) 1675 } 1676 1677 // Remove rightSib from storage 1678 err = storage.Remove(rightSib.ID()) 1679 if err != nil { 1680 // Wrap err as external error (if needed) because err is returned by SlabStorage interface. 1681 return wrapErrorfAsExternalErrorIfNeeded(err, fmt.Sprintf("failed to remove slab %s", rightSib.ID())) 1682 } 1683 1684 return nil 1685 } 1686 } 1687 1688 func (a *ArrayMetaDataSlab) Merge(slab Slab) error { 1689 1690 // The assumption len > 0 holds in all cases except for the root slab 1691 1692 baseCountSum := a.childrenCountSum[len(a.childrenCountSum)-1] 1693 leftSlabChildrenCount := len(a.childrenHeaders) 1694 1695 rightSlab := slab.(*ArrayMetaDataSlab) 1696 a.childrenHeaders = append(a.childrenHeaders, rightSlab.childrenHeaders...) 1697 a.header.size += rightSlab.header.size - arrayMetaDataSlabPrefixSize 1698 a.header.count += rightSlab.header.count 1699 1700 // Adjust childrenCountSum 1701 for i := leftSlabChildrenCount; i < len(a.childrenHeaders); i++ { 1702 baseCountSum += a.childrenHeaders[i].count 1703 a.childrenCountSum = append(a.childrenCountSum, baseCountSum) 1704 } 1705 1706 return nil 1707 } 1708 1709 func (a *ArrayMetaDataSlab) Split(storage SlabStorage) (Slab, Slab, error) { 1710 1711 if len(a.childrenHeaders) < 2 { 1712 // Can't split meta slab with less than 2 headers 1713 return nil, nil, NewSlabSplitErrorf("ArrayMetaDataSlab (%s) has less than 2 child headers", a.header.id) 1714 } 1715 1716 leftChildrenCount := int(math.Ceil(float64(len(a.childrenHeaders)) / 2)) 1717 leftSize := leftChildrenCount * arraySlabHeaderSize 1718 1719 leftCount := uint32(0) 1720 for i := 0; i < leftChildrenCount; i++ { 1721 leftCount += a.childrenHeaders[i].count 1722 } 1723 1724 // Construct right slab 1725 sID, err := storage.GenerateStorageID(a.header.id.Address) 1726 if err != nil { 1727 // Wrap err as external error (if needed) because err is returned by SlabStorage interface. 1728 return nil, nil, wrapErrorfAsExternalErrorIfNeeded( 1729 err, 1730 fmt.Sprintf("failed to generate storage ID for address 0x%x", a.header.id.Address)) 1731 } 1732 1733 rightSlab := &ArrayMetaDataSlab{ 1734 header: ArraySlabHeader{ 1735 id: sID, 1736 size: a.header.size - uint32(leftSize), 1737 count: a.header.count - leftCount, 1738 }, 1739 } 1740 1741 rightSlab.childrenHeaders = make([]ArraySlabHeader, len(a.childrenHeaders)-leftChildrenCount) 1742 copy(rightSlab.childrenHeaders, a.childrenHeaders[leftChildrenCount:]) 1743 1744 rightSlab.childrenCountSum = make([]uint32, len(rightSlab.childrenHeaders)) 1745 countSum := uint32(0) 1746 for i := 0; i < len(rightSlab.childrenCountSum); i++ { 1747 countSum += rightSlab.childrenHeaders[i].count 1748 rightSlab.childrenCountSum[i] = countSum 1749 } 1750 1751 // Modify left (original)slab 1752 a.childrenHeaders = a.childrenHeaders[:leftChildrenCount] 1753 a.childrenCountSum = a.childrenCountSum[:leftChildrenCount] 1754 a.header.count = leftCount 1755 a.header.size = arrayMetaDataSlabPrefixSize + uint32(leftSize) 1756 1757 return a, rightSlab, nil 1758 } 1759 1760 func (a *ArrayMetaDataSlab) LendToRight(slab Slab) error { 1761 rightSlab := slab.(*ArrayMetaDataSlab) 1762 1763 childrenHeadersLen := len(a.childrenHeaders) + len(rightSlab.childrenHeaders) 1764 leftChildrenHeadersLen := childrenHeadersLen / 2 1765 rightChildrenHeadersLen := childrenHeadersLen - leftChildrenHeadersLen 1766 1767 // Update right slab childrenHeaders by prepending borrowed children headers 1768 rightChildrenHeaders := make([]ArraySlabHeader, rightChildrenHeadersLen) 1769 n := copy(rightChildrenHeaders, a.childrenHeaders[leftChildrenHeadersLen:]) 1770 copy(rightChildrenHeaders[n:], rightSlab.childrenHeaders) 1771 rightSlab.childrenHeaders = rightChildrenHeaders 1772 1773 // Rebuild right slab childrenCountSum 1774 rightSlab.childrenCountSum = make([]uint32, len(rightSlab.childrenHeaders)) 1775 countSum := uint32(0) 1776 for i := 0; i < len(rightSlab.childrenCountSum); i++ { 1777 countSum += rightSlab.childrenHeaders[i].count 1778 rightSlab.childrenCountSum[i] = countSum 1779 } 1780 1781 // Update right slab header 1782 rightSlab.header.count = 0 1783 for i := 0; i < len(rightSlab.childrenHeaders); i++ { 1784 rightSlab.header.count += rightSlab.childrenHeaders[i].count 1785 } 1786 rightSlab.header.size = arrayMetaDataSlabPrefixSize + uint32(len(rightSlab.childrenHeaders))*arraySlabHeaderSize 1787 1788 // Update left slab (original) 1789 a.childrenHeaders = a.childrenHeaders[:leftChildrenHeadersLen] 1790 a.childrenCountSum = a.childrenCountSum[:leftChildrenHeadersLen] 1791 1792 a.header.count = 0 1793 for i := 0; i < len(a.childrenHeaders); i++ { 1794 a.header.count += a.childrenHeaders[i].count 1795 } 1796 a.header.size = arrayMetaDataSlabPrefixSize + uint32(leftChildrenHeadersLen)*arraySlabHeaderSize 1797 1798 return nil 1799 } 1800 1801 func (a *ArrayMetaDataSlab) BorrowFromRight(slab Slab) error { 1802 originalLeftSlabCountSum := a.header.count 1803 originalLeftSlabHeaderLen := len(a.childrenHeaders) 1804 1805 rightSlab := slab.(*ArrayMetaDataSlab) 1806 1807 childrenHeadersLen := len(a.childrenHeaders) + len(rightSlab.childrenHeaders) 1808 leftSlabHeaderLen := childrenHeadersLen / 2 1809 rightSlabHeaderLen := childrenHeadersLen - leftSlabHeaderLen 1810 1811 // Update left slab (original) 1812 a.childrenHeaders = append(a.childrenHeaders, rightSlab.childrenHeaders[:leftSlabHeaderLen-len(a.childrenHeaders)]...) 1813 1814 countSum := originalLeftSlabCountSum 1815 for i := originalLeftSlabHeaderLen; i < len(a.childrenHeaders); i++ { 1816 countSum += a.childrenHeaders[i].count 1817 a.childrenCountSum = append(a.childrenCountSum, countSum) 1818 } 1819 a.header.count = countSum 1820 a.header.size = arrayMetaDataSlabPrefixSize + uint32(leftSlabHeaderLen)*arraySlabHeaderSize 1821 1822 // Update right slab 1823 rightSlab.childrenHeaders = rightSlab.childrenHeaders[len(rightSlab.childrenHeaders)-rightSlabHeaderLen:] 1824 rightSlab.childrenCountSum = rightSlab.childrenCountSum[:len(rightSlab.childrenHeaders)] 1825 1826 countSum = uint32(0) 1827 for i := 0; i < len(rightSlab.childrenHeaders); i++ { 1828 countSum += rightSlab.childrenHeaders[i].count 1829 rightSlab.childrenCountSum[i] = countSum 1830 } 1831 rightSlab.header.count = countSum 1832 rightSlab.header.size = arrayMetaDataSlabPrefixSize + uint32(rightSlabHeaderLen)*arraySlabHeaderSize 1833 1834 return nil 1835 } 1836 1837 func (a ArrayMetaDataSlab) IsFull() bool { 1838 return a.header.size > uint32(maxThreshold) 1839 } 1840 1841 func (a ArrayMetaDataSlab) IsUnderflow() (uint32, bool) { 1842 if uint32(minThreshold) > a.header.size { 1843 return uint32(minThreshold) - a.header.size, true 1844 } 1845 return 0, false 1846 } 1847 1848 func (a *ArrayMetaDataSlab) CanLendToLeft(size uint32) bool { 1849 n := uint32(math.Ceil(float64(size) / arraySlabHeaderSize)) 1850 return a.header.size-arraySlabHeaderSize*n > uint32(minThreshold) 1851 } 1852 1853 func (a *ArrayMetaDataSlab) CanLendToRight(size uint32) bool { 1854 n := uint32(math.Ceil(float64(size) / arraySlabHeaderSize)) 1855 return a.header.size-arraySlabHeaderSize*n > uint32(minThreshold) 1856 } 1857 1858 func (a ArrayMetaDataSlab) IsData() bool { 1859 return false 1860 } 1861 1862 func (a *ArrayMetaDataSlab) SetID(id StorageID) { 1863 a.header.id = id 1864 } 1865 1866 func (a *ArrayMetaDataSlab) Header() ArraySlabHeader { 1867 return a.header 1868 } 1869 1870 func (a *ArrayMetaDataSlab) ByteSize() uint32 { 1871 return a.header.size 1872 } 1873 1874 func (a *ArrayMetaDataSlab) ID() StorageID { 1875 return a.header.id 1876 } 1877 1878 func (a *ArrayMetaDataSlab) ExtraData() *ArrayExtraData { 1879 return a.extraData 1880 } 1881 1882 func (a *ArrayMetaDataSlab) RemoveExtraData() *ArrayExtraData { 1883 extraData := a.extraData 1884 a.extraData = nil 1885 return extraData 1886 } 1887 1888 func (a *ArrayMetaDataSlab) SetExtraData(extraData *ArrayExtraData) { 1889 a.extraData = extraData 1890 } 1891 1892 func (a *ArrayMetaDataSlab) PopIterate(storage SlabStorage, fn ArrayPopIterationFunc) error { 1893 1894 // Iterate child slabs backwards 1895 for i := len(a.childrenHeaders) - 1; i >= 0; i-- { 1896 1897 childID := a.childrenHeaders[i].id 1898 1899 child, err := getArraySlab(storage, childID) 1900 if err != nil { 1901 // Don't need to wrap error as external error because err is already categorized by getArraySlab(). 1902 return err 1903 } 1904 1905 err = child.PopIterate(storage, fn) 1906 if err != nil { 1907 // Don't need to wrap error as external error because err is already categorized by ArraySlab.PopIterate(). 1908 return err 1909 } 1910 1911 // Remove child slab 1912 err = storage.Remove(childID) 1913 if err != nil { 1914 // Wrap err as external error (if needed) because err is returned by SlabStorage interface. 1915 return wrapErrorfAsExternalErrorIfNeeded(err, fmt.Sprintf("failed to remove slab %s", childID)) 1916 } 1917 } 1918 1919 // All child slabs are removed. 1920 1921 // Reset meta data slab 1922 a.childrenCountSum = nil 1923 a.childrenHeaders = nil 1924 a.header.count = 0 1925 a.header.size = arrayMetaDataSlabPrefixSize 1926 1927 return nil 1928 } 1929 1930 func (a *ArrayMetaDataSlab) String() string { 1931 var elemsStr []string 1932 for _, h := range a.childrenHeaders { 1933 elemsStr = append(elemsStr, fmt.Sprintf("{id:%s size:%d count:%d}", h.id, h.size, h.count)) 1934 } 1935 1936 return fmt.Sprintf("ArrayMetaDataSlab id:%s size:%d count:%d children: [%s]", 1937 a.header.id, 1938 a.header.size, 1939 a.header.count, 1940 strings.Join(elemsStr, " "), 1941 ) 1942 } 1943 1944 func NewArray(storage SlabStorage, address Address, typeInfo TypeInfo) (*Array, error) { 1945 1946 extraData := &ArrayExtraData{TypeInfo: typeInfo} 1947 1948 sID, err := storage.GenerateStorageID(address) 1949 if err != nil { 1950 // Wrap err as external error (if needed) because err is returned by SlabStorage interface. 1951 return nil, wrapErrorfAsExternalErrorIfNeeded( 1952 err, 1953 fmt.Sprintf("failed to generate storage ID for address 0x%x", address)) 1954 } 1955 1956 root := &ArrayDataSlab{ 1957 header: ArraySlabHeader{ 1958 id: sID, 1959 size: arrayRootDataSlabPrefixSize, 1960 }, 1961 extraData: extraData, 1962 } 1963 1964 err = storage.Store(root.header.id, root) 1965 if err != nil { 1966 // Wrap err as external error (if needed) because err is returned by SlabStorage interface. 1967 return nil, wrapErrorfAsExternalErrorIfNeeded(err, fmt.Sprintf("failed to store slab %s", root.header.id)) 1968 } 1969 1970 return &Array{ 1971 Storage: storage, 1972 root: root, 1973 }, nil 1974 } 1975 1976 func NewArrayWithRootID(storage SlabStorage, rootID StorageID) (*Array, error) { 1977 if rootID == StorageIDUndefined { 1978 return nil, NewStorageIDErrorf("cannot create Array from undefined storage id") 1979 } 1980 1981 root, err := getArraySlab(storage, rootID) 1982 if err != nil { 1983 // Don't need to wrap error as external error because err is already categorized by getArraySlab(). 1984 return nil, err 1985 } 1986 1987 extraData := root.ExtraData() 1988 if extraData == nil { 1989 return nil, NewNotValueError(rootID) 1990 } 1991 1992 return &Array{ 1993 Storage: storage, 1994 root: root, 1995 }, nil 1996 } 1997 1998 func (a *Array) Get(i uint64) (Storable, error) { 1999 // Don't need to wrap error as external error because err is already categorized by ArraySlab.Get(). 2000 return a.root.Get(a.Storage, i) 2001 } 2002 2003 func (a *Array) Set(index uint64, value Value) (Storable, error) { 2004 existingStorable, err := a.root.Set(a.Storage, a.Address(), index, value) 2005 if err != nil { 2006 // Don't need to wrap error as external error because err is already categorized by ArraySlab.Set(). 2007 return nil, err 2008 } 2009 2010 if a.root.IsFull() { 2011 err = a.splitRoot() 2012 if err != nil { 2013 // Don't need to wrap error as external error because err is already categorized by Array.splitRoot(). 2014 return nil, err 2015 } 2016 return existingStorable, nil 2017 } 2018 2019 if !a.root.IsData() { 2020 root := a.root.(*ArrayMetaDataSlab) 2021 if len(root.childrenHeaders) == 1 { 2022 err = a.promoteChildAsNewRoot(root.childrenHeaders[0].id) 2023 if err != nil { 2024 // Don't need to wrap error as external error because err is already categorized by Array.promoteChildAsNewRoot(). 2025 return nil, err 2026 } 2027 } 2028 } 2029 2030 return existingStorable, nil 2031 } 2032 2033 func (a *Array) Append(value Value) error { 2034 // Don't need to wrap error as external error because err is already categorized by Array.Insert(). 2035 return a.Insert(a.Count(), value) 2036 } 2037 2038 func (a *Array) Insert(index uint64, value Value) error { 2039 err := a.root.Insert(a.Storage, a.Address(), index, value) 2040 if err != nil { 2041 // Don't need to wrap error as external error because err is already categorized by ArraySlab.Insert(). 2042 return err 2043 } 2044 2045 if a.root.IsFull() { 2046 // Don't need to wrap error as external error because err is already categorized by Array.splitRoot(). 2047 return a.splitRoot() 2048 } 2049 2050 return nil 2051 } 2052 2053 func (a *Array) Remove(index uint64) (Storable, error) { 2054 storable, err := a.root.Remove(a.Storage, index) 2055 if err != nil { 2056 // Don't need to wrap error as external error because err is already categorized by ArraySlab.Remove(). 2057 return nil, err 2058 } 2059 2060 if !a.root.IsData() { 2061 // Set root to its child slab if root has one child slab. 2062 root := a.root.(*ArrayMetaDataSlab) 2063 if len(root.childrenHeaders) == 1 { 2064 err = a.promoteChildAsNewRoot(root.childrenHeaders[0].id) 2065 if err != nil { 2066 // Don't need to wrap error as external error because err is already categorized by Array.promoteChildAsNewRoot(). 2067 return nil, err 2068 } 2069 } 2070 } 2071 2072 return storable, nil 2073 } 2074 2075 func (a *Array) splitRoot() error { 2076 2077 if a.root.IsData() { 2078 // Adjust root data slab size before splitting 2079 dataSlab := a.root.(*ArrayDataSlab) 2080 dataSlab.header.size = dataSlab.header.size - arrayRootDataSlabPrefixSize + arrayDataSlabPrefixSize 2081 } 2082 2083 // Get old root's extra data and reset it to nil in old root 2084 extraData := a.root.RemoveExtraData() 2085 2086 // Save root node id 2087 rootID := a.root.ID() 2088 2089 // Assign a new storage id to old root before splitting it. 2090 sID, err := a.Storage.GenerateStorageID(a.Address()) 2091 if err != nil { 2092 // Wrap err as external error (if needed) because err is returned by SlabStorage interface. 2093 return wrapErrorfAsExternalErrorIfNeeded( 2094 err, 2095 fmt.Sprintf("failed to generate storage ID for address 0x%x", a.Address())) 2096 } 2097 2098 oldRoot := a.root 2099 oldRoot.SetID(sID) 2100 2101 // Split old root 2102 leftSlab, rightSlab, err := oldRoot.Split(a.Storage) 2103 if err != nil { 2104 // Don't need to wrap error as external error because err is already categorized by ArraySlab.Split(). 2105 return err 2106 } 2107 2108 left := leftSlab.(ArraySlab) 2109 right := rightSlab.(ArraySlab) 2110 2111 // Create new ArrayMetaDataSlab with the old root's storage ID 2112 newRoot := &ArrayMetaDataSlab{ 2113 header: ArraySlabHeader{ 2114 id: rootID, 2115 count: left.Header().count + right.Header().count, 2116 size: arrayMetaDataSlabPrefixSize + arraySlabHeaderSize*2, 2117 }, 2118 childrenHeaders: []ArraySlabHeader{left.Header(), right.Header()}, 2119 childrenCountSum: []uint32{left.Header().count, left.Header().count + right.Header().count}, 2120 extraData: extraData, 2121 } 2122 2123 a.root = newRoot 2124 2125 err = a.Storage.Store(left.ID(), left) 2126 if err != nil { 2127 // Wrap err as external error (if needed) because err is returned by SlabStorage interface. 2128 return wrapErrorfAsExternalErrorIfNeeded(err, fmt.Sprintf("failed to store slab %s", left.ID())) 2129 } 2130 err = a.Storage.Store(right.ID(), right) 2131 if err != nil { 2132 // Wrap err as external error (if needed) because err is returned by SlabStorage interface. 2133 return wrapErrorfAsExternalErrorIfNeeded(err, fmt.Sprintf("failed to store slab %s", right.ID())) 2134 } 2135 err = a.Storage.Store(a.root.ID(), a.root) 2136 if err != nil { 2137 // Wrap err as external error (if needed) because err is returned by SlabStorage interface. 2138 return wrapErrorfAsExternalErrorIfNeeded(err, fmt.Sprintf("failed to store slab %s", a.root.ID())) 2139 } 2140 2141 return nil 2142 } 2143 2144 func (a *Array) promoteChildAsNewRoot(childID StorageID) error { 2145 2146 child, err := getArraySlab(a.Storage, childID) 2147 if err != nil { 2148 // Don't need to wrap error as external error because err is already categorized by getArraySlab(). 2149 return err 2150 } 2151 2152 if child.IsData() { 2153 // Adjust data slab size before promoting non-root data slab to root 2154 dataSlab := child.(*ArrayDataSlab) 2155 dataSlab.header.size = dataSlab.header.size - arrayDataSlabPrefixSize + arrayRootDataSlabPrefixSize 2156 } 2157 2158 extraData := a.root.RemoveExtraData() 2159 2160 rootID := a.root.ID() 2161 2162 a.root = child 2163 2164 a.root.SetID(rootID) 2165 2166 a.root.SetExtraData(extraData) 2167 2168 err = a.Storage.Store(rootID, a.root) 2169 if err != nil { 2170 // Wrap err as external error (if needed) because err is returned by SlabStorage interface. 2171 return wrapErrorfAsExternalErrorIfNeeded(err, fmt.Sprintf("failed to store slab %s", rootID)) 2172 } 2173 err = a.Storage.Remove(childID) 2174 if err != nil { 2175 // Wrap err as external error (if needed) because err is returned by SlabStorage interface. 2176 return wrapErrorfAsExternalErrorIfNeeded(err, fmt.Sprintf("failed to remove slab %s", childID)) 2177 } 2178 2179 return nil 2180 } 2181 2182 var emptyArrayIterator = &ArrayIterator{} 2183 2184 type ArrayIterator struct { 2185 storage SlabStorage 2186 id StorageID 2187 dataSlab *ArrayDataSlab 2188 index int 2189 remainingCount int 2190 } 2191 2192 func (i *ArrayIterator) Next() (Value, error) { 2193 if i.remainingCount == 0 { 2194 return nil, nil 2195 } 2196 2197 if i.dataSlab == nil { 2198 if i.id == StorageIDUndefined { 2199 return nil, nil 2200 } 2201 2202 slab, found, err := i.storage.Retrieve(i.id) 2203 if err != nil { 2204 // Wrap err as external error (if needed) because err is returned by SlabStorage interface. 2205 return nil, wrapErrorfAsExternalErrorIfNeeded(err, fmt.Sprintf("failed to retrieve slab %s", i.id)) 2206 } 2207 if !found { 2208 return nil, NewSlabNotFoundErrorf(i.id, "slab not found during array iteration") 2209 } 2210 2211 i.dataSlab = slab.(*ArrayDataSlab) 2212 i.index = 0 2213 } 2214 2215 var element Value 2216 var err error 2217 if i.index < len(i.dataSlab.elements) { 2218 element, err = i.dataSlab.elements[i.index].StoredValue(i.storage) 2219 if err != nil { 2220 // Wrap err as external error (if needed) because err is returned by Storable interface. 2221 return nil, wrapErrorfAsExternalErrorIfNeeded(err, "failed to get storable's stored value") 2222 } 2223 2224 i.index++ 2225 } 2226 2227 if i.index >= len(i.dataSlab.elements) { 2228 i.id = i.dataSlab.next 2229 i.dataSlab = nil 2230 } 2231 2232 i.remainingCount-- 2233 2234 return element, nil 2235 } 2236 2237 func (a *Array) Iterator() (*ArrayIterator, error) { 2238 slab, err := firstArrayDataSlab(a.Storage, a.root) 2239 if err != nil { 2240 // Don't need to wrap error as external error because err is already categorized by firstArrayDataSlab(). 2241 return nil, err 2242 } 2243 2244 return &ArrayIterator{ 2245 storage: a.Storage, 2246 id: slab.ID(), 2247 dataSlab: slab, 2248 remainingCount: int(a.Count()), 2249 }, nil 2250 } 2251 2252 func (a *Array) RangeIterator(startIndex uint64, endIndex uint64) (*ArrayIterator, error) { 2253 count := a.Count() 2254 2255 if startIndex > count || endIndex > count { 2256 return nil, NewSliceOutOfBoundsError(startIndex, endIndex, 0, count) 2257 } 2258 2259 if startIndex > endIndex { 2260 return nil, NewInvalidSliceIndexError(startIndex, endIndex) 2261 } 2262 2263 numberOfElements := endIndex - startIndex 2264 2265 if numberOfElements == 0 { 2266 return emptyArrayIterator, nil 2267 } 2268 2269 var dataSlab *ArrayDataSlab 2270 index := startIndex 2271 2272 if a.root.IsData() { 2273 dataSlab = a.root.(*ArrayDataSlab) 2274 } else if startIndex == 0 { 2275 var err error 2276 dataSlab, err = firstArrayDataSlab(a.Storage, a.root) 2277 if err != nil { 2278 // Don't need to wrap error as external error because err is already categorized by firstArrayDataSlab(). 2279 return nil, err 2280 } 2281 } else { 2282 var err error 2283 // getArrayDataSlabWithIndex returns data slab containing element at startIndex, 2284 // getArrayDataSlabWithIndex also returns adjusted index for this element at returned data slab. 2285 // Adjusted index must be used as index when creating ArrayIterator. 2286 dataSlab, index, err = getArrayDataSlabWithIndex(a.Storage, a.root, startIndex) 2287 if err != nil { 2288 // Don't need to wrap error as external error because err is already categorized by getArrayDataSlabWithIndex(). 2289 return nil, err 2290 } 2291 } 2292 2293 return &ArrayIterator{ 2294 storage: a.Storage, 2295 id: dataSlab.ID(), 2296 dataSlab: dataSlab, 2297 index: int(index), 2298 remainingCount: int(numberOfElements), 2299 }, nil 2300 } 2301 2302 type ArrayIterationFunc func(element Value) (resume bool, err error) 2303 2304 func (a *Array) Iterate(fn ArrayIterationFunc) error { 2305 2306 iterator, err := a.Iterator() 2307 if err != nil { 2308 // Don't need to wrap error as external error because err is already categorized by Array.Iterator(). 2309 return err 2310 } 2311 2312 for { 2313 value, err := iterator.Next() 2314 if err != nil { 2315 // Don't need to wrap error as external error because err is already categorized by ArrayIterator.Next(). 2316 return err 2317 } 2318 if value == nil { 2319 return nil 2320 } 2321 resume, err := fn(value) 2322 if err != nil { 2323 // Wrap err as external error (if needed) because err is returned by ArrayIterationFunc callback. 2324 return wrapErrorAsExternalErrorIfNeeded(err) 2325 } 2326 if !resume { 2327 return nil 2328 } 2329 } 2330 } 2331 2332 func (a *Array) IterateRange(startIndex uint64, endIndex uint64, fn ArrayIterationFunc) error { 2333 2334 iterator, err := a.RangeIterator(startIndex, endIndex) 2335 if err != nil { 2336 // Don't need to wrap error as external error because err is already categorized by Array.RangeIterator(). 2337 return err 2338 } 2339 2340 for { 2341 value, err := iterator.Next() 2342 if err != nil { 2343 // Don't need to wrap error as external error because err is already categorized by ArrayIterator.Next(). 2344 return err 2345 } 2346 if value == nil { 2347 return nil 2348 } 2349 resume, err := fn(value) 2350 if err != nil { 2351 // Wrap err as external error (if needed) because err is returned by ArrayIterationFunc callback. 2352 return wrapErrorAsExternalErrorIfNeeded(err) 2353 } 2354 if !resume { 2355 return nil 2356 } 2357 } 2358 } 2359 func (a *Array) Count() uint64 { 2360 return uint64(a.root.Header().count) 2361 } 2362 2363 func (a *Array) StorageID() StorageID { 2364 return a.root.ID() 2365 } 2366 2367 func (a *Array) Type() TypeInfo { 2368 if extraData := a.root.ExtraData(); extraData != nil { 2369 return extraData.TypeInfo 2370 } 2371 return nil 2372 } 2373 2374 func (a *Array) String() string { 2375 iterator, err := a.Iterator() 2376 if err != nil { 2377 return err.Error() 2378 } 2379 2380 var elemsStr []string 2381 for { 2382 v, err := iterator.Next() 2383 if err != nil { 2384 return err.Error() 2385 } 2386 if v == nil { 2387 break 2388 } 2389 elemsStr = append(elemsStr, fmt.Sprintf("%s", v)) 2390 } 2391 2392 return fmt.Sprintf("[%s]", strings.Join(elemsStr, " ")) 2393 } 2394 2395 func getArraySlab(storage SlabStorage, id StorageID) (ArraySlab, error) { 2396 slab, found, err := storage.Retrieve(id) 2397 if err != nil { 2398 // err can be an external error because storage is an interface. 2399 return nil, wrapErrorAsExternalErrorIfNeeded(err) 2400 } 2401 if !found { 2402 return nil, NewSlabNotFoundErrorf(id, "array slab not found") 2403 } 2404 arraySlab, ok := slab.(ArraySlab) 2405 if !ok { 2406 return nil, NewSlabDataErrorf("slab %s isn't ArraySlab", id) 2407 } 2408 return arraySlab, nil 2409 } 2410 2411 func firstArrayDataSlab(storage SlabStorage, slab ArraySlab) (*ArrayDataSlab, error) { 2412 if slab.IsData() { 2413 return slab.(*ArrayDataSlab), nil 2414 } 2415 meta := slab.(*ArrayMetaDataSlab) 2416 firstChildID := meta.childrenHeaders[0].id 2417 firstChild, err := getArraySlab(storage, firstChildID) 2418 if err != nil { 2419 // Don't need to wrap error as external error because err is already categorized by getArraySlab(). 2420 return nil, err 2421 } 2422 // Don't need to wrap error as external error because err is already categorized by firstArrayDataSlab(). 2423 return firstArrayDataSlab(storage, firstChild) 2424 } 2425 2426 // getArrayDataSlabWithIndex returns data slab containing element at specified index 2427 func getArrayDataSlabWithIndex(storage SlabStorage, slab ArraySlab, index uint64) (*ArrayDataSlab, uint64, error) { 2428 if slab.IsData() { 2429 dataSlab := slab.(*ArrayDataSlab) 2430 if index >= uint64(len(dataSlab.elements)) { 2431 return nil, 0, NewIndexOutOfBoundsError(index, 0, uint64(len(dataSlab.elements))) 2432 } 2433 return dataSlab, index, nil 2434 } 2435 2436 metaSlab := slab.(*ArrayMetaDataSlab) 2437 _, adjustedIndex, childID, err := metaSlab.childSlabIndexInfo(index) 2438 if err != nil { 2439 // Don't need to wrap error as external error because err is already categorized by ArrayMetadataSlab.childSlabIndexInfo(). 2440 return nil, 0, err 2441 } 2442 2443 child, err := getArraySlab(storage, childID) 2444 if err != nil { 2445 // Don't need to wrap error as external error because err is already categorized by getArraySlab(). 2446 return nil, 0, err 2447 } 2448 2449 // Don't need to wrap error as external error because err is already categorized by getArrayDataSlabWithIndex(). 2450 return getArrayDataSlabWithIndex(storage, child, adjustedIndex) 2451 } 2452 2453 type ArrayPopIterationFunc func(Storable) 2454 2455 // PopIterate iterates and removes elements backward. 2456 // Each element is passed to ArrayPopIterationFunc callback before removal. 2457 func (a *Array) PopIterate(fn ArrayPopIterationFunc) error { 2458 2459 err := a.root.PopIterate(a.Storage, fn) 2460 if err != nil { 2461 // Don't need to wrap error as external error because err is already categorized by ArraySlab.PopIterate(). 2462 return err 2463 } 2464 2465 rootID := a.root.ID() 2466 2467 extraData := a.root.ExtraData() 2468 2469 // Set root to empty data slab 2470 a.root = &ArrayDataSlab{ 2471 header: ArraySlabHeader{ 2472 id: rootID, 2473 size: arrayRootDataSlabPrefixSize, 2474 }, 2475 extraData: extraData, 2476 } 2477 2478 // Save root slab 2479 err = a.Storage.Store(a.root.ID(), a.root) 2480 if err != nil { 2481 // Wrap err as external error (if needed) because err is returned by SlabStorage interface. 2482 return wrapErrorfAsExternalErrorIfNeeded(err, fmt.Sprintf("failed to store slab %s", a.root.ID())) 2483 } 2484 2485 return nil 2486 } 2487 2488 type ArrayElementProvider func() (Value, error) 2489 2490 func NewArrayFromBatchData(storage SlabStorage, address Address, typeInfo TypeInfo, fn ArrayElementProvider) (*Array, error) { 2491 2492 var slabs []ArraySlab 2493 2494 id, err := storage.GenerateStorageID(address) 2495 if err != nil { 2496 // Wrap err as external error (if needed) because err is returned by SlabStorage interface. 2497 return nil, wrapErrorfAsExternalErrorIfNeeded( 2498 err, 2499 fmt.Sprintf("failed to generate storage ID for address 0x%x", address)) 2500 } 2501 2502 dataSlab := &ArrayDataSlab{ 2503 header: ArraySlabHeader{ 2504 id: id, 2505 size: arrayDataSlabPrefixSize, 2506 }, 2507 } 2508 2509 // Batch append data by creating a list of ArrayDataSlab 2510 for { 2511 value, err := fn() 2512 if err != nil { 2513 // Wrap err as external error (if needed) because err is returned by ArrayElementProvider callback. 2514 return nil, wrapErrorAsExternalErrorIfNeeded(err) 2515 } 2516 if value == nil { 2517 break 2518 } 2519 2520 // Finalize current data slab without appending new element 2521 if dataSlab.header.size >= uint32(targetThreshold) { 2522 2523 // Generate storge id for next data slab 2524 nextID, err := storage.GenerateStorageID(address) 2525 if err != nil { 2526 // Wrap err as external error (if needed) because err is returned by SlabStorage interface. 2527 return nil, wrapErrorfAsExternalErrorIfNeeded( 2528 err, 2529 fmt.Sprintf("failed to generate storage ID for address 0x%x", address)) 2530 } 2531 2532 // Save next slab's storage id in data slab 2533 dataSlab.next = nextID 2534 2535 // Append data slab to dataSlabs 2536 slabs = append(slabs, dataSlab) 2537 2538 // Create next data slab 2539 dataSlab = &ArrayDataSlab{ 2540 header: ArraySlabHeader{ 2541 id: nextID, 2542 size: arrayDataSlabPrefixSize, 2543 }, 2544 } 2545 2546 } 2547 2548 storable, err := value.Storable(storage, address, MaxInlineArrayElementSize) 2549 if err != nil { 2550 // Wrap err as external error (if needed) because err is returned by Value interface. 2551 return nil, wrapErrorfAsExternalErrorIfNeeded(err, "failed to get value's storable") 2552 } 2553 2554 // Append new element 2555 dataSlab.elements = append(dataSlab.elements, storable) 2556 dataSlab.header.count++ 2557 dataSlab.header.size += storable.ByteSize() 2558 } 2559 2560 // Append last data slab to slabs 2561 slabs = append(slabs, dataSlab) 2562 2563 for len(slabs) > 1 { 2564 2565 lastSlab := slabs[len(slabs)-1] 2566 2567 // Rebalance last slab if needed 2568 if underflowSize, underflow := lastSlab.IsUnderflow(); underflow { 2569 2570 leftSib := slabs[len(slabs)-2] 2571 2572 if leftSib.CanLendToRight(underflowSize) { 2573 2574 // Rebalance with left 2575 err := leftSib.LendToRight(lastSlab) 2576 if err != nil { 2577 // Don't need to wrap error as external error because err is already categorized by ArraySlab.LeftToRight(). 2578 return nil, err 2579 } 2580 2581 } else { 2582 2583 // Merge with left 2584 err := leftSib.Merge(lastSlab) 2585 if err != nil { 2586 // Don't need to wrap error as external error because err is already categorized by ArraySlab.Merge(). 2587 return nil, err 2588 } 2589 2590 // Remove last slab from slabs 2591 slabs[len(slabs)-1] = nil 2592 slabs = slabs[:len(slabs)-1] 2593 } 2594 } 2595 2596 // All slabs are within target size range. 2597 2598 if len(slabs) == 1 { 2599 // This happens when there were exactly two slabs and 2600 // last slab has merged with the first slab. 2601 break 2602 } 2603 2604 // Store all slabs 2605 for _, slab := range slabs { 2606 err = storage.Store(slab.ID(), slab) 2607 if err != nil { 2608 // Wrap err as external error (if needed) because err is returned by SlabStorage interface. 2609 return nil, wrapErrorfAsExternalErrorIfNeeded( 2610 err, 2611 fmt.Sprintf("failed to store slab %s", slab.ID())) 2612 } 2613 } 2614 2615 // Get next level meta slabs 2616 slabs, err = nextLevelArraySlabs(storage, address, slabs) 2617 if err != nil { 2618 // Don't need to wrap error as external error because err is already categorized by nextLevelArraySlabs(). 2619 return nil, err 2620 } 2621 2622 } 2623 2624 // found root slab 2625 root := slabs[0] 2626 2627 // root is data slab, adjust its size 2628 if dataSlab, ok := root.(*ArrayDataSlab); ok { 2629 dataSlab.header.size = dataSlab.header.size - arrayDataSlabPrefixSize + arrayRootDataSlabPrefixSize 2630 } 2631 2632 extraData := &ArrayExtraData{TypeInfo: typeInfo} 2633 2634 // Set extra data in root 2635 root.SetExtraData(extraData) 2636 2637 // Store root 2638 err = storage.Store(root.ID(), root) 2639 if err != nil { 2640 // Wrap err as external error (if needed) because err is returned by SlabStorage interface. 2641 return nil, wrapErrorfAsExternalErrorIfNeeded(err, fmt.Sprintf("failed to store slab %s", root.ID())) 2642 } 2643 2644 return &Array{ 2645 Storage: storage, 2646 root: root, 2647 }, nil 2648 } 2649 2650 // nextLevelArraySlabs returns next level meta data slabs from slabs. 2651 // slabs must have at least 2 elements. It is reused and returned as next level slabs. 2652 // Caller is responsible for rebalance last slab and storing returned slabs in storage. 2653 func nextLevelArraySlabs(storage SlabStorage, address Address, slabs []ArraySlab) ([]ArraySlab, error) { 2654 2655 maxNumberOfHeadersInMetaSlab := (maxThreshold - arrayMetaDataSlabPrefixSize) / arraySlabHeaderSize 2656 2657 nextLevelSlabsIndex := 0 2658 2659 // Generate storge id 2660 id, err := storage.GenerateStorageID(address) 2661 if err != nil { 2662 // Wrap err as external error (if needed) because err is returned by SlabStorage interface. 2663 return nil, wrapErrorfAsExternalErrorIfNeeded( 2664 err, 2665 fmt.Sprintf("failed to generate storage ID for address 0x%x", address)) 2666 } 2667 2668 metaSlab := &ArrayMetaDataSlab{ 2669 header: ArraySlabHeader{ 2670 id: id, 2671 size: arrayMetaDataSlabPrefixSize, 2672 }, 2673 } 2674 2675 for _, slab := range slabs { 2676 2677 if len(metaSlab.childrenHeaders) == int(maxNumberOfHeadersInMetaSlab) { 2678 2679 slabs[nextLevelSlabsIndex] = metaSlab 2680 nextLevelSlabsIndex++ 2681 2682 // Generate storge id for next meta data slab 2683 id, err = storage.GenerateStorageID(address) 2684 if err != nil { 2685 // Wrap err as external error (if needed) because err is returned by SlabStorage interface. 2686 return nil, wrapErrorfAsExternalErrorIfNeeded( 2687 err, 2688 fmt.Sprintf("failed to generate storage ID for address 0x%x", address)) 2689 } 2690 2691 metaSlab = &ArrayMetaDataSlab{ 2692 header: ArraySlabHeader{ 2693 id: id, 2694 size: arrayMetaDataSlabPrefixSize, 2695 }, 2696 } 2697 } 2698 2699 metaSlab.header.size += arraySlabHeaderSize 2700 metaSlab.header.count += slab.Header().count 2701 2702 metaSlab.childrenHeaders = append(metaSlab.childrenHeaders, slab.Header()) 2703 metaSlab.childrenCountSum = append(metaSlab.childrenCountSum, metaSlab.header.count) 2704 } 2705 2706 // Append last meta slab to slabs 2707 slabs[nextLevelSlabsIndex] = metaSlab 2708 nextLevelSlabsIndex++ 2709 2710 return slabs[:nextLevelSlabsIndex], nil 2711 }