Skip to content

Commit

Permalink
Merge pull request #478 from onflow/fxamacker/export-slab-id-length
Browse files Browse the repository at this point in the history
Rename and export `SlabIDLength` and related constants
  • Loading branch information
fxamacker authored Jan 28, 2025
2 parents 3c2924c + 2abb5c7 commit 5101cce
Show file tree
Hide file tree
Showing 10 changed files with 115 additions and 112 deletions.
31 changes: 14 additions & 17 deletions array.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,28 +32,25 @@ import (
// NOTE: we use encoding size (in bytes) instead of Go type size for slab operations,
// such as merge and split, so size constants here are related to encoding size.
const (
slabAddressSize = 8
slabIndexSize = 8
slabIDSize = slabAddressSize + slabIndexSize

// version and flag size: version (1 byte) + flag (1 byte)
versionAndFlagSize = 2

// slab header size: slab index (8 bytes) + count (4 bytes) + size (2 bytes)
// Support up to 4,294,967,295 elements in each array.
// Support up to 65,535 bytes for slab size limit (default limit is 1536 max bytes).
arraySlabHeaderSize = slabIndexSize + 4 + 2
arraySlabHeaderSize = SlabIndexLength + 4 + 2

// meta data slab prefix size: version (1 byte) + flag (1 byte) + address (8 bytes) + child header count (2 bytes)
// Support up to 65,535 children per metadata slab.
arrayMetaDataSlabPrefixSize = versionAndFlagSize + slabAddressSize + 2
arrayMetaDataSlabPrefixSize = versionAndFlagSize + SlabAddressLength + 2

// Encoded element head in array data slab (fixed-size for easy computation).
arrayDataSlabElementHeadSize = 3

// non-root data slab prefix size: version (1 byte) + flag (1 byte) + next id (16 bytes) + element array head (3 bytes)
// Support up to 65,535 elements in the array per data slab.
arrayDataSlabPrefixSize = versionAndFlagSize + slabIDSize + arrayDataSlabElementHeadSize
arrayDataSlabPrefixSize = versionAndFlagSize + SlabIDLength + arrayDataSlabElementHeadSize

// root data slab prefix size: version (1 byte) + flag (1 byte) + element array head (3 bytes)
// Support up to 65,535 elements in the array per data slab.
Expand Down Expand Up @@ -420,7 +417,7 @@ func newArrayDataSlabFromDataV0(
var next SlabID
if !h.isRoot() {
// Check data length for next slab ID
if len(data) < slabIDSize {
if len(data) < SlabIDLength {
return nil, NewDecodingErrorf("data is too short for array data slab")
}

Expand All @@ -431,7 +428,7 @@ func newArrayDataSlabFromDataV0(
return nil, err
}

data = data[slabIDSize:]
data = data[SlabIDLength:]
}

// Check data length for array element head
Expand Down Expand Up @@ -539,7 +536,7 @@ func newArrayDataSlabFromDataV1(
return nil, err
}

data = data[slabIDSize:]
data = data[SlabIDLength:]
}

// Check minimum data length after header
Expand Down Expand Up @@ -651,11 +648,11 @@ func DecodeInlinedArrayStorable(
if err != nil {
return nil, NewDecodingError(err)
}
if len(b) != slabIndexSize {
if len(b) != SlabIndexLength {
return nil, NewDecodingError(
fmt.Errorf(
"failed to decode inlined array data slab: expect %d bytes for slab index, got %d bytes",
slabIndexSize,
SlabIndexLength,
len(b)))
}

Expand Down Expand Up @@ -1494,7 +1491,7 @@ func newArrayMetaDataSlabFromDataV0(
arrayMetaDataArrayHeadSizeV0 = 2

// slab header size: slab id (16 bytes) + count (4 bytes) + size (4 bytes)
arraySlabHeaderSizeV0 = slabIDSize + 4 + 4
arraySlabHeaderSizeV0 = SlabIDLength + 4 + 4
)

var err error
Expand Down Expand Up @@ -1547,7 +1544,7 @@ func newArrayMetaDataSlabFromDataV0(
return nil, err
}

countOffset := offset + slabIDSize
countOffset := offset + SlabIDLength
count := binary.BigEndian.Uint32(data[countOffset:])

sizeOffset := countOffset + 4
Expand Down Expand Up @@ -1633,7 +1630,7 @@ func newArrayMetaDataSlabFromDataV1(
// Decode shared address of headers
var address Address
copy(address[:], data[offset:])
offset += slabAddressSize
offset += SlabAddressLength

// Decode number of child headers
const arrayHeaderSize = 2
Expand All @@ -1660,7 +1657,7 @@ func newArrayMetaDataSlabFromDataV1(
copy(index[:], data[offset:])

slabID := SlabID{address, index}
offset += slabIndexSize
offset += SlabIndexLength

// Decode count
count := binary.BigEndian.Uint32(data[offset:])
Expand Down Expand Up @@ -1748,7 +1745,7 @@ func (a *ArrayMetaDataSlab) Encode(enc *Encoder) error {
copy(enc.Scratch[:], a.header.slabID.address[:])

// Encode child header count to scratch
const childHeaderCountOffset = slabAddressSize
const childHeaderCountOffset = SlabAddressLength
binary.BigEndian.PutUint16(
enc.Scratch[childHeaderCountOffset:],
uint16(len(a.childrenHeaders)),
Expand All @@ -1767,7 +1764,7 @@ func (a *ArrayMetaDataSlab) Encode(enc *Encoder) error {
copy(enc.Scratch[:], h.slabID.index[:])

// Encode count
const countOffset = slabIndexSize
const countOffset = SlabIndexLength
binary.BigEndian.PutUint32(enc.Scratch[countOffset:], h.count)

// Encode size
Expand Down
14 changes: 7 additions & 7 deletions array_debug.go
Original file line number Diff line number Diff line change
Expand Up @@ -847,7 +847,7 @@ func computeSize(data []byte) (int, error) {
size -= inlinedSlabExtrDataSize

if !h.isRoot() && isDataSlab && !h.hasNextSlabID() {
size += slabIDSize
size += SlabIDLength
}

return size, nil
Expand Down Expand Up @@ -975,22 +975,22 @@ func verifyArrayValueID(a *Array) error {

vid := a.ValueID()

if !bytes.Equal(vid[:slabAddressSize], rootSlabID.address[:]) {
if !bytes.Equal(vid[:SlabAddressLength], rootSlabID.address[:]) {
return NewFatalError(
fmt.Errorf(
"expect first %d bytes of array value ID as %v, got %v",
slabAddressSize,
SlabAddressLength,
rootSlabID.address[:],
vid[:slabAddressSize]))
vid[:SlabAddressLength]))
}

if !bytes.Equal(vid[slabAddressSize:], rootSlabID.index[:]) {
if !bytes.Equal(vid[SlabAddressLength:], rootSlabID.index[:]) {
return NewFatalError(
fmt.Errorf(
"expect second %d bytes of array value ID as %v, got %v",
slabIndexSize,
SlabIndexLength,
rootSlabID.index[:],
vid[slabAddressSize:]))
vid[SlabAddressLength:]))
}

return nil
Expand Down
62 changes: 31 additions & 31 deletions array_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5027,7 +5027,7 @@ func TestArrayMaxInlineElement(t *testing.T) {
// Size of root data slab with two elements of max inlined size is target slab size minus
// slab id size (next slab id is omitted in root slab), and minus 1 byte
// (for rounding when computing max inline array element size).
require.Equal(t, targetThreshold-slabIDSize-1, uint64(array.root.Header().size))
require.Equal(t, targetThreshold-SlabIDLength-1, uint64(array.root.Header().size))

testArray(t, storage, typeInfo, address, array, values, false)
}
Expand Down Expand Up @@ -6109,8 +6109,8 @@ func TestArrayID(t *testing.T) {
sid := array.SlabID()
id := array.ValueID()

require.Equal(t, sid.address[:], id[:8])
require.Equal(t, sid.index[:], id[8:])
require.Equal(t, sid.address[:], id[:SlabAddressLength])
require.Equal(t, sid.index[:], id[SlabAddressLength:])
}

func TestSlabSizeWhenResettingMutableStorable(t *testing.T) {
Expand Down Expand Up @@ -6202,8 +6202,8 @@ func TestChildArrayInlinabilityInParentArray(t *testing.T) {
require.Equal(t, SlabIDUndefined, childArray.SlabID())

valueID := childArray.ValueID()
require.Equal(t, address[:], valueID[:slabAddressSize])
require.NotEqual(t, SlabIndexUndefined[:], valueID[slabAddressSize:])
require.Equal(t, address[:], valueID[:SlabAddressLength])
require.NotEqual(t, SlabIndexUndefined[:], valueID[SlabAddressLength:])

v := NewStringValue(strings.Repeat("a", 9))
vSize := v.size
Expand Down Expand Up @@ -6329,8 +6329,8 @@ func TestChildArrayInlinabilityInParentArray(t *testing.T) {
require.Equal(t, SlabIDUndefined, childArray.SlabID())

valueID := childArray.ValueID()
require.Equal(t, address[:], valueID[:slabAddressSize])
require.NotEqual(t, SlabIndexUndefined[:], valueID[slabAddressSize:])
require.Equal(t, address[:], valueID[:SlabAddressLength])
require.NotEqual(t, SlabIndexUndefined[:], valueID[SlabAddressLength:])

children[i].array = childArray
children[i].valueID = valueID
Expand Down Expand Up @@ -6529,8 +6529,8 @@ func TestChildArrayInlinabilityInParentArray(t *testing.T) {
require.Equal(t, SlabIDUndefined, childArray.SlabID())

valueID := childArray.ValueID()
require.Equal(t, address[:], valueID[:slabAddressSize])
require.NotEqual(t, SlabIndexUndefined[:], valueID[slabAddressSize:])
require.Equal(t, address[:], valueID[:SlabAddressLength])
require.NotEqual(t, SlabIndexUndefined[:], valueID[SlabAddressLength:])

children[i].array = childArray
children[i].valueID = valueID
Expand Down Expand Up @@ -6722,8 +6722,8 @@ func TestNestedThreeLevelChildArrayInlinabilityInParentArray(t *testing.T) {
require.Equal(t, SlabIDUndefined, childArray.SlabID())

valueID := childArray.ValueID()
require.Equal(t, address[:], valueID[:slabAddressSize])
require.NotEqual(t, SlabIndexUndefined[:], valueID[slabAddressSize:])
require.Equal(t, address[:], valueID[:SlabAddressLength])
require.NotEqual(t, SlabIndexUndefined[:], valueID[SlabAddressLength:])

// Get inlined grand child array
e, err = childArray.Get(0)
Expand All @@ -6736,9 +6736,9 @@ func TestNestedThreeLevelChildArrayInlinabilityInParentArray(t *testing.T) {
require.Equal(t, SlabIDUndefined, gchildArray.SlabID())

gValueID := gchildArray.ValueID()
require.Equal(t, address[:], gValueID[:slabAddressSize])
require.NotEqual(t, SlabIndexUndefined[:], gValueID[slabAddressSize:])
require.NotEqual(t, valueID[slabAddressSize:], gValueID[slabAddressSize:])
require.Equal(t, address[:], gValueID[:SlabAddressLength])
require.NotEqual(t, SlabIndexUndefined[:], gValueID[SlabAddressLength:])
require.NotEqual(t, valueID[SlabAddressLength:], gValueID[SlabAddressLength:])

v := NewStringValue(strings.Repeat("a", 9))
vSize := v.size
Expand Down Expand Up @@ -6917,8 +6917,8 @@ func TestNestedThreeLevelChildArrayInlinabilityInParentArray(t *testing.T) {
require.Equal(t, SlabIDUndefined, childArray.SlabID())

valueID := childArray.ValueID()
require.Equal(t, address[:], valueID[:slabAddressSize])
require.NotEqual(t, SlabIndexUndefined[:], valueID[slabAddressSize:])
require.Equal(t, address[:], valueID[:SlabAddressLength])
require.NotEqual(t, SlabIndexUndefined[:], valueID[SlabAddressLength:])

// Get inlined grand child array
e, err = childArray.Get(0)
Expand All @@ -6931,9 +6931,9 @@ func TestNestedThreeLevelChildArrayInlinabilityInParentArray(t *testing.T) {
require.Equal(t, SlabIDUndefined, gchildArray.SlabID())

gValueID := gchildArray.ValueID()
require.Equal(t, address[:], gValueID[:slabAddressSize])
require.NotEqual(t, SlabIndexUndefined[:], gValueID[slabAddressSize:])
require.NotEqual(t, valueID[slabAddressSize:], gValueID[slabAddressSize:])
require.Equal(t, address[:], gValueID[:SlabAddressLength])
require.NotEqual(t, SlabIndexUndefined[:], gValueID[SlabAddressLength:])
require.NotEqual(t, valueID[SlabAddressLength:], gValueID[SlabAddressLength:])

v := NewStringValue(strings.Repeat("a", 9))
vSize := v.size
Expand Down Expand Up @@ -7150,8 +7150,8 @@ func TestNestedThreeLevelChildArrayInlinabilityInParentArray(t *testing.T) {
require.Equal(t, SlabIDUndefined, childArray.SlabID())

valueID := childArray.ValueID()
require.Equal(t, address[:], valueID[:slabAddressSize])
require.NotEqual(t, SlabIndexUndefined[:], valueID[slabAddressSize:])
require.Equal(t, address[:], valueID[:SlabAddressLength])
require.NotEqual(t, SlabIndexUndefined[:], valueID[SlabAddressLength:])

e, err = childArray.Get(0)
require.NoError(t, err)
Expand All @@ -7163,9 +7163,9 @@ func TestNestedThreeLevelChildArrayInlinabilityInParentArray(t *testing.T) {
require.Equal(t, SlabIDUndefined, gchildArray.SlabID())

gValueID := gchildArray.ValueID()
require.Equal(t, address[:], gValueID[:slabAddressSize])
require.NotEqual(t, SlabIndexUndefined[:], gValueID[slabAddressSize:])
require.NotEqual(t, valueID[slabAddressSize:], gValueID[slabAddressSize:])
require.Equal(t, address[:], gValueID[:SlabAddressLength])
require.NotEqual(t, SlabIndexUndefined[:], gValueID[SlabAddressLength:])
require.NotEqual(t, valueID[SlabAddressLength:], gValueID[SlabAddressLength:])

children[i] = arrayInfo{
array: childArray,
Expand Down Expand Up @@ -7446,8 +7446,8 @@ func TestNestedThreeLevelChildArrayInlinabilityInParentArray(t *testing.T) {
require.Equal(t, SlabIDUndefined, childArray.SlabID())

valueID := childArray.ValueID()
require.Equal(t, address[:], valueID[:slabAddressSize])
require.NotEqual(t, SlabIndexUndefined[:], valueID[slabAddressSize:])
require.Equal(t, address[:], valueID[:SlabAddressLength])
require.NotEqual(t, SlabIndexUndefined[:], valueID[SlabAddressLength:])

e, err = childArray.Get(0)
require.NoError(t, err)
Expand All @@ -7459,9 +7459,9 @@ func TestNestedThreeLevelChildArrayInlinabilityInParentArray(t *testing.T) {
require.Equal(t, SlabIDUndefined, gchildArray.SlabID())

gValueID := gchildArray.ValueID()
require.Equal(t, address[:], gValueID[:slabAddressSize])
require.NotEqual(t, SlabIndexUndefined[:], gValueID[slabAddressSize:])
require.NotEqual(t, valueID[slabAddressSize:], gValueID[slabAddressSize:])
require.Equal(t, address[:], gValueID[:SlabAddressLength])
require.NotEqual(t, SlabIndexUndefined[:], gValueID[SlabAddressLength:])
require.NotEqual(t, valueID[SlabAddressLength:], gValueID[SlabAddressLength:])

children[i] = arrayInfo{
array: childArray,
Expand Down Expand Up @@ -7779,8 +7779,8 @@ func TestChildArrayWhenParentArrayIsModified(t *testing.T) {
require.Equal(t, SlabIDUndefined, childArray.SlabID())

valueID := childArray.ValueID()
require.Equal(t, address[:], valueID[:slabAddressSize])
require.NotEqual(t, SlabIndexUndefined[:], valueID[slabAddressSize:])
require.Equal(t, address[:], valueID[:SlabAddressLength])
require.NotEqual(t, SlabIndexUndefined[:], valueID[SlabAddressLength:])

children[i] = &struct {
array *Array
Expand Down
Loading

0 comments on commit 5101cce

Please sign in to comment.