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 }