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  }