Skip to content

Commit

Permalink
Refactor inlining functions
Browse files Browse the repository at this point in the history
  • Loading branch information
fxamacker committed Oct 2, 2023
1 parent 042eb68 commit f17354c
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 67 deletions.
64 changes: 30 additions & 34 deletions array.go
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,8 @@ type ArraySlab interface {

Inlined() bool
Inlinable(maxInlineSize uint64) bool
Inline(SlabStorage) error
Uninline(SlabStorage) error
}

// Array is a heterogeneous variable-size array, storing any type of values
Expand Down Expand Up @@ -906,8 +908,8 @@ func (a *ArrayDataSlab) Inlinable(maxInlineSize uint64) bool {
return uint64(inlinedSize) <= maxInlineSize
}

// inline converts not-inlined ArrayDataSlab to inlined ArrayDataSlab and removes it from storage.
func (a *ArrayDataSlab) inline(storage SlabStorage) error {
// Inline converts not-inlined ArrayDataSlab to inlined ArrayDataSlab and removes it from storage.
func (a *ArrayDataSlab) Inline(storage SlabStorage) error {
if a.inlined {
return NewFatalError(fmt.Errorf("failed to inline ArrayDataSlab %s: it is inlined already", a.header.slabID))
}
Expand All @@ -932,8 +934,8 @@ func (a *ArrayDataSlab) inline(storage SlabStorage) error {
return nil
}

// uninline converts an inlined ArrayDataSlab to uninlined ArrayDataSlab and stores it in storage.
func (a *ArrayDataSlab) uninline(storage SlabStorage) error {
// Uninline converts an inlined ArrayDataSlab to uninlined ArrayDataSlab and stores it in storage.
func (a *ArrayDataSlab) Uninline(storage SlabStorage) error {
if !a.inlined {
return NewFatalError(fmt.Errorf("failed to un-inline ArrayDataSlab %s: it is not inlined", a.header.slabID))
}
Expand Down Expand Up @@ -2584,6 +2586,14 @@ func (a *ArrayMetaDataSlab) Inlinable(_ uint64) bool {
return false
}

func (a *ArrayMetaDataSlab) Inline(_ SlabStorage) error {
return NewFatalError(fmt.Errorf("failed to inline ArrayMetaDataSlab %s: ArrayMetaDataSlab can't be inlined", a.header.slabID))
}

func (a *ArrayMetaDataSlab) Uninline(_ SlabStorage) error {
return NewFatalError(fmt.Errorf("failed to uninline ArrayMetaDataSlab %s: ArrayMetaDataSlab is already unlined", a.header.slabID))
}

func (a *ArrayMetaDataSlab) IsData() bool {
return false
}
Expand Down Expand Up @@ -2872,19 +2882,19 @@ func (a *Array) Set(index uint64, value Value) (Storable, error) {
// This is to prevent potential data loss because the overwritten inlined slab was not in
// storage and any future changes to it would have been lost.
switch s := existingStorable.(type) {
case *ArrayDataSlab:
err = s.uninline(a.Storage)
case ArraySlab:
err = s.Uninline(a.Storage)
if err != nil {
return nil, err
}
existingStorable = SlabIDStorable(s.header.slabID)
existingStorable = SlabIDStorable(s.SlabID())

case *MapDataSlab:
err = s.uninline(a.Storage)
case MapSlab:
err = s.Uninline(a.Storage)
if err != nil {
return nil, err
}
existingStorable = SlabIDStorable(s.header.slabID)
existingStorable = SlabIDStorable(s.SlabID())
}

return existingStorable, nil
Expand Down Expand Up @@ -3002,19 +3012,19 @@ func (a *Array) Remove(index uint64) (Storable, error) {
// This is to prevent potential data loss because the overwritten inlined slab was not in
// storage and any future changes to it would have been lost.
switch s := storable.(type) {
case *ArrayDataSlab:
err = s.uninline(a.Storage)
case ArraySlab:
err = s.Uninline(a.Storage)
if err != nil {
return nil, err
}
storable = SlabIDStorable(s.header.slabID)
storable = SlabIDStorable(s.SlabID())

case *MapDataSlab:
err = s.uninline(a.Storage)
case MapSlab:
err = s.Uninline(a.Storage)
if err != nil {
return nil, err
}
storable = SlabIDStorable(s.header.slabID)
storable = SlabIDStorable(s.SlabID())
}

return storable, nil
Expand Down Expand Up @@ -3189,33 +3199,19 @@ func (a *Array) Storable(_ SlabStorage, _ Address, maxInlineSize uint64) (Storab
// Root slab is inlinable and was NOT inlined.

// Inline root data slab.

// Inlineable root slab must be data slab.
rootDataSlab, ok := a.root.(*ArrayDataSlab)
if !ok {
return nil, NewFatalError(fmt.Errorf("unexpected inlinable array slab type %T", a.root))
}

err := rootDataSlab.inline(a.Storage)
err := a.root.Inline(a.Storage)
if err != nil {
return nil, err
}

return rootDataSlab, nil
return a.root, nil

case !inlinable && inlined:

// Root slab is NOT inlinable and was previously inlined.

// Un-inline root slab.

// Inlined root slab must be data slab.
rootDataSlab, ok := a.root.(*ArrayDataSlab)
if !ok {
return nil, NewFatalError(fmt.Errorf("unexpected inlined array slab type %T", a.root))
}

err := rootDataSlab.uninline(a.Storage)
// Uninline root slab.
err := a.root.Uninline(a.Storage)
if err != nil {
return nil, err
}
Expand Down
61 changes: 28 additions & 33 deletions map.go
Original file line number Diff line number Diff line change
Expand Up @@ -363,6 +363,8 @@ type MapSlab interface {

Inlined() bool
Inlinable(maxInlineSize uint64) bool
Inline(SlabStorage) error
Uninline(SlabStorage) error
}

// OrderedMap is an ordered map of key-value pairs; keys can be any hashable type
Expand Down Expand Up @@ -3061,7 +3063,7 @@ func (m *MapDataSlab) Inlinable(maxInlineSize uint64) bool {
}

// inline converts not-inlined MapDataSlab to inlined MapDataSlab and removes it from storage.
func (m *MapDataSlab) inline(storage SlabStorage) error {
func (m *MapDataSlab) Inline(storage SlabStorage) error {
if m.inlined {
return NewFatalError(fmt.Errorf("failed to inline MapDataSlab %s: it is inlined already", m.header.slabID))
}
Expand All @@ -3085,7 +3087,7 @@ func (m *MapDataSlab) inline(storage SlabStorage) error {
}

// uninline converts an inlined MapDataSlab to uninlined MapDataSlab and stores it in storage.
func (m *MapDataSlab) uninline(storage SlabStorage) error {
func (m *MapDataSlab) Uninline(storage SlabStorage) error {
if !m.inlined {
return NewFatalError(fmt.Errorf("failed to uninline MapDataSlab %s: it is not inlined", m.header.slabID))
}
Expand Down Expand Up @@ -3781,6 +3783,14 @@ func (m *MapMetaDataSlab) Inlinable(_ uint64) bool {
return false
}

func (m *MapMetaDataSlab) Inline(_ SlabStorage) error {
return NewFatalError(fmt.Errorf("failed to inline MapMetaDataSlab %s: MapMetaDataSlab can't be inlined", m.header.slabID))
}

func (m *MapMetaDataSlab) Uninline(_ SlabStorage) error {
return NewFatalError(fmt.Errorf("failed to uninline MapMetaDataSlab %s: MapMetaDataSlab is already unlined", m.header.slabID))
}

func (m *MapMetaDataSlab) StoredValue(storage SlabStorage) (Value, error) {
if m.extraData == nil {
return nil, NewNotValueError(m.SlabID())
Expand Down Expand Up @@ -4810,19 +4820,19 @@ func (m *OrderedMap) Set(comparator ValueComparator, hip HashInputProvider, key
// This is to prevent potential data loss because the overwritten inlined slab was not in
// storage and any future changes to it would have been lost.
switch s := storable.(type) {
case *ArrayDataSlab:
err = s.uninline(m.Storage)
case ArraySlab:
err = s.Uninline(m.Storage)
if err != nil {
return nil, err
}
storable = SlabIDStorable(s.header.slabID)
storable = SlabIDStorable(s.SlabID())

case *MapDataSlab:
err = s.uninline(m.Storage)
case MapSlab:
err = s.Uninline(m.Storage)
if err != nil {
return nil, err
}
storable = SlabIDStorable(s.header.slabID)
storable = SlabIDStorable(s.SlabID())
}

return storable, nil
Expand Down Expand Up @@ -4913,19 +4923,19 @@ func (m *OrderedMap) Remove(comparator ValueComparator, hip HashInputProvider, k
// This is to prevent potential data loss because the overwritten inlined slab was not in
// storage and any future changes to it would have been lost.
switch s := valueStorable.(type) {
case *ArrayDataSlab:
err = s.uninline(m.Storage)
case ArraySlab:
err = s.Uninline(m.Storage)
if err != nil {
return nil, nil, err
}
valueStorable = SlabIDStorable(s.header.slabID)
valueStorable = SlabIDStorable(s.SlabID())

case *MapDataSlab:
err = s.uninline(m.Storage)
case MapSlab:
err = s.Uninline(m.Storage)
if err != nil {
return nil, nil, err
}
valueStorable = SlabIDStorable(s.header.slabID)
valueStorable = SlabIDStorable(s.SlabID())
}

return keyStorable, valueStorable, nil
Expand Down Expand Up @@ -5124,33 +5134,18 @@ func (m *OrderedMap) Storable(_ SlabStorage, _ Address, maxInlineSize uint64) (S
// Root slab is inlinable and was NOT inlined.

// Inline root data slab.

// Inlineable root slab must be data slab.
rootDataSlab, ok := m.root.(*MapDataSlab)
if !ok {
return nil, NewFatalError(fmt.Errorf("unexpected inlinable map slab type %T", m.root))
}

err := rootDataSlab.inline(m.Storage)
err := m.root.Inline(m.Storage)
if err != nil {
return nil, err
}

return rootDataSlab, nil
return m.root, nil

case !inlinable && inlined:

// Root slab is NOT inlinable and was inlined.

// Un-inline root slab.

// Inlined root slab must be data slab.
rootDataSlab, ok := m.root.(*MapDataSlab)
if !ok {
return nil, NewFatalError(fmt.Errorf("unexpected inlined map slab type %T", m.root))
}

err := rootDataSlab.uninline(m.Storage)
// Uninline root slab.
err := m.root.Uninline(m.Storage)
if err != nil {
return nil, err
}
Expand Down

0 comments on commit f17354c

Please sign in to comment.