github.com/onflow/atree@v0.6.0/storable_slab.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 // StorableSlab allows storing storables (CBOR encoded data) directly in a slab. 22 // Eventually we will only have a dictionary at the account storage root, 23 // so this won't be needed, but during the refactor we have the need to store 24 // other non-dictionary values (e.g. strings, integers, etc.) directly in accounts 25 // (i.e. directly in slabs aka registers) 26 type StorableSlab struct { 27 StorageID StorageID 28 Storable Storable 29 } 30 31 var _ Slab = StorableSlab{} 32 33 func (s StorableSlab) ChildStorables() []Storable { 34 return []Storable{s.Storable} 35 } 36 37 func (s StorableSlab) Encode(enc *Encoder) error { 38 // Encode version 39 enc.Scratch[0] = 0 40 41 // Encode flag 42 flag := maskStorable 43 flag = setNoSizeLimit(flag) 44 45 if _, ok := s.Storable.(StorageIDStorable); ok { 46 flag = setHasPointers(flag) 47 } 48 49 enc.Scratch[1] = flag 50 51 _, err := enc.Write(enc.Scratch[:versionAndFlagSize]) 52 if err != nil { 53 return NewEncodingError(err) 54 } 55 56 err = s.Storable.Encode(enc) 57 if err != nil { 58 // Wrap err as external error (if needed) because err is returned by Storable interface. 59 return wrapErrorfAsExternalErrorIfNeeded(err, "failed to encode storable") 60 } 61 62 return nil 63 } 64 65 func (s StorableSlab) ByteSize() uint32 { 66 return versionAndFlagSize + s.Storable.ByteSize() 67 } 68 69 func (s StorableSlab) ID() StorageID { 70 return s.StorageID 71 } 72 73 func (s StorableSlab) StoredValue(storage SlabStorage) (Value, error) { 74 value, err := s.Storable.StoredValue(storage) 75 if err != nil { 76 // Wrap err as external error (if needed) because err is returned by Storable interface. 77 return nil, wrapErrorfAsExternalErrorIfNeeded(err, "failed to get storable's stored value") 78 } 79 return value, nil 80 } 81 82 func (StorableSlab) Split(_ SlabStorage) (Slab, Slab, error) { 83 return nil, nil, NewNotApplicableError("StorableSlab", "Slab", "Split") 84 } 85 86 func (StorableSlab) Merge(_ Slab) error { 87 return NewNotApplicableError("StorableSlab", "Slab", "Merge") 88 } 89 90 func (StorableSlab) LendToRight(_ Slab) error { 91 return NewNotApplicableError("StorableSlab", "Slab", "LendToRight") 92 } 93 94 func (StorableSlab) BorrowFromRight(_ Slab) error { 95 return NewNotApplicableError("StorableSlab", "Slab", "BorrowFromRight") 96 }