github.com/onflow/atree@v0.6.0/basicarray.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  
    25  	"github.com/fxamacker/cbor/v2"
    26  )
    27  
    28  const (
    29  	basicArrayDataSlabPrefixSize = 1 + 8
    30  )
    31  
    32  type BasicArrayDataSlab struct {
    33  	header   ArraySlabHeader
    34  	elements []Storable
    35  }
    36  
    37  func (a *BasicArrayDataSlab) StoredValue(storage SlabStorage) (Value, error) {
    38  	return &BasicArray{storage: storage, root: a}, nil
    39  }
    40  
    41  type BasicArray struct {
    42  	storage SlabStorage
    43  	root    *BasicArrayDataSlab
    44  }
    45  
    46  var _ Value = &BasicArray{}
    47  
    48  func (a *BasicArray) Storable(_ SlabStorage, _ Address, _ uint64) (Storable, error) {
    49  	return a.root, nil
    50  }
    51  
    52  func newBasicArrayDataSlabFromData(
    53  	id StorageID,
    54  	data []byte,
    55  	decMode cbor.DecMode,
    56  	decodeStorable StorableDecoder,
    57  ) (
    58  	*BasicArrayDataSlab,
    59  	error,
    60  ) {
    61  	if len(data) < versionAndFlagSize {
    62  		return nil, NewDecodingErrorf("data is too short for basic array slab")
    63  	}
    64  
    65  	// Check flag
    66  	if getSlabArrayType(data[1]) != slabBasicArray {
    67  		return nil, NewDecodingErrorf(
    68  			"data has invalid flag 0x%x, want 0x%x",
    69  			data[0],
    70  			maskBasicArray,
    71  		)
    72  	}
    73  
    74  	cborDec := decMode.NewByteStreamDecoder(data[2:])
    75  
    76  	elemCount, err := cborDec.DecodeArrayHead()
    77  	if err != nil {
    78  		return nil, NewDecodingError(err)
    79  	}
    80  
    81  	elements := make([]Storable, elemCount)
    82  	for i := 0; i < int(elemCount); i++ {
    83  		storable, err := decodeStorable(cborDec, StorageIDUndefined)
    84  		if err != nil {
    85  			// Wrap err as external error (if needed) because err is returned by StorableDecoder callback.
    86  			return nil, wrapErrorfAsExternalErrorIfNeeded(err, "failed to decode array element")
    87  		}
    88  		elements[i] = storable
    89  	}
    90  
    91  	return &BasicArrayDataSlab{
    92  		header:   ArraySlabHeader{id: id, size: uint32(len(data)), count: uint32(elemCount)},
    93  		elements: elements,
    94  	}, nil
    95  }
    96  
    97  func (a *BasicArrayDataSlab) Encode(enc *Encoder) error {
    98  
    99  	flag := maskBasicArray | maskSlabRoot
   100  
   101  	// Encode flag
   102  	_, err := enc.Write([]byte{0x0, flag})
   103  	if err != nil {
   104  		return NewEncodingError(err)
   105  	}
   106  
   107  	// Encode CBOR array size for 9 bytes
   108  	enc.Scratch[0] = 0x80 | 27
   109  	binary.BigEndian.PutUint64(enc.Scratch[1:], uint64(len(a.elements)))
   110  
   111  	_, err = enc.Write(enc.Scratch[:9])
   112  	if err != nil {
   113  		return NewEncodingError(err)
   114  	}
   115  
   116  	for i := 0; i < len(a.elements); i++ {
   117  		err := a.elements[i].Encode(enc)
   118  		if err != nil {
   119  			// Wrap err as external error (if needed) because err is returned by Storable interface.
   120  			return wrapErrorfAsExternalErrorIfNeeded(err, "failed to encode array element")
   121  		}
   122  	}
   123  	err = enc.CBOR.Flush()
   124  	if err != nil {
   125  		return NewEncodingError(err)
   126  	}
   127  
   128  	return nil
   129  }
   130  
   131  func (a *BasicArrayDataSlab) ChildStorables() []Storable {
   132  	s := make([]Storable, len(a.elements))
   133  	copy(s, a.elements)
   134  	return s
   135  }
   136  
   137  func (a *BasicArrayDataSlab) Get(_ SlabStorage, index uint64) (Storable, error) {
   138  	if index >= uint64(len(a.elements)) {
   139  		return nil, NewIndexOutOfBoundsError(index, 0, uint64(len(a.elements)))
   140  	}
   141  	v := a.elements[index]
   142  	return v, nil
   143  }
   144  
   145  func (a *BasicArrayDataSlab) Set(storage SlabStorage, index uint64, v Storable) error {
   146  	if index >= uint64(len(a.elements)) {
   147  		return NewIndexOutOfBoundsError(index, 0, uint64(len(a.elements)))
   148  	}
   149  
   150  	oldElem := a.elements[index]
   151  
   152  	a.elements[index] = v
   153  
   154  	a.header.size = a.header.size -
   155  		oldElem.ByteSize() +
   156  		v.ByteSize()
   157  
   158  	err := storage.Store(a.header.id, a)
   159  	if err != nil {
   160  		// Wrap err as external error (if needed) because err is returned by SlabStorage interface.
   161  		return wrapErrorfAsExternalErrorIfNeeded(err, fmt.Sprintf("failed to store slab %s", a.header.id))
   162  	}
   163  
   164  	return nil
   165  }
   166  
   167  func (a *BasicArrayDataSlab) Insert(storage SlabStorage, index uint64, v Storable) error {
   168  	if index > uint64(len(a.elements)) {
   169  		return NewIndexOutOfBoundsError(index, 0, uint64(len(a.elements)))
   170  	}
   171  
   172  	if index == uint64(len(a.elements)) {
   173  		a.elements = append(a.elements, v)
   174  	} else {
   175  		a.elements = append(a.elements, nil)
   176  		copy(a.elements[index+1:], a.elements[index:])
   177  		a.elements[index] = v
   178  	}
   179  
   180  	a.header.count++
   181  	a.header.size += v.ByteSize()
   182  
   183  	err := storage.Store(a.header.id, a)
   184  	if err != nil {
   185  		// Wrap err as external error (if needed) because err is returned by SlabStorage interface.
   186  		return wrapErrorfAsExternalErrorIfNeeded(err, fmt.Sprintf("failed to store slab %s", a.header.id))
   187  	}
   188  
   189  	return nil
   190  }
   191  
   192  func (a *BasicArrayDataSlab) Remove(storage SlabStorage, index uint64) (Storable, error) {
   193  	if index >= uint64(len(a.elements)) {
   194  		return nil, NewIndexOutOfBoundsError(index, 0, uint64(len(a.elements)))
   195  	}
   196  
   197  	v := a.elements[index]
   198  
   199  	switch index {
   200  	case 0:
   201  		a.elements = a.elements[1:]
   202  	case uint64(len(a.elements)) - 1:
   203  		a.elements = a.elements[:len(a.elements)-1]
   204  	default:
   205  		copy(a.elements[index:], a.elements[index+1:])
   206  		a.elements = a.elements[:len(a.elements)-1]
   207  	}
   208  
   209  	a.header.count--
   210  	a.header.size -= v.ByteSize()
   211  
   212  	err := storage.Store(a.header.id, a)
   213  	if err != nil {
   214  		// Wrap err as external error (if needed) because err is returned by SlabStorage interface.
   215  		return nil, wrapErrorfAsExternalErrorIfNeeded(err, fmt.Sprintf("failed to store slab %s", a.header.id))
   216  	}
   217  
   218  	return v, nil
   219  }
   220  
   221  func (a *BasicArrayDataSlab) Count() uint64 {
   222  	return uint64(len(a.elements))
   223  }
   224  
   225  func (a *BasicArrayDataSlab) Header() ArraySlabHeader {
   226  	return a.header
   227  }
   228  
   229  func (a *BasicArrayDataSlab) ByteSize() uint32 {
   230  	return a.header.size
   231  }
   232  
   233  func (a *BasicArrayDataSlab) ID() StorageID {
   234  	return a.header.id
   235  }
   236  
   237  func (a *BasicArrayDataSlab) String() string {
   238  	return fmt.Sprintf("%v", a.elements)
   239  }
   240  
   241  func (a *BasicArrayDataSlab) Split(_ SlabStorage) (Slab, Slab, error) {
   242  	return nil, nil, NewNotApplicableError("BasicArrayDataSlab", "Slab", "Split")
   243  }
   244  
   245  func (a *BasicArrayDataSlab) Merge(_ Slab) error {
   246  	return NewNotApplicableError("BasicArrayDataSlab", "Slab", "Merge")
   247  }
   248  
   249  func (a *BasicArrayDataSlab) LendToRight(_ Slab) error {
   250  	return NewNotApplicableError("BasicArrayDataSlab", "Slab", "LendToRight")
   251  }
   252  
   253  func (a *BasicArrayDataSlab) BorrowFromRight(_ Slab) error {
   254  	return NewNotApplicableError("BasicArrayDataSlab", "Slab", "BorrowFromRight")
   255  }
   256  
   257  func NewBasicArray(storage SlabStorage, address Address) (*BasicArray, error) {
   258  	sID, err := storage.GenerateStorageID(address)
   259  	if err != nil {
   260  		// Wrap err as external error (if needed) because err is returned by SlabStorage interface.
   261  		return nil, wrapErrorfAsExternalErrorIfNeeded(err, fmt.Sprintf("failed to generate storage ID for address 0x%x", address))
   262  	}
   263  
   264  	root := &BasicArrayDataSlab{
   265  		header: ArraySlabHeader{
   266  			id:   sID,
   267  			size: basicArrayDataSlabPrefixSize,
   268  		},
   269  	}
   270  
   271  	return &BasicArray{
   272  		storage: storage,
   273  		root:    root,
   274  	}, nil
   275  }
   276  
   277  func (a *BasicArray) StorageID() StorageID {
   278  	return a.root.ID()
   279  }
   280  
   281  func (a *BasicArray) Address() Address {
   282  	return a.StorageID().Address
   283  }
   284  
   285  func NewBasicArrayWithRootID(storage SlabStorage, id StorageID) (*BasicArray, error) {
   286  	if id == StorageIDUndefined {
   287  		return nil, NewStorageIDErrorf("cannot create BasicArray from undefined storage id")
   288  	}
   289  	slab, found, err := storage.Retrieve(id)
   290  	if err != nil {
   291  		// Wrap err as external error (if needed) because err is returned by SlabStorage interface.
   292  		return nil, wrapErrorfAsExternalErrorIfNeeded(err, fmt.Sprintf("failed to retrieve slab %s", id))
   293  	}
   294  	if !found {
   295  		return nil, NewSlabNotFoundErrorf(id, "BasicArray slab not found")
   296  	}
   297  	dataSlab, ok := slab.(*BasicArrayDataSlab)
   298  	if !ok {
   299  		return nil, NewSlabDataErrorf("slab %s isn't BasicArraySlab", id)
   300  	}
   301  	return &BasicArray{storage: storage, root: dataSlab}, nil
   302  }
   303  
   304  func (a *BasicArray) Get(index uint64) (Value, error) {
   305  	storable, err := a.root.Get(a.storage, index)
   306  	if err != nil {
   307  		// Don't need to wrap error as external error because err is already categorized by BasicArrayDataSlab.Get().
   308  		return nil, err
   309  	}
   310  	value, err := storable.StoredValue(a.storage)
   311  	if err != nil {
   312  		// Wrap err as external error (if needed) because err is returned by Storable interface.
   313  		return nil, wrapErrorfAsExternalErrorIfNeeded(err, "failed to get storable's stored value")
   314  	}
   315  	return value, nil
   316  }
   317  
   318  func (a *BasicArray) Set(index uint64, v Value) error {
   319  	storable, err := v.Storable(a.storage, a.Address(), MaxInlineArrayElementSize)
   320  	if err != nil {
   321  		// Wrap err as external error (if needed) because err is returned by Value interface.
   322  		return wrapErrorfAsExternalErrorIfNeeded(err, "failed to get value's storable")
   323  	}
   324  	// Don't need to wrap error as external error because err is already categorized by BasicArrayDataSlab.Set().
   325  	return a.root.Set(a.storage, index, storable)
   326  }
   327  
   328  func (a *BasicArray) Append(v Value) error {
   329  	index := uint64(a.root.header.count)
   330  	// Don't need to wrap error as external error because err is already categorized by BasicArray.Insert().
   331  	return a.Insert(index, v)
   332  }
   333  
   334  func (a *BasicArray) Insert(index uint64, v Value) error {
   335  	storable, err := v.Storable(a.storage, a.Address(), MaxInlineArrayElementSize)
   336  	if err != nil {
   337  		// Wrap err as external error (if needed) because err is returned by Value interface.
   338  		return wrapErrorfAsExternalErrorIfNeeded(err, "failed to get value's storable")
   339  	}
   340  	// Don't need to wrap error as external error because err is already categorized by BasicArrayDataSlab.Insert().
   341  	return a.root.Insert(a.storage, index, storable)
   342  }
   343  
   344  func (a *BasicArray) Remove(index uint64) (Value, error) {
   345  	storable, err := a.root.Remove(a.storage, index)
   346  	if err != nil {
   347  		// Don't need to wrap error as external error because err is already categorized by BasicArrayDataSlab.Remove().
   348  		return nil, err
   349  	}
   350  	value, err := storable.StoredValue(a.storage)
   351  	if err != nil {
   352  		// Wrap err as external error (if needed) because err is returned by Storable interface.
   353  		return nil, wrapErrorfAsExternalErrorIfNeeded(err, "failed to get storable's stored value")
   354  	}
   355  	return value, nil
   356  }
   357  
   358  func (a *BasicArray) Count() uint64 {
   359  	return a.root.Count()
   360  }
   361  
   362  func (a *BasicArray) String() string {
   363  	return a.root.String()
   364  }