diff --git a/array_test.go b/array_test.go index 9a57e89..e4a15cd 100644 --- a/array_test.go +++ b/array_test.go @@ -6171,11 +6171,7 @@ func TestSlabSizeWhenResettingMutableStorable(t *testing.T) { require.True(t, IsArrayRootDataSlab(array)) - storableByteSizes := make([]uint32, arrayCount) - for i := 0; i < arrayCount; i++ { - storableByteSizes[i] = initialStorableSize - } - expectedArrayRootDataSlabSize := ComputeArrayRootDataSlabByteSize(storableByteSizes) + expectedArrayRootDataSlabSize := ComputeArrayRootDataSlabByteSizeWithFixSizedElement(initialStorableSize, arrayCount) require.Equal(t, expectedArrayRootDataSlabSize, GetArrayRootSlabByteSize(array)) err = VerifyArray(array, address, typeInfo, typeInfoComparator, hashInputProvider, true) @@ -6192,10 +6188,7 @@ func TestSlabSizeWhenResettingMutableStorable(t *testing.T) { require.True(t, IsArrayRootDataSlab(array)) - for i := 0; i < arrayCount; i++ { - storableByteSizes[i] = mutatedStorableSize - } - expectedArrayRootDataSlabSize = ComputeArrayRootDataSlabByteSize(storableByteSizes) + expectedArrayRootDataSlabSize = ComputeArrayRootDataSlabByteSizeWithFixSizedElement(mutatedStorableSize, arrayCount) require.Equal(t, expectedArrayRootDataSlabSize, GetArrayRootSlabByteSize(array)) err = VerifyArray(array, address, typeInfo, typeInfoComparator, hashInputProvider, true) @@ -6223,12 +6216,8 @@ func TestChildArrayInlinabilityInParentArray(t *testing.T) { require.Equal(t, 1, getStoredDeltas(storage)) // There is only 1 stored slab because child array is inlined. // Test parent slab size with 1 empty inlined child arrays - childArraySize := ComputeInlinedArraySlabByteSize(nil) - storableByteSizes := make([]uint32, arrayCount) - for i := 0; i < arrayCount; i++ { - storableByteSizes[i] = childArraySize - } - expectedParentSize := ComputeArrayRootDataSlabByteSize(storableByteSizes) + childArraySize := emptyInlinedArrayByteSize + expectedParentSize := ComputeArrayRootDataSlabByteSizeWithFixSizedElement(childArraySize, arrayCount) require.Equal(t, expectedParentSize, GetArrayRootSlabByteSize(parentArray)) testArray(t, storage, typeInfo, address, parentArray, expectedValues, true) @@ -6268,11 +6257,7 @@ func TestChildArrayInlinabilityInParentArray(t *testing.T) { require.Equal(t, valueID, childArray.ValueID()) // Value ID is unchanged // Test inlined child slab size - childStorableByteSizes := make([]uint32, int(childArray.Count())) - for i := 0; i < int(childArray.Count()); i++ { - childStorableByteSizes[i] = vSize - } - expectedInlinedSize := ComputeInlinedArraySlabByteSize(childStorableByteSizes) + expectedInlinedSize := ComputeInlinedArraySlabByteSizeWithFixSizedElement(vSize, int(childArray.Count())) require.Equal(t, expectedInlinedSize, GetArrayRootSlabByteSize(childArray)) // Test parent slab size @@ -6299,14 +6284,10 @@ func TestChildArrayInlinabilityInParentArray(t *testing.T) { require.Equal(t, expectedSlabID, childArray.SlabID()) // Storage ID is the same bytewise as value ID. require.Equal(t, valueID, childArray.ValueID()) // Value ID is unchanged - storableByteSizes = make([]uint32, childArray.Count()) - for i := 0; i < int(childArray.Count()); i++ { - storableByteSizes[i] = vSize - } - expectedStandaloneSlabSize := ComputeArrayRootDataSlabByteSize(storableByteSizes) + expectedStandaloneSlabSize := ComputeArrayRootDataSlabByteSizeWithFixSizedElement(vSize, int(childArray.Count())) require.Equal(t, expectedStandaloneSlabSize, GetArrayRootSlabByteSize(childArray)) - expectedParentSize = ComputeArrayRootDataSlabByteSize([]uint32{SlabIDStorable{}.ByteSize()}) + expectedParentSize = ComputeArrayRootDataSlabByteSize([]uint32{slabIDStorableByteSize}) require.Equal(t, expectedParentSize, GetArrayRootSlabByteSize(parentArray)) // Test parent array's mutableElementIndex @@ -6328,11 +6309,7 @@ func TestChildArrayInlinabilityInParentArray(t *testing.T) { require.Equal(t, SlabIDUndefined, childArray.SlabID()) require.Equal(t, valueID, childArray.ValueID()) // value ID is unchanged - childStorableByteSizes := make([]uint32, childArray.Count()) - for i := 0; i < int(childArray.Count()); i++ { - childStorableByteSizes[i] = vSize - } - expectedInlinedSize := ComputeInlinedArraySlabByteSize(childStorableByteSizes) + expectedInlinedSize := ComputeInlinedArraySlabByteSizeWithFixSizedElement(vSize, int(childArray.Count())) require.Equal(t, expectedInlinedSize, GetArrayRootSlabByteSize(childArray)) expectedParentSize := ComputeArrayRootDataSlabByteSize([]uint32{expectedInlinedSize}) @@ -6362,7 +6339,7 @@ func TestChildArrayInlinabilityInParentArray(t *testing.T) { require.Equal(t, 1, getStoredDeltas(storage)) // There is only 1 stored slab because child array is inlined. // Test parent slab size with 2 empty inlined child arrays - childArrayByteSize := ComputeInlinedArraySlabByteSize(nil) + childArrayByteSize := emptyInlinedArrayByteSize storableByteSizes := make([]uint32, arrayCount) for i := 0; i < arrayCount; i++ { storableByteSizes[i] = childArrayByteSize @@ -6423,11 +6400,7 @@ func TestChildArrayInlinabilityInParentArray(t *testing.T) { require.Equal(t, childValueID, childArray.ValueID()) // Value ID is unchanged // Test inlined child slab size - childStorableByteSizes := make([]uint32, int(childArray.Count())) - for i := 0; i < int(childArray.Count()); i++ { - childStorableByteSizes[i] = vSize - } - expectedInlinedSize := ComputeInlinedArraySlabByteSize(childStorableByteSizes) + expectedInlinedSize := ComputeInlinedArraySlabByteSizeWithFixSizedElement(vSize, int(childArray.Count())) require.Equal(t, expectedInlinedSize, GetArrayRootSlabByteSize(childArray)) // Test parent slab size @@ -6465,14 +6438,10 @@ func TestChildArrayInlinabilityInParentArray(t *testing.T) { require.Equal(t, expectedSlabID, childArray.SlabID()) // Storage ID is the same bytewise as value ID. require.Equal(t, childValueID, childArray.ValueID()) // Value ID is unchanged - childStorableByteSizes := make([]uint32, childArray.Count()) - for i := 0; i < int(childArray.Count()); i++ { - childStorableByteSizes[i] = vSize - } - expectedStandaloneSlabSize := ComputeArrayRootDataSlabByteSize(childStorableByteSizes) + expectedStandaloneSlabSize := ComputeArrayRootDataSlabByteSizeWithFixSizedElement(vSize, int(childArray.Count())) require.Equal(t, expectedStandaloneSlabSize, GetArrayRootSlabByteSize(childArray)) - storableByteSizes[i] = SlabIDStorable{}.ByteSize() + storableByteSizes[i] = slabIDStorableByteSize require.Equal(t, ComputeArrayRootDataSlabByteSize(storableByteSizes), GetArrayRootSlabByteSize(parentArray)) // Test parent array's mutableElementIndex @@ -6504,11 +6473,7 @@ func TestChildArrayInlinabilityInParentArray(t *testing.T) { require.Equal(t, SlabIDUndefined, childArray.SlabID()) require.Equal(t, childValueID, childArray.ValueID()) // value ID is unchanged - childStorableByteSizes := make([]uint32, childArray.Count()) - for i := 0; i < int(childArray.Count()); i++ { - childStorableByteSizes[i] = vSize - } - expectedInlinedSize := ComputeInlinedArraySlabByteSize(childStorableByteSizes) + expectedInlinedSize := ComputeInlinedArraySlabByteSizeWithFixSizedElement(vSize, int(childArray.Count())) require.Equal(t, expectedInlinedSize, GetArrayRootSlabByteSize(childArray)) storableByteSizes[i] = expectedInlinedSize @@ -6542,11 +6507,7 @@ func TestChildArrayInlinabilityInParentArray(t *testing.T) { require.Equal(t, SlabIDUndefined, childArray.SlabID()) require.Equal(t, childValueID, childArray.ValueID()) // value ID is unchanged - childStorableByteSizes := make([]uint32, childArray.Count()) - for i := 0; i < int(childArray.Count()); i++ { - childStorableByteSizes[i] = vSize - } - expectedInlinedSize := ComputeInlinedArraySlabByteSize(childStorableByteSizes) + expectedInlinedSize := ComputeInlinedArraySlabByteSizeWithFixSizedElement(vSize, int(childArray.Count())) require.Equal(t, expectedInlinedSize, GetArrayRootSlabByteSize(childArray)) storableByteSizes[j] = expectedInlinedSize @@ -6580,12 +6541,8 @@ func TestChildArrayInlinabilityInParentArray(t *testing.T) { require.Equal(t, 1, getStoredDeltas(storage)) // There is only 1 stored slab because child array is inlined. // Test parent slab size with 4 empty inlined child arrays - childArrayByteSize := ComputeInlinedArraySlabByteSize(nil) - storableByteSizes := make([]uint32, arrayCount) - for i := 0; i < arrayCount; i++ { - storableByteSizes[i] = childArrayByteSize - } - expectedParentSize := ComputeArrayRootDataSlabByteSize(storableByteSizes) + childArrayByteSize := emptyInlinedArrayByteSize + expectedParentSize := ComputeArrayRootDataSlabByteSizeWithFixSizedElement(childArrayByteSize, arrayCount) require.Equal(t, expectedParentSize, GetArrayRootSlabByteSize(parentArray)) // Test parent array's mutableElementIndex @@ -6640,11 +6597,7 @@ func TestChildArrayInlinabilityInParentArray(t *testing.T) { require.Equal(t, childValueID, childArray.ValueID()) // Value ID is unchanged // Test inlined child slab size - childStorableByteSizes := make([]uint32, int(childArray.Count())) - for i := 0; i < int(childArray.Count()); i++ { - childStorableByteSizes[i] = vSize - } - expectedInlinedSize := ComputeInlinedArraySlabByteSize(childStorableByteSizes) + expectedInlinedSize := ComputeInlinedArraySlabByteSizeWithFixSizedElement(vSize, int(childArray.Count())) require.Equal(t, expectedInlinedSize, GetArrayRootSlabByteSize(childArray)) // Test parent array's mutableElementIndex @@ -6678,11 +6631,7 @@ func TestChildArrayInlinabilityInParentArray(t *testing.T) { require.Equal(t, expectedSlabID, childArray.SlabID()) // Storage ID is the same bytewise as value ID. require.Equal(t, childValueID, childArray.ValueID()) // Value ID is unchanged - storableByteSizes := make([]uint32, childArray.Count()) - for i := 0; i < int(childArray.Count()); i++ { - storableByteSizes[i] = vSize - } - expectedStandaloneSlabSize := ComputeArrayRootDataSlabByteSize(storableByteSizes) + expectedStandaloneSlabSize := ComputeArrayRootDataSlabByteSizeWithFixSizedElement(vSize, int(childArray.Count())) require.Equal(t, expectedStandaloneSlabSize, GetArrayRootSlabByteSize(childArray)) // Test parent array's mutableElementIndex @@ -6714,11 +6663,7 @@ func TestChildArrayInlinabilityInParentArray(t *testing.T) { require.Equal(t, SlabIDUndefined, childArray.SlabID()) require.Equal(t, childValueID, childArray.ValueID()) // value ID is unchanged - childStorableByteSizes := make([]uint32, int(childArray.Count())) - for i := 0; i < int(childArray.Count()); i++ { - childStorableByteSizes[i] = vSize - } - expectedInlinedSize := ComputeInlinedArraySlabByteSize(childStorableByteSizes) + expectedInlinedSize := ComputeInlinedArraySlabByteSizeWithFixSizedElement(vSize, int(childArray.Count())) require.Equal(t, expectedInlinedSize, GetArrayRootSlabByteSize(childArray)) // Test parent array's mutableElementIndex @@ -6753,11 +6698,7 @@ func TestChildArrayInlinabilityInParentArray(t *testing.T) { require.Equal(t, SlabIDUndefined, childArray.SlabID()) require.Equal(t, childValueID, childArray.ValueID()) // value ID is unchanged - childStorableByteSizes := make([]uint32, int(childArray.Count())) - for i := 0; i < int(childArray.Count()); i++ { - childStorableByteSizes[i] = vSize - } - expectedInlinedSize := ComputeInlinedArraySlabByteSize(childStorableByteSizes) + expectedInlinedSize := ComputeInlinedArraySlabByteSizeWithFixSizedElement(vSize, int(childArray.Count())) require.Equal(t, expectedInlinedSize, GetArrayRootSlabByteSize(childArray)) // Test parent array's mutableElementIndex @@ -6799,13 +6740,9 @@ func TestNestedThreeLevelChildArrayInlinabilityInParentArray(t *testing.T) { require.Equal(t, 1, getStoredDeltas(storage)) // There is only 1 stored slab because child array is inlined. // Test parent slab size with 1 inlined child array - gchildArrayByteSize := ComputeInlinedArraySlabByteSize(nil) + gchildArrayByteSize := emptyInlinedArrayByteSize childArrayByteSize := ComputeInlinedArraySlabByteSize([]uint32{gchildArrayByteSize}) - storableByteSizes := make([]uint32, arrayCount) - for i := 0; i < arrayCount; i++ { - storableByteSizes[i] = childArrayByteSize - } - expectedParentSize := ComputeArrayRootDataSlabByteSize(storableByteSizes) + expectedParentSize := ComputeArrayRootDataSlabByteSizeWithFixSizedElement(childArrayByteSize, arrayCount) require.Equal(t, expectedParentSize, GetArrayRootSlabByteSize(parentArray)) // Test parent array's mutableElementIndex @@ -6874,11 +6811,7 @@ func TestNestedThreeLevelChildArrayInlinabilityInParentArray(t *testing.T) { // Test inlined grand child slab size - gchildStorableByteSizes := make([]uint32, int(gchildArray.Count())) - for i := 0; i < int(gchildArray.Count()); i++ { - gchildStorableByteSizes[i] = vSize - } - expectedInlinedGrandChildSize := ComputeInlinedArraySlabByteSize(gchildStorableByteSizes) + expectedInlinedGrandChildSize := ComputeInlinedArraySlabByteSizeWithFixSizedElement(vSize, int(gchildArray.Count())) require.Equal(t, expectedInlinedGrandChildSize, GetArrayRootSlabByteSize(gchildArray)) // Test inlined child slab size @@ -6923,17 +6856,13 @@ func TestNestedThreeLevelChildArrayInlinabilityInParentArray(t *testing.T) { require.Equal(t, gValueID, gchildArray.ValueID()) // Value ID is unchanged // Test inlined grand child slab size - gchildStorableByteSizes := make([]uint32, int(gchildArray.Count())) - for i := 0; i < int(gchildArray.Count()); i++ { - gchildStorableByteSizes[i] = vSize - } - expectedInlinedGrandChildSize := ComputeInlinedArraySlabByteSize(gchildStorableByteSizes) + expectedInlinedGrandChildSize := ComputeInlinedArraySlabByteSizeWithFixSizedElement(vSize, int(gchildArray.Count())) require.Equal(t, expectedInlinedGrandChildSize, GetArrayRootSlabByteSize(gchildArray)) expectedStandaloneSlabSize := ComputeArrayRootDataSlabByteSize([]uint32{expectedInlinedGrandChildSize}) require.Equal(t, expectedStandaloneSlabSize, GetArrayRootSlabByteSize(childArray)) - expectedParentSize = ComputeArrayRootDataSlabByteSize([]uint32{SlabIDStorable{}.ByteSize()}) + expectedParentSize = ComputeArrayRootDataSlabByteSize([]uint32{slabIDStorableByteSize}) require.Equal(t, expectedParentSize, GetArrayRootSlabByteSize(parentArray)) // Test array's mutableElementIndex @@ -6970,11 +6899,7 @@ func TestNestedThreeLevelChildArrayInlinabilityInParentArray(t *testing.T) { require.Equal(t, gValueID, gchildArray.ValueID()) // value ID is unchanged // Test inlined grand child slab size - gchildStorableByteSizes := make([]uint32, int(gchildArray.Count())) - for i := 0; i < int(gchildArray.Count()); i++ { - gchildStorableByteSizes[i] = vSize - } - expectedInlinedGrandChildSize := ComputeInlinedArraySlabByteSize(gchildStorableByteSizes) + expectedInlinedGrandChildSize := ComputeInlinedArraySlabByteSizeWithFixSizedElement(vSize, int(gchildArray.Count())) require.Equal(t, expectedInlinedGrandChildSize, GetArrayRootSlabByteSize(gchildArray)) // Test inlined child slab size @@ -7013,13 +6938,9 @@ func TestNestedThreeLevelChildArrayInlinabilityInParentArray(t *testing.T) { require.Equal(t, 1, getStoredDeltas(storage)) // There is only 1 stored slab because child array is inlined. // Test parent slab size with 1 inlined child array - gchildArrayByteSize := ComputeInlinedArraySlabByteSize(nil) + gchildArrayByteSize := emptyInlinedArrayByteSize childArrayByteSize := ComputeInlinedArraySlabByteSize([]uint32{gchildArrayByteSize}) - storableByteSizes := make([]uint32, arrayCount) - for i := 0; i < arrayCount; i++ { - storableByteSizes[i] = childArrayByteSize - } - expectedParentSize := ComputeArrayRootDataSlabByteSize(storableByteSizes) + expectedParentSize := ComputeArrayRootDataSlabByteSizeWithFixSizedElement(childArrayByteSize, arrayCount) require.Equal(t, expectedParentSize, GetArrayRootSlabByteSize(parentArray)) // Test parent array's mutableElementIndex @@ -7087,11 +7008,7 @@ func TestNestedThreeLevelChildArrayInlinabilityInParentArray(t *testing.T) { require.Equal(t, gValueID, gchildArray.ValueID()) // Value ID is unchanged // Test inlined grand child slab size - gchildStorableByteSizes := make([]uint32, int(gchildArray.Count())) - for i := 0; i < int(gchildArray.Count()); i++ { - gchildStorableByteSizes[i] = vSize - } - expectedInlinedGrandChildSize := ComputeInlinedArraySlabByteSize(gchildStorableByteSizes) + expectedInlinedGrandChildSize := ComputeInlinedArraySlabByteSizeWithFixSizedElement(vSize, int(gchildArray.Count())) require.Equal(t, expectedInlinedGrandChildSize, GetArrayRootSlabByteSize(gchildArray)) // Test inlined child slab size @@ -7138,7 +7055,7 @@ func TestNestedThreeLevelChildArrayInlinabilityInParentArray(t *testing.T) { require.Equal(t, gValueID, gchildArray.ValueID()) // Value ID is unchanged // Test inlined grand child slab size - storableByteSizes = make([]uint32, int(gchildArray.Count())) + storableByteSizes := make([]uint32, int(gchildArray.Count())) storableByteSizes[0] = largeValueSize for i := 1; i < int(gchildArray.Count()); i++ { storableByteSizes[i] = vSize @@ -7146,7 +7063,7 @@ func TestNestedThreeLevelChildArrayInlinabilityInParentArray(t *testing.T) { expectedInlinedGrandChildSize := ComputeArrayRootDataSlabByteSize(storableByteSizes) require.Equal(t, expectedInlinedGrandChildSize, GetArrayRootSlabByteSize(gchildArray)) - expectedStandaloneSlabSize := ComputeInlinedArraySlabByteSize([]uint32{SlabIDStorable{}.ByteSize()}) + expectedStandaloneSlabSize := ComputeInlinedArraySlabByteSize([]uint32{slabIDStorableByteSize}) require.Equal(t, expectedStandaloneSlabSize, GetArrayRootSlabByteSize(childArray)) expectedParentSize = ComputeArrayRootDataSlabByteSize([]uint32{expectedStandaloneSlabSize}) @@ -7185,11 +7102,7 @@ func TestNestedThreeLevelChildArrayInlinabilityInParentArray(t *testing.T) { require.Equal(t, gValueID, gchildArray.ValueID()) // value ID is unchanged // Test inlined grand child slab size - gchildStorableByteSizes := make([]uint32, int(gchildArray.Count())) - for i := 0; i < int(gchildArray.Count()); i++ { - gchildStorableByteSizes[i] = vSize - } - expectedInlinedGrandChildSize := ComputeInlinedArraySlabByteSize(gchildStorableByteSizes) + expectedInlinedGrandChildSize := ComputeInlinedArraySlabByteSizeWithFixSizedElement(vSize, int(gchildArray.Count())) require.Equal(t, expectedInlinedGrandChildSize, GetArrayRootSlabByteSize(gchildArray)) // Test inlined child slab size @@ -7259,11 +7172,7 @@ func TestNestedThreeLevelChildArrayInlinabilityInParentArray(t *testing.T) { // Test parent slab size with 1 inlined child array gchildArraySize := ComputeInlinedArraySlabByteSize([]uint32{vSize}) childArraySize := ComputeInlinedArraySlabByteSize([]uint32{gchildArraySize}) - storableByteSizes := make([]uint32, arrayCount) - for i := 0; i < arrayCount; i++ { - storableByteSizes[i] = childArraySize - } - expectedParentSize := ComputeArrayRootDataSlabByteSize(storableByteSizes) + expectedParentSize := ComputeArrayRootDataSlabByteSizeWithFixSizedElement(childArraySize, arrayCount) require.Equal(t, expectedParentSize, GetArrayRootSlabByteSize(parentArray)) // Test parent array's mutableElementIndex @@ -7399,11 +7308,7 @@ func TestNestedThreeLevelChildArrayInlinabilityInParentArray(t *testing.T) { require.Equal(t, gValueID, gchildArray.ValueID()) // Value ID is unchanged // Test inlined grand child slab size - gchildStorableByteSizes := make([]uint32, int(gchildArray.Count())) - for i := 0; i < int(gchildArray.Count()); i++ { - gchildStorableByteSizes[i] = vSize - } - expectedInlinedGrandChildSize := ComputeInlinedArraySlabByteSize(gchildStorableByteSizes) + expectedInlinedGrandChildSize := ComputeInlinedArraySlabByteSizeWithFixSizedElement(vSize, int(gchildArray.Count())) require.Equal(t, expectedInlinedGrandChildSize, GetArrayRootSlabByteSize(gchildArray)) childStorableByteSizes := make([]uint32, int(childArray.Count())) @@ -7424,12 +7329,12 @@ func TestNestedThreeLevelChildArrayInlinabilityInParentArray(t *testing.T) { require.Equal(t, 3, getStoredDeltas(storage)) // There are 3 stored slab because child array is no longer inlined. - expectedParentSize = ComputeArrayRootDataSlabByteSize([]uint32{SlabIDStorable{}.ByteSize(), SlabIDStorable{}.ByteSize()}) + expectedParentSize = ComputeArrayRootDataSlabByteSizeWithFixSizedElement(slabIDStorableByteSize, 2) require.Equal(t, expectedParentSize, GetArrayRootSlabByteSize(parentArray)) // Remove one elements from each child array to trigger child arrays being inlined again. - storableByteSizes = make([]uint32, arrayCount) + storableByteSizes := make([]uint32, arrayCount) for i, child := range children { childArray := child.array @@ -7458,11 +7363,7 @@ func TestNestedThreeLevelChildArrayInlinabilityInParentArray(t *testing.T) { require.Equal(t, gValueID, gchildArray.ValueID()) // Value ID is unchanged // Test inlined grand child slab size - gchildStorableByteSizes := make([]uint32, int(gchildArray.Count())) - for i := 0; i < int(gchildArray.Count()); i++ { - gchildStorableByteSizes[i] = vSize - } - expectedInlinedGrandChildSize := ComputeInlinedArraySlabByteSize(gchildStorableByteSizes) + expectedInlinedGrandChildSize := ComputeInlinedArraySlabByteSizeWithFixSizedElement(vSize, int(gchildArray.Count())) require.Equal(t, expectedInlinedGrandChildSize, GetArrayRootSlabByteSize(gchildArray)) // Test inlined child slab size @@ -7519,11 +7420,7 @@ func TestNestedThreeLevelChildArrayInlinabilityInParentArray(t *testing.T) { require.Equal(t, gValueID, gchildArray.ValueID()) // value ID is unchanged // Test inlined grand child slab size - gchildStorableByteSizes := make([]uint32, int(gchildArray.Count())) - for i := 0; i < int(gchildArray.Count()); i++ { - gchildStorableByteSizes[i] = vSize - } - expectedInlinedGrandChildSize := ComputeInlinedArraySlabByteSize(gchildStorableByteSizes) + expectedInlinedGrandChildSize := ComputeInlinedArraySlabByteSizeWithFixSizedElement(vSize, int(gchildArray.Count())) require.Equal(t, expectedInlinedGrandChildSize, GetArrayRootSlabByteSize(gchildArray)) // Test inlined child slab size @@ -7594,13 +7491,9 @@ func TestNestedThreeLevelChildArrayInlinabilityInParentArray(t *testing.T) { require.True(t, IsArrayRootDataSlab(parentArray)) require.Equal(t, 1, getStoredDeltas(storage)) // There is only 1 stored slab because child array is inlined. - gchildArraySize := ComputeInlinedArraySlabByteSize(nil) + gchildArraySize := emptyInlinedArrayByteSize childArraySize := ComputeInlinedArraySlabByteSize([]uint32{gchildArraySize}) - storableByteSizes := make([]uint32, arrayCount) - for i := 0; i < arrayCount; i++ { - storableByteSizes[i] = childArraySize - } - expectedParentSize := ComputeArrayRootDataSlabByteSize(storableByteSizes) + expectedParentSize := ComputeArrayRootDataSlabByteSizeWithFixSizedElement(childArraySize, arrayCount) require.Equal(t, expectedParentSize, GetArrayRootSlabByteSize(parentArray)) // Test parent array's mutableElementIndex @@ -7685,11 +7578,7 @@ func TestNestedThreeLevelChildArrayInlinabilityInParentArray(t *testing.T) { require.Equal(t, gValueID, gchildArray.ValueID()) // Value ID is unchanged // Test inlined grand child slab size - gchildStorableByteSizes := make([]uint32, int(gchildArray.Count())) - for i := 0; i < int(gchildArray.Count()); i++ { - gchildStorableByteSizes[i] = vSize - } - expectedInlinedGrandChildSize := ComputeInlinedArraySlabByteSize(gchildStorableByteSizes) + expectedInlinedGrandChildSize := ComputeInlinedArraySlabByteSizeWithFixSizedElement(vSize, int(gchildArray.Count())) require.Equal(t, expectedInlinedGrandChildSize, GetArrayRootSlabByteSize(gchildArray)) // Test inlined child slab size @@ -7737,11 +7626,7 @@ func TestNestedThreeLevelChildArrayInlinabilityInParentArray(t *testing.T) { require.Equal(t, gValueID, gchildArray.ValueID()) // Value ID is unchanged // Test inlined grand child slab size - gchildStorableByteSizes := make([]uint32, int(gchildArray.Count())) - for i := 0; i < int(gchildArray.Count()); i++ { - gchildStorableByteSizes[i] = vSize - } - expectedInlinedGrandChildSize := ComputeInlinedArraySlabByteSize(gchildStorableByteSizes) + expectedInlinedGrandChildSize := ComputeInlinedArraySlabByteSizeWithFixSizedElement(vSize, int(gchildArray.Count())) require.Equal(t, expectedInlinedGrandChildSize, GetArrayRootSlabByteSize(gchildArray)) expectedInlinedChildSlabSize := ComputeInlinedArraySlabByteSize([]uint32{expectedInlinedGrandChildSize}) @@ -7794,11 +7679,7 @@ func TestNestedThreeLevelChildArrayInlinabilityInParentArray(t *testing.T) { require.Equal(t, gValueID, gchildArray.ValueID()) // Value ID is unchanged // Test standalone grand child slab size - gchildArrayStorableByteSizes := make([]uint32, int(gchildArray.Count())) - for i := 0; i < int(gchildArray.Count()); i++ { - gchildArrayStorableByteSizes[i] = vSize - } - expectedInlinedGrandChildSize := ComputeInlinedArraySlabByteSize(gchildArrayStorableByteSizes) + expectedInlinedGrandChildSize := ComputeInlinedArraySlabByteSizeWithFixSizedElement(vSize, int(gchildArray.Count())) require.Equal(t, expectedInlinedGrandChildSize, GetArrayRootSlabByteSize(gchildArray)) expectedStandaloneChildSlabSize := ComputeArrayRootDataSlabByteSize([]uint32{expectedInlinedGrandChildSize}) @@ -7849,11 +7730,7 @@ func TestNestedThreeLevelChildArrayInlinabilityInParentArray(t *testing.T) { require.Equal(t, gValueID, gchildArray.ValueID()) // Value ID is unchanged // Test inlined grand child slab size - gchildStorableByteSizes := make([]uint32, int(gchildArray.Count())) - for i := 0; i < int(gchildArray.Count()); i++ { - gchildStorableByteSizes[i] = vSize - } - expectedInlinedGrandChildSize := ComputeInlinedArraySlabByteSize(gchildStorableByteSizes) + expectedInlinedGrandChildSize := ComputeInlinedArraySlabByteSizeWithFixSizedElement(vSize, int(gchildArray.Count())) require.Equal(t, expectedInlinedGrandChildSize, GetArrayRootSlabByteSize(gchildArray)) // Test inlined child slab size @@ -7907,11 +7784,7 @@ func TestNestedThreeLevelChildArrayInlinabilityInParentArray(t *testing.T) { require.Equal(t, gValueID, gchildArray.ValueID()) // value ID is unchanged // Test inlined grand child slab size - gchildStorableByteSizes := make([]uint32, int(gchildArray.Count())) - for i := 0; i < int(gchildArray.Count()); i++ { - gchildStorableByteSizes[i] = vSize - } - expectedInlinedGrandChildSize := ComputeInlinedArraySlabByteSize(gchildStorableByteSizes) + expectedInlinedGrandChildSize := ComputeInlinedArraySlabByteSizeWithFixSizedElement(vSize, int(gchildArray.Count())) require.Equal(t, expectedInlinedGrandChildSize, GetArrayRootSlabByteSize(gchildArray)) // Test inlined child slab size @@ -7934,13 +7807,9 @@ func TestNestedThreeLevelChildArrayInlinabilityInParentArray(t *testing.T) { require.Equal(t, uint64(arrayCount), parentArray.Count()) require.Equal(t, 1, getStoredDeltas(storage)) - gchildArraySize = ComputeInlinedArraySlabByteSize(nil) + gchildArraySize = emptyInlinedArrayByteSize childArraySize = ComputeInlinedArraySlabByteSize([]uint32{gchildArraySize}) - storableByteSizes = make([]uint32, arrayCount) - for i := 0; i < arrayCount; i++ { - storableByteSizes[i] = childArraySize - } - expectedParentSize = ComputeArrayRootDataSlabByteSize(storableByteSizes) + expectedParentSize = ComputeArrayRootDataSlabByteSizeWithFixSizedElement(childArraySize, arrayCount) require.Equal(t, expectedParentSize, GetArrayRootSlabByteSize(parentArray)) }) } @@ -7961,12 +7830,8 @@ func TestChildArrayWhenParentArrayIsModified(t *testing.T) { require.Equal(t, 1, getStoredDeltas(storage)) // There is only 1 stored slab because child array is inlined. // Test parent slab size with empty inlined child arrays - childArraySize := ComputeInlinedArraySlabByteSize(nil) - storableByteSizes := make([]uint32, arrayCount) - for i := 0; i < arrayCount; i++ { - storableByteSizes[i] = childArraySize - } - expectedParentSize := ComputeArrayRootDataSlabByteSize(storableByteSizes) + childArraySize := emptyInlinedArrayByteSize + expectedParentSize := ComputeArrayRootDataSlabByteSizeWithFixSizedElement(childArraySize, arrayCount) require.Equal(t, expectedParentSize, GetArrayRootSlabByteSize(parentArray)) // Test array's mutableElementIndex @@ -8037,11 +7902,7 @@ func TestChildArrayWhenParentArrayIsModified(t *testing.T) { require.Equal(t, childValueID, childArray.ValueID()) // Value ID is unchanged // Test inlined child slab size - childStorableByteSizes := make([]uint32, int(childArray.Count())) - for i := 0; i < int(childArray.Count()); i++ { - childStorableByteSizes[i] = vSize - } - expectedInlinedSize := ComputeInlinedArraySlabByteSize(childStorableByteSizes) + expectedInlinedSize := ComputeInlinedArraySlabByteSizeWithFixSizedElement(vSize, int(childArray.Count())) require.Equal(t, expectedInlinedSize, GetArrayRootSlabByteSize(childArray)) // Test array's mutableElementIndex @@ -8086,11 +7947,7 @@ func TestChildArrayWhenParentArrayIsModified(t *testing.T) { require.Equal(t, childValueID, childArray.ValueID()) // Value ID is unchanged // Test inlined child slab size - childStorableByteSizes := make([]uint32, int(childArray.Count())) - for i := 0; i < int(childArray.Count()); i++ { - childStorableByteSizes[i] = vSize - } - expectedInlinedSize := ComputeInlinedArraySlabByteSize(childStorableByteSizes) + expectedInlinedSize := ComputeInlinedArraySlabByteSizeWithFixSizedElement(vSize, int(childArray.Count())) require.Equal(t, expectedInlinedSize, GetArrayRootSlabByteSize(childArray)) // Test array's mutableElementIndex @@ -8130,11 +7987,7 @@ func TestChildArrayWhenParentArrayIsModified(t *testing.T) { require.Equal(t, childValueID, childArray.ValueID()) // Value ID is unchanged // Test inlined child slab size - childStorableByteSizes := make([]uint32, int(childArray.Count())) - for i := 0; i < int(childArray.Count()); i++ { - childStorableByteSizes[i] = vSize - } - expectedInlinedSize := ComputeInlinedArraySlabByteSize(childStorableByteSizes) + expectedInlinedSize := ComputeInlinedArraySlabByteSizeWithFixSizedElement(vSize, int(childArray.Count())) require.Equal(t, expectedInlinedSize, GetArrayRootSlabByteSize(childArray)) // Test array's mutableElementIndex @@ -8179,11 +8032,7 @@ func TestChildArrayWhenParentArrayIsModified(t *testing.T) { require.Equal(t, childValueID, childArray.ValueID()) // Value ID is unchanged // Test inlined child slab size - childStorableByteSizes := make([]uint32, int(childArray.Count())) - for i := 0; i < int(childArray.Count()); i++ { - childStorableByteSizes[i] = vSize - } - expectedInlinedSize := ComputeInlinedArraySlabByteSize(childStorableByteSizes) + expectedInlinedSize := ComputeInlinedArraySlabByteSizeWithFixSizedElement(vSize, int(childArray.Count())) require.Equal(t, expectedInlinedSize, GetArrayRootSlabByteSize(childArray)) // Test array's mutableElementIndex @@ -8228,11 +8077,7 @@ func TestChildArrayWhenParentArrayIsModified(t *testing.T) { require.Equal(t, childValueID, childArray.ValueID()) // Value ID is unchanged // Test inlined child slab size - childStorableByteSizes := make([]uint32, int(childArray.Count())) - for i := 0; i < int(childArray.Count()); i++ { - childStorableByteSizes[i] = vSize - } - expectedInlinedSize := ComputeInlinedArraySlabByteSize(childStorableByteSizes) + expectedInlinedSize := ComputeInlinedArraySlabByteSizeWithFixSizedElement(vSize, int(childArray.Count())) require.Equal(t, expectedInlinedSize, GetArrayRootSlabByteSize(childArray)) // Test array's mutableElementIndex @@ -8272,11 +8117,7 @@ func TestChildArrayWhenParentArrayIsModified(t *testing.T) { require.Equal(t, childValueID, childArray.ValueID()) // Value ID is unchanged // Test inlined child slab size - childStorableByteSizes := make([]uint32, int(childArray.Count())) - for i := 0; i < int(childArray.Count()); i++ { - childStorableByteSizes[i] = vSize - } - expectedInlinedSize := ComputeInlinedArraySlabByteSize(childStorableByteSizes) + expectedInlinedSize := ComputeInlinedArraySlabByteSizeWithFixSizedElement(vSize, int(childArray.Count())) require.Equal(t, expectedInlinedSize, GetArrayRootSlabByteSize(childArray)) // Test array's mutableElementIndex diff --git a/array_wrappervalue_test.go b/array_wrappervalue_test.go index 9731124..7875a43 100644 --- a/array_wrappervalue_test.go +++ b/array_wrappervalue_test.go @@ -2572,11 +2572,13 @@ func TestArrayWrapperValueModifyNewArrayAtLevel3(t *testing.T) { // Set elements var setCount int - if array.Count() <= 10 { - setCount = int(array.Count()) - } else { - for setCount < int(array.Count())/2 { - setCount = r.Intn(int(array.Count()) + 1) + for setCount == 0 { + if array.Count() <= 10 { + setCount = int(array.Count()) + } else { + for setCount < int(array.Count())/2 { + setCount = r.Intn(int(array.Count()) + 1) + } } } diff --git a/export_test.go b/export_test.go index 791d64b..f513e18 100644 --- a/export_test.go +++ b/export_test.go @@ -31,7 +31,8 @@ var ( // Exported function of slab size settings for testing. var ( - TargetSlabSize = targetSlabSize + TargetSlabSize = targetSlabSize + MaxInlineMapValueSize = maxInlineMapValueSize ) // Exported function of Array for testing. @@ -104,6 +105,14 @@ func GetMutableValueNotifierValueID(v Value) (ValueID, error) { return m.ValueID(), nil } +func ComputeArrayRootDataSlabByteSizeWithFixSizedElement(storableByteSize uint32, count int) uint32 { + storableByteSizes := make([]uint32, count) + for i := 0; i < count; i++ { + storableByteSizes[i] = storableByteSize + } + return ComputeArrayRootDataSlabByteSize(storableByteSizes) +} + func ComputeArrayRootDataSlabByteSize(storableByteSizes []uint32) uint32 { slabSize := uint32(arrayRootDataSlabPrefixSize) for _, storableByteSize := range storableByteSizes { @@ -112,6 +121,14 @@ func ComputeArrayRootDataSlabByteSize(storableByteSizes []uint32) uint32 { return slabSize } +func ComputeInlinedArraySlabByteSizeWithFixSizedElement(storableByteSize uint32, count int) uint32 { + storableByteSizes := make([]uint32, count) + for i := 0; i < count; i++ { + storableByteSizes[i] = storableByteSize + } + return ComputeInlinedArraySlabByteSize(storableByteSizes) +} + func ComputeInlinedArraySlabByteSize(storableByteSizes []uint32) uint32 { slabSize := uint32(inlinedArrayDataSlabPrefixSize) for _, storableByteSize := range storableByteSizes { @@ -119,3 +136,53 @@ func ComputeInlinedArraySlabByteSize(storableByteSizes []uint32) uint32 { } return slabSize } + +func ComputeMapRootDataSlabByteSizeWithFixSizedElement(keyStorableByteSize, valueStorableByteSize uint32, count int) uint32 { + elementStorableByteSizes := make([][2]uint32, count) + for i := 0; i < count; i++ { + elementStorableByteSizes[i] = [2]uint32{keyStorableByteSize, valueStorableByteSize} + } + return ComputeMapRootDataSlabByteSize(elementStorableByteSizes) +} + +func ComputeMapRootDataSlabByteSize(elementStorableByteSizes [][2]uint32) uint32 { + slabSize := uint32(mapRootDataSlabPrefixSize + hkeyElementsPrefixSize) + for _, elementStorableByteSize := range elementStorableByteSizes { + keyStorableByteSize := elementStorableByteSize[0] + valueStorableByteSize := elementStorableByteSize[1] + + elementSize := singleElementPrefixSize + + digestSize + + keyStorableByteSize + + valueStorableByteSize + + slabSize += elementSize + } + + return slabSize +} + +func ComputeInlinedMapSlabByteSizeWithFixSizedElement(keyStorableByteSize, valueStorableByteSize uint32, count int) uint32 { + elementStorableByteSizes := make([][2]uint32, count) + for i := 0; i < count; i++ { + elementStorableByteSizes[i] = [2]uint32{keyStorableByteSize, valueStorableByteSize} + } + return ComputeInlinedMapSlabByteSize(elementStorableByteSizes) +} + +func ComputeInlinedMapSlabByteSize(elementStorableByteSizes [][2]uint32) uint32 { + slabSize := uint32(inlinedMapDataSlabPrefixSize + hkeyElementsPrefixSize) + for _, elementStorableByteSize := range elementStorableByteSizes { + keyStorableByteSize := elementStorableByteSize[0] + valueStorableByteSize := elementStorableByteSize[1] + + elementSize := singleElementPrefixSize + + digestSize + + keyStorableByteSize + + valueStorableByteSize + + slabSize += elementSize + } + + return slabSize +} diff --git a/map_test.go b/map_test.go index 001dcde..3fe1063 100644 --- a/map_test.go +++ b/map_test.go @@ -16704,10 +16704,12 @@ func TestSlabSizeWhenResettingMutableStorableInMap(t *testing.T) { ) keyValues := make(map[Value]*testMutableValue, mapCount) + elementByteSizes := make([][2]uint32, mapCount) for i := 0; i < mapCount; i++ { k := Uint64Value(i) v := newTestMutableValue(initialStorableSize) keyValues[k] = v + elementByteSizes[i] = [2]uint32{k.ByteSize(), initialStorableSize} } typeInfo := testTypeInfo{42} @@ -16725,26 +16727,29 @@ func TestSlabSizeWhenResettingMutableStorableInMap(t *testing.T) { require.True(t, IsMapRootDataSlab(m)) - expectedElementSize := singleElementPrefixSize + digestSize + Uint64Value(0).ByteSize() + initialStorableSize - expectedMapRootDataSlabSize := mapRootDataSlabPrefixSize + hkeyElementsPrefixSize + expectedElementSize*mapCount + expectedMapRootDataSlabSize := ComputeMapRootDataSlabByteSize(elementByteSizes) require.Equal(t, expectedMapRootDataSlabSize, GetMapRootSlabByteSize(m)) err = VerifyMap(m, address, typeInfo, typeInfoComparator, hashInputProvider, true) require.NoError(t, err) // Reset mutable values after changing its storable size + elementByteSizes = elementByteSizes[:0] for k, v := range keyValues { v.updateStorableSize(mutatedStorableSize) existingStorable, err := m.Set(compare, hashInputProvider, k, v) require.NoError(t, err) require.NotNil(t, existingStorable) + + ks, err := k.Storable(storage, address, MaxInlineMapKeySize()) + require.NoError(t, err) + elementByteSizes = append(elementByteSizes, [2]uint32{ks.ByteSize(), mutatedStorableSize}) } require.True(t, IsMapRootDataSlab(m)) - expectedElementSize = singleElementPrefixSize + digestSize + Uint64Value(0).ByteSize() + mutatedStorableSize - expectedMapRootDataSlabSize = mapRootDataSlabPrefixSize + hkeyElementsPrefixSize + expectedElementSize*mapCount + expectedMapRootDataSlabSize = ComputeMapRootDataSlabByteSize(elementByteSizes) require.Equal(t, expectedMapRootDataSlabSize, GetMapRootSlabByteSize(m)) err = VerifyMap(m, address, typeInfo, typeInfoComparator, hashInputProvider, true) @@ -16756,8 +16761,6 @@ func TestChildMapInlinabilityInParentMap(t *testing.T) { SetThreshold(256) defer SetThreshold(1024) - const expectedEmptyInlinedMapSize = uint32(inlinedMapDataSlabPrefixSize + hkeyElementsPrefixSize) // 22 - t.Run("parent is root data slab, with one child map", func(t *testing.T) { const ( mapCount = 1 @@ -16775,7 +16778,7 @@ func TestChildMapInlinabilityInParentMap(t *testing.T) { storage := newTestPersistentStorage(t) address := Address{1, 2, 3, 4, 5, 6, 7, 8} - parentMap, expectedKeyValues := createMapWithEmptyChildMap(t, storage, address, typeInfo, mapCount, func() Value { + parentMap, expectedKeyValues, elementByteSizesByKey := createMapWithEmptyChildMap(t, storage, address, typeInfo, mapCount, func() Value { return NewStringValue(randStr(r, keyStringSize)) }) @@ -16812,15 +16815,20 @@ func TestChildMapInlinabilityInParentMap(t *testing.T) { require.Equal(t, 1, getStoredDeltas(storage)) // Test inlined child slab size - expectedChildElementSize := singleElementPrefixSize + digestSize + encodedKeySize + encodedValueSize - expectedInlinedMapSize := inlinedMapDataSlabPrefixSize + hkeyElementsPrefixSize + - expectedChildElementSize*uint32(childMap.Count()) + expectedInlinedMapSize := ComputeInlinedMapSlabByteSizeWithFixSizedElement( + encodedKeySize, + encodedValueSize, + int(childMap.Count())) require.Equal(t, expectedInlinedMapSize, GetMapRootSlabByteSize(childMap)) // Test parent slab size - expectedParentElementSize := singleElementPrefixSize + digestSize + encodedKeySize + expectedInlinedMapSize - expectedParentSize := uint32(mapRootDataSlabPrefixSize+hkeyElementsPrefixSize) + - expectedParentElementSize*mapCount + elementByteSizesByKey[childKey] = [2]uint32{elementByteSizesByKey[childKey][0], expectedInlinedMapSize} + + elementByteSizes := make([][2]uint32, 0, len(elementByteSizesByKey)) + for _, v := range elementByteSizesByKey { + elementByteSizes = append(elementByteSizes, v) + } + expectedParentSize := ComputeMapRootDataSlabByteSize(elementByteSizes) require.Equal(t, expectedParentSize, GetMapRootSlabByteSize(parentMap)) testMap(t, storage, typeInfo, address, parentMap, expectedKeyValues, nil, true) @@ -16854,14 +16862,23 @@ func TestChildMapInlinabilityInParentMap(t *testing.T) { require.Equal(t, expectedSlabID, childMap.SlabID()) // Storage ID is the same bytewise as value ID. require.Equal(t, valueID, childMap.ValueID()) // Value ID is unchanged - expectedChildElementSize := singleElementPrefixSize + digestSize + encodedKeySize + encodedValueSize - expectedStandaloneSlabSize := uint32(mapRootDataSlabPrefixSize+hkeyElementsPrefixSize) + - expectedChildElementSize*uint32(childMap.Count()) + expectedStandaloneSlabSize := ComputeMapRootDataSlabByteSizeWithFixSizedElement( + encodedKeySize, + encodedValueSize, + int(childMap.Count()), + ) require.Equal(t, expectedStandaloneSlabSize, GetMapRootSlabByteSize(childMap)) - expectedParentElementSize := singleElementPrefixSize + digestSize + encodedKeySize + SlabIDStorable(expectedSlabID).ByteSize() - expectedParentSize := uint32(mapRootDataSlabPrefixSize+hkeyElementsPrefixSize) + - expectedParentElementSize*mapCount + elementByteSizesByKey[childKey] = [2]uint32{ + elementByteSizesByKey[childKey][0], + slabIDStorableByteSize, + } + + elementByteSizes := make([][2]uint32, 0, len(elementByteSizesByKey)) + for _, v := range elementByteSizesByKey { + elementByteSizes = append(elementByteSizes, v) + } + expectedParentSize := ComputeMapRootDataSlabByteSize(elementByteSizes) require.Equal(t, expectedParentSize, GetMapRootSlabByteSize(parentMap)) testMap(t, storage, typeInfo, address, parentMap, expectedKeyValues, nil, true) @@ -16893,14 +16910,19 @@ func TestChildMapInlinabilityInParentMap(t *testing.T) { require.Equal(t, valueID, childMap.ValueID()) // value ID is unchanged require.Equal(t, 1, getStoredDeltas(storage)) - expectedChildElementSize := singleElementPrefixSize + digestSize + encodedKeySize + encodedValueSize - expectedInlinedMapSize := inlinedMapDataSlabPrefixSize + hkeyElementsPrefixSize + - expectedChildElementSize*uint32(childMap.Count()) + expectedInlinedMapSize := ComputeInlinedMapSlabByteSizeWithFixSizedElement( + encodedKeySize, + encodedValueSize, + int(childMap.Count())) require.Equal(t, expectedInlinedMapSize, GetMapRootSlabByteSize(childMap)) - expectedParentElementSize := singleElementPrefixSize + digestSize + encodedKeySize + expectedInlinedMapSize - expectedParentSize := uint32(mapRootDataSlabPrefixSize+hkeyElementsPrefixSize) + - expectedParentElementSize*mapCount + elementByteSizesByKey[childKey] = [2]uint32{elementByteSizesByKey[childKey][0], expectedInlinedMapSize} + + elementByteSizes := make([][2]uint32, 0, len(elementByteSizesByKey)) + for _, v := range elementByteSizesByKey { + elementByteSizes = append(elementByteSizes, v) + } + expectedParentSize := ComputeMapRootDataSlabByteSize(elementByteSizes) require.Equal(t, expectedParentSize, GetMapRootSlabByteSize(parentMap)) testMap(t, storage, typeInfo, address, parentMap, expectedKeyValues, nil, true) @@ -16929,7 +16951,7 @@ func TestChildMapInlinabilityInParentMap(t *testing.T) { storage := newTestPersistentStorage(t) address := Address{1, 2, 3, 4, 5, 6, 7, 8} - parentMap, expectedKeyValues := createMapWithEmptyChildMap(t, storage, address, typeInfo, mapCount, func() Value { + parentMap, expectedKeyValues, elementByteSizesByKey := createMapWithEmptyChildMap(t, storage, address, typeInfo, mapCount, func() Value { return NewStringValue(randStr(r, keyStringSize)) }) @@ -16941,8 +16963,6 @@ func TestChildMapInlinabilityInParentMap(t *testing.T) { children := getInlinedChildMapsFromParentMap(t, address, parentMap) - expectedParentSize := GetMapRootSlabByteSize(parentMap) - // Appending 3 elements to child map so that inlined child map reaches max inlined size as map element. for i := 0; i < 3; i++ { for childKey, child := range children { @@ -16968,13 +16988,23 @@ func TestChildMapInlinabilityInParentMap(t *testing.T) { require.Equal(t, 1, getStoredDeltas(storage)) // Test inlined child slab size - expectedChildElementSize := singleElementPrefixSize + digestSize + encodedKeySize + encodedValueSize - expectedInlinedMapSize := inlinedMapDataSlabPrefixSize + hkeyElementsPrefixSize + - expectedChildElementSize*uint32(childMap.Count()) + expectedInlinedMapSize := ComputeInlinedMapSlabByteSizeWithFixSizedElement( + encodedKeySize, + encodedValueSize, + int(childMap.Count()), + ) require.Equal(t, expectedInlinedMapSize, GetMapRootSlabByteSize(childMap)) // Test parent slab size - expectedParentSize += expectedChildElementSize + elementByteSizesByKey[childKey] = [2]uint32{ + elementByteSizesByKey[childKey][0], + expectedInlinedMapSize} + + elementByteSizes := make([][2]uint32, 0, len(elementByteSizesByKey)) + for _, v := range elementByteSizesByKey { + elementByteSizes = append(elementByteSizes, v) + } + expectedParentSize := ComputeMapRootDataSlabByteSize(elementByteSizes) require.Equal(t, expectedParentSize, GetMapRootSlabByteSize(parentMap)) testMap(t, storage, typeInfo, address, parentMap, expectedKeyValues, nil, true) @@ -17008,16 +17038,23 @@ func TestChildMapInlinabilityInParentMap(t *testing.T) { require.Equal(t, expectedSlabID, childMap.SlabID()) // Storage ID is the same bytewise as value ID. require.Equal(t, valueID, childMap.ValueID()) // Value ID is unchanged - expectedChildElementSize := singleElementPrefixSize + digestSize + encodedKeySize + encodedValueSize - expectedStandaloneSlabSize := uint32(mapRootDataSlabPrefixSize+hkeyElementsPrefixSize) + - expectedChildElementSize*uint32(childMap.Count()) + expectedStandaloneSlabSize := ComputeMapRootDataSlabByteSizeWithFixSizedElement( + encodedKeySize, + encodedValueSize, + int(childMap.Count()), + ) require.Equal(t, expectedStandaloneSlabSize, GetMapRootSlabByteSize(childMap)) - // Subtract inlined child map size from expected parent size - expectedParentSize -= uint32(inlinedMapDataSlabPrefixSize+hkeyElementsPrefixSize) + - expectedChildElementSize*uint32(childMap.Count()-1) - // Add slab id storable size to expected parent size - expectedParentSize += SlabIDStorable(expectedSlabID).ByteSize() + elementByteSizesByKey[childKey] = [2]uint32{ + elementByteSizesByKey[childKey][0], + slabIDStorableByteSize, + } + + elementByteSizes := make([][2]uint32, 0, len(elementByteSizesByKey)) + for _, v := range elementByteSizesByKey { + elementByteSizes = append(elementByteSizes, v) + } + expectedParentSize := ComputeMapRootDataSlabByteSize(elementByteSizes) require.Equal(t, expectedParentSize, GetMapRootSlabByteSize(parentMap)) testMap(t, storage, typeInfo, address, parentMap, expectedKeyValues, nil, true) @@ -17055,15 +17092,23 @@ func TestChildMapInlinabilityInParentMap(t *testing.T) { require.Equal(t, SlabIDUndefined, childMap.SlabID()) require.Equal(t, valueID, childMap.ValueID()) // value ID is unchanged - expectedChildElementSize := singleElementPrefixSize + digestSize + encodedKeySize + encodedValueSize - expectedInlinedMapSize := inlinedMapDataSlabPrefixSize + hkeyElementsPrefixSize + - expectedChildElementSize*uint32(childMap.Count()) + expectedInlinedMapSize := ComputeInlinedMapSlabByteSizeWithFixSizedElement( + encodedKeySize, + encodedValueSize, + int(childMap.Count()), + ) require.Equal(t, expectedInlinedMapSize, GetMapRootSlabByteSize(childMap)) - // Subtract slab id storable size from expected parent size - expectedParentSize -= SlabIDStorable(SlabID{}).ByteSize() - // Add expected inlined child map to expected parent size - expectedParentSize += expectedInlinedMapSize + elementByteSizesByKey[childKey] = [2]uint32{ + elementByteSizesByKey[childKey][0], + expectedInlinedMapSize, + } + + elementByteSizes := make([][2]uint32, 0, len(elementByteSizesByKey)) + for _, v := range elementByteSizesByKey { + elementByteSizes = append(elementByteSizes, v) + } + expectedParentSize := ComputeMapRootDataSlabByteSize(elementByteSizes) require.Equal(t, expectedParentSize, GetMapRootSlabByteSize(parentMap)) testMap(t, storage, typeInfo, address, parentMap, expectedKeyValues, nil, true) @@ -17096,12 +17141,23 @@ func TestChildMapInlinabilityInParentMap(t *testing.T) { require.Equal(t, SlabIDUndefined, childMap.SlabID()) require.Equal(t, valueID, childMap.ValueID()) // value ID is unchanged - expectedChildElementSize := singleElementPrefixSize + digestSize + encodedKeySize + encodedValueSize - expectedInlinedMapSize := inlinedMapDataSlabPrefixSize + hkeyElementsPrefixSize + - expectedChildElementSize*uint32(childMap.Count()) + expectedInlinedMapSize := ComputeInlinedMapSlabByteSizeWithFixSizedElement( + encodedKeySize, + encodedValueSize, + int(childMap.Count()), + ) require.Equal(t, expectedInlinedMapSize, GetMapRootSlabByteSize(childMap)) - expectedParentSize -= expectedChildElementSize + elementByteSizesByKey[childKey] = [2]uint32{ + elementByteSizesByKey[childKey][0], + expectedInlinedMapSize, + } + + elementByteSizes := make([][2]uint32, 0, len(elementByteSizesByKey)) + for _, v := range elementByteSizesByKey { + elementByteSizes = append(elementByteSizes, v) + } + expectedParentSize := ComputeMapRootDataSlabByteSize(elementByteSizes) require.Equal(t, expectedParentSize, GetMapRootSlabByteSize(parentMap)) testMap(t, storage, typeInfo, address, parentMap, expectedKeyValues, nil, true) @@ -17130,7 +17186,7 @@ func TestChildMapInlinabilityInParentMap(t *testing.T) { storage := newTestPersistentStorage(t) address := Address{1, 2, 3, 4, 5, 6, 7, 8} - parentMap, expectedKeyValues := createMapWithEmptyChildMap(t, storage, address, typeInfo, mapCount, func() Value { + parentMap, expectedKeyValues, _ := createMapWithEmptyChildMap(t, storage, address, typeInfo, mapCount, func() Value { return NewStringValue(randStr(r, keyStringSize)) }) @@ -17166,9 +17222,11 @@ func TestChildMapInlinabilityInParentMap(t *testing.T) { require.Equal(t, valueID, childMap.ValueID()) // Value ID is unchanged // Test inlined child slab size - expectedChildElementSize := singleElementPrefixSize + digestSize + encodedKeySize + encodedValueSize - expectedInlinedMapSize := inlinedMapDataSlabPrefixSize + hkeyElementsPrefixSize + - expectedChildElementSize*uint32(childMap.Count()) + expectedInlinedMapSize := ComputeInlinedMapSlabByteSizeWithFixSizedElement( + encodedKeySize, + encodedValueSize, + int(childMap.Count()), + ) require.Equal(t, expectedInlinedMapSize, GetMapRootSlabByteSize(childMap)) testMap(t, storage, typeInfo, address, parentMap, expectedKeyValues, nil, true) @@ -17203,9 +17261,11 @@ func TestChildMapInlinabilityInParentMap(t *testing.T) { require.Equal(t, expectedSlabID, childMap.SlabID()) // Storage ID is the same bytewise as value ID. require.Equal(t, valueID, childMap.ValueID()) // Value ID is unchanged - expectedChildElementSize := singleElementPrefixSize + digestSize + encodedKeySize + encodedValueSize - expectedStandaloneSlabSize := uint32(mapRootDataSlabPrefixSize+hkeyElementsPrefixSize) + - expectedChildElementSize*uint32(childMap.Count()) + expectedStandaloneSlabSize := ComputeMapRootDataSlabByteSizeWithFixSizedElement( + encodedKeySize, + encodedValueSize, + int(childMap.Count()), + ) require.Equal(t, expectedStandaloneSlabSize, GetMapRootSlabByteSize(childMap)) testMap(t, storage, typeInfo, address, parentMap, expectedKeyValues, nil, true) @@ -17241,9 +17301,11 @@ func TestChildMapInlinabilityInParentMap(t *testing.T) { require.Equal(t, SlabIDUndefined, childMap.SlabID()) require.Equal(t, valueID, childMap.ValueID()) // value ID is unchanged - expectedChildElementSize := singleElementPrefixSize + digestSize + encodedKeySize + encodedValueSize - expectedInlinedMapSize := inlinedMapDataSlabPrefixSize + hkeyElementsPrefixSize + - expectedChildElementSize*uint32(childMap.Count()) + expectedInlinedMapSize := ComputeInlinedMapSlabByteSizeWithFixSizedElement( + encodedKeySize, + encodedValueSize, + int(childMap.Count()), + ) require.Equal(t, expectedInlinedMapSize, GetMapRootSlabByteSize(childMap)) testMap(t, storage, typeInfo, address, parentMap, expectedKeyValues, nil, true) @@ -17278,9 +17340,11 @@ func TestChildMapInlinabilityInParentMap(t *testing.T) { require.Equal(t, SlabIDUndefined, childMap.SlabID()) require.Equal(t, valueID, childMap.ValueID()) // value ID is unchanged - expectedChildElementSize := singleElementPrefixSize + digestSize + encodedKeySize + encodedValueSize - expectedInlinedMapSize := inlinedMapDataSlabPrefixSize + hkeyElementsPrefixSize + - expectedChildElementSize*uint32(childMap.Count()) + expectedInlinedMapSize := ComputeInlinedMapSlabByteSizeWithFixSizedElement( + encodedKeySize, + encodedValueSize, + int(childMap.Count()), + ) require.Equal(t, expectedInlinedMapSize, GetMapRootSlabByteSize(childMap)) testMap(t, storage, typeInfo, address, parentMap, expectedKeyValues, nil, true) @@ -17296,9 +17360,11 @@ func TestChildMapInlinabilityInParentMap(t *testing.T) { require.Equal(t, 1, getStoredDeltas(storage)) // There is only 1 stored slab because child map is inlined. // Test parent map slab size - expectedParentElementSize := singleElementPrefixSize + digestSize + encodedKeySize + expectedEmptyInlinedMapSize - expectedParentSize := uint32(mapRootDataSlabPrefixSize+hkeyElementsPrefixSize) + // standalone map data slab with 0 element - expectedParentElementSize*uint32(mapCount) + expectedParentSize := ComputeMapRootDataSlabByteSizeWithFixSizedElement( + encodedKeySize, + emptyInlinedMapByteSize, + mapCount, + ) require.Equal(t, expectedParentSize, GetMapRootSlabByteSize(parentMap)) }) } @@ -17330,7 +17396,7 @@ func TestNestedThreeLevelChildMapInlinabilityInParentMap(t *testing.T) { } // Create a parent map, with an inlined child map, with an inlined grand child map - parentMap, expectedKeyValues := createMapWithEmpty2LevelChildMap(t, storage, address, typeInfo, mapCount, getKeyFunc) + parentMap, expectedKeyValues, elementByteSizesByKey := createMapWithEmpty2LevelChildMap(t, storage, address, typeInfo, mapCount, getKeyFunc) require.Equal(t, uint64(mapCount), parentMap.Count()) require.True(t, IsMapRootDataSlab(parentMap)) @@ -17341,8 +17407,6 @@ func TestNestedThreeLevelChildMapInlinabilityInParentMap(t *testing.T) { children := getInlinedChildMapsFromParentMap(t, address, parentMap) require.Equal(t, mapCount, len(children)) - expectedParentSize := GetMapRootSlabByteSize(parentMap) - // Inserting 1 elements to grand child map so that inlined grand child map reaches max inlined size as map element. for childKey, child := range children { require.Equal(t, 1, len(child.children)) @@ -17391,19 +17455,33 @@ func TestNestedThreeLevelChildMapInlinabilityInParentMap(t *testing.T) { require.Equal(t, 1, getStoredDeltas(storage)) // Test inlined grand child slab size - expectedGrandChildElementSize := singleElementPrefixSize + digestSize + encodedKeySize + encodedValueSize - expectedGrandChildMapSize := inlinedMapDataSlabPrefixSize + hkeyElementsPrefixSize + - expectedGrandChildElementSize*uint32(gchildMap.Count()) + expectedGrandChildMapSize := ComputeInlinedMapSlabByteSizeWithFixSizedElement( + encodedKeySize, + encodedValueSize, + int(gchildMap.Count()), + ) require.Equal(t, expectedGrandChildMapSize, GetMapRootSlabByteSize(gchildMap)) // Test inlined child slab size - expectedChildElementSize := singleElementPrefixSize + digestSize + encodedKeySize + expectedGrandChildMapSize - expectedChildMapSize := inlinedMapDataSlabPrefixSize + hkeyElementsPrefixSize + - expectedChildElementSize*uint32(childMap.Count()) + expectedChildMapSize := ComputeInlinedMapSlabByteSizeWithFixSizedElement( + encodedKeySize, + expectedGrandChildMapSize, + int(childMap.Count()), + ) require.Equal(t, expectedChildMapSize, GetMapRootSlabByteSize(childMap)) // Test parent slab size - expectedParentSize += expectedGrandChildElementSize + elementByteSizesByKey[childKey] = [2]uint32{ + elementByteSizesByKey[childKey][0], + expectedChildMapSize, + } + + elementByteSizes := make([][2]uint32, 0, len(elementByteSizesByKey)) + for _, v := range elementByteSizesByKey { + elementByteSizes = append(elementByteSizes, v) + } + + expectedParentSize := ComputeMapRootDataSlabByteSize(elementByteSizes) require.Equal(t, expectedParentSize, GetMapRootSlabByteSize(parentMap)) testMap(t, storage, typeInfo, address, parentMap, expectedKeyValues, nil, true) @@ -17462,20 +17540,27 @@ func TestNestedThreeLevelChildMapInlinabilityInParentMap(t *testing.T) { require.Equal(t, 2, getStoredDeltas(storage)) // Test inlined grand child slab size - expectedGrandChildElementSize := singleElementPrefixSize + digestSize + encodedKeySize + encodedValueSize - expectedGrandChildMapSize := inlinedMapDataSlabPrefixSize + hkeyElementsPrefixSize + - expectedGrandChildElementSize*uint32(gchildMap.Count()) + expectedGrandChildMapSize := ComputeInlinedMapSlabByteSizeWithFixSizedElement( + encodedKeySize, + encodedValueSize, + int(gchildMap.Count()), + ) require.Equal(t, expectedGrandChildMapSize, GetMapRootSlabByteSize(gchildMap)) // Test standalone child slab size - expectedChildElementSize := singleElementPrefixSize + digestSize + encodedKeySize + expectedGrandChildMapSize - expectedChildMapSize := mapRootDataSlabPrefixSize + hkeyElementsPrefixSize + - expectedChildElementSize*uint32(childMap.Count()) + expectedChildMapSize := ComputeMapRootDataSlabByteSizeWithFixSizedElement( + encodedKeySize, + expectedGrandChildMapSize, + int(childMap.Count()), + ) require.Equal(t, expectedChildMapSize, GetMapRootSlabByteSize(childMap)) // Test parent slab size - expectedParentSize := mapRootDataSlabPrefixSize + hkeyElementsPrefixSize + - singleElementPrefixSize + digestSize + encodedKeySize + SlabIDStorable(SlabID{}).ByteSize() + expectedParentSize := ComputeMapRootDataSlabByteSizeWithFixSizedElement( + encodedKeySize, + slabIDStorableByteSize, + int(parentMap.Count()), + ) require.Equal(t, expectedParentSize, GetMapRootSlabByteSize(parentMap)) testMap(t, storage, typeInfo, address, parentMap, expectedKeyValues, nil, true) @@ -17532,21 +17617,27 @@ func TestNestedThreeLevelChildMapInlinabilityInParentMap(t *testing.T) { require.Equal(t, gValueID, gchildMap.ValueID()) // value ID is unchanged // Test inlined grand child slab size - expectedGrandChildElementSize := singleElementPrefixSize + digestSize + encodedKeySize + encodedValueSize - expectedGrandChildMapSize := inlinedMapDataSlabPrefixSize + hkeyElementsPrefixSize + - expectedGrandChildElementSize*uint32(gchildMap.Count()) + expectedGrandChildMapSize := ComputeInlinedMapSlabByteSizeWithFixSizedElement( + encodedKeySize, + encodedValueSize, + int(gchildMap.Count()), + ) require.Equal(t, expectedGrandChildMapSize, GetMapRootSlabByteSize(gchildMap)) // Test inlined child slab size - expectedChildElementSize := singleElementPrefixSize + digestSize + encodedKeySize + expectedGrandChildMapSize - expectedChildMapSize := inlinedMapDataSlabPrefixSize + hkeyElementsPrefixSize + - expectedChildElementSize*uint32(childMap.Count()) + expectedChildMapSize := ComputeInlinedMapSlabByteSizeWithFixSizedElement( + encodedKeySize, + expectedGrandChildMapSize, + int(childMap.Count()), + ) require.Equal(t, expectedChildMapSize, GetMapRootSlabByteSize(childMap)) // Test parent child slab size - expectedParentElementSize := singleElementPrefixSize + digestSize + encodedKeySize + expectedChildMapSize - expectedParentMapSize := mapRootDataSlabPrefixSize + hkeyElementsPrefixSize + - expectedParentElementSize*uint32(parentMap.Count()) + expectedParentMapSize := ComputeMapRootDataSlabByteSizeWithFixSizedElement( + encodedKeySize, + expectedChildMapSize, + int(parentMap.Count()), + ) require.Equal(t, expectedParentMapSize, GetMapRootSlabByteSize(parentMap)) testMap(t, storage, typeInfo, address, parentMap, expectedKeyValues, nil, true) @@ -17575,7 +17666,6 @@ func TestNestedThreeLevelChildMapInlinabilityInParentMap(t *testing.T) { encodedKeySize := NewStringValue(strings.Repeat("a", keyStringSize)).ByteSize() encodedValueSize := NewStringValue(strings.Repeat("a", valueStringSize)).ByteSize() encodedLargeValueSize := NewStringValue(strings.Repeat("a", largeValueStringSize)).ByteSize() - slabIDStorableSize := SlabIDStorable(SlabID{}).ByteSize() r := newRand(t) @@ -17588,7 +17678,7 @@ func TestNestedThreeLevelChildMapInlinabilityInParentMap(t *testing.T) { } // Create a parent map, with an inlined child map, with an inlined grand child map - parentMap, expectedKeyValues := createMapWithEmpty2LevelChildMap(t, storage, address, typeInfo, mapCount, getKeyFunc) + parentMap, expectedKeyValues, elementByteSizesByKey := createMapWithEmpty2LevelChildMap(t, storage, address, typeInfo, mapCount, getKeyFunc) require.Equal(t, uint64(mapCount), parentMap.Count()) require.True(t, IsMapRootDataSlab(parentMap)) @@ -17599,8 +17689,6 @@ func TestNestedThreeLevelChildMapInlinabilityInParentMap(t *testing.T) { children := getInlinedChildMapsFromParentMap(t, address, parentMap) require.Equal(t, mapCount, len(children)) - expectedParentSize := GetMapRootSlabByteSize(parentMap) - // Inserting 1 elements to grand child map so that inlined grand child map reaches max inlined size as map element. for childKey, child := range children { require.Equal(t, 1, len(child.children)) @@ -17649,19 +17737,30 @@ func TestNestedThreeLevelChildMapInlinabilityInParentMap(t *testing.T) { require.Equal(t, 1, getStoredDeltas(storage)) // Test inlined grand child slab size - expectedGrandChildElementSize := singleElementPrefixSize + digestSize + encodedKeySize + encodedValueSize - expectedGrandChildMapSize := inlinedMapDataSlabPrefixSize + hkeyElementsPrefixSize + - expectedGrandChildElementSize*uint32(gchildMap.Count()) + expectedGrandChildMapSize := ComputeInlinedMapSlabByteSizeWithFixSizedElement( + encodedKeySize, + encodedValueSize, + int(gchildMap.Count()), + ) require.Equal(t, expectedGrandChildMapSize, GetMapRootSlabByteSize(gchildMap)) // Test inlined child slab size - expectedChildElementSize := singleElementPrefixSize + digestSize + encodedKeySize + expectedGrandChildMapSize - expectedChildMapSize := inlinedMapDataSlabPrefixSize + hkeyElementsPrefixSize + - expectedChildElementSize*uint32(childMap.Count()) + expectedChildMapSize := ComputeInlinedMapSlabByteSizeWithFixSizedElement( + encodedKeySize, + expectedGrandChildMapSize, + int(childMap.Count()), + ) require.Equal(t, expectedChildMapSize, GetMapRootSlabByteSize(childMap)) // Test parent slab size - expectedParentSize += expectedGrandChildElementSize + elementByteSizesByKey[childKey] = [2]uint32{elementByteSizesByKey[childKey][0], expectedChildMapSize} + + elementByteSizes := make([][2]uint32, 0, len(elementByteSizesByKey)) + for _, v := range elementByteSizesByKey { + elementByteSizes = append(elementByteSizes, v) + } + + expectedParentSize := ComputeMapRootDataSlabByteSize(elementByteSizes) require.Equal(t, expectedParentSize, GetMapRootSlabByteSize(parentMap)) testMap(t, storage, typeInfo, address, parentMap, expectedKeyValues, nil, true) @@ -17723,20 +17822,24 @@ func TestNestedThreeLevelChildMapInlinabilityInParentMap(t *testing.T) { require.Equal(t, 2, getStoredDeltas(storage)) // Test standalone grand child slab size - expectedGrandChildElement1Size := singleElementPrefixSize + digestSize + encodedKeySize + encodedValueSize - expectedGrandChildElement2Size := singleElementPrefixSize + digestSize + encodedKeySize + encodedLargeValueSize - expectedGrandChildMapSize := mapRootDataSlabPrefixSize + hkeyElementsPrefixSize + - expectedGrandChildElement1Size + expectedGrandChildElement2Size + expectedGrandChildMapSize := ComputeMapRootDataSlabByteSize( + [][2]uint32{ + {encodedKeySize, encodedValueSize}, + {encodedKeySize, encodedLargeValueSize}, + }, + ) require.Equal(t, expectedGrandChildMapSize, GetMapRootSlabByteSize(gchildMap)) // Test inlined child slab size - expectedChildElementSize := singleElementPrefixSize + digestSize + encodedKeySize + slabIDStorableSize - expectedChildMapSize := inlinedMapDataSlabPrefixSize + hkeyElementsPrefixSize + expectedChildElementSize + expectedChildMapSize := ComputeInlinedMapSlabByteSize([][2]uint32{{encodedKeySize, slabIDStorableByteSize}}) require.Equal(t, expectedChildMapSize, GetMapRootSlabByteSize(childMap)) // Test parent slab size - expectedParentSize := mapRootDataSlabPrefixSize + hkeyElementsPrefixSize + - singleElementPrefixSize + digestSize + encodedKeySize + expectedChildMapSize + expectedParentSize := ComputeMapRootDataSlabByteSize( + [][2]uint32{ + {encodedKeySize, expectedChildMapSize}, + }, + ) require.Equal(t, expectedParentSize, GetMapRootSlabByteSize(parentMap)) testMap(t, storage, typeInfo, address, parentMap, expectedKeyValues, nil, true) @@ -17799,21 +17902,26 @@ func TestNestedThreeLevelChildMapInlinabilityInParentMap(t *testing.T) { require.Equal(t, gValueID, gchildMap.ValueID()) // value ID is unchanged // Test inlined grand child slab size - expectedGrandChildElementSize := singleElementPrefixSize + digestSize + encodedKeySize + encodedValueSize - expectedGrandChildMapSize := inlinedMapDataSlabPrefixSize + hkeyElementsPrefixSize + - expectedGrandChildElementSize*uint32(gchildMap.Count()) + expectedGrandChildMapSize := ComputeInlinedMapSlabByteSizeWithFixSizedElement( + encodedKeySize, + encodedValueSize, + int(gchildMap.Count()), + ) require.Equal(t, expectedGrandChildMapSize, GetMapRootSlabByteSize(gchildMap)) // Test inlined child slab size - expectedChildElementSize := singleElementPrefixSize + digestSize + encodedKeySize + expectedGrandChildMapSize - expectedChildMapSize := inlinedMapDataSlabPrefixSize + hkeyElementsPrefixSize + - expectedChildElementSize*uint32(childMap.Count()) + expectedChildMapSize := ComputeInlinedMapSlabByteSizeWithFixSizedElement( + encodedKeySize, + expectedGrandChildMapSize, + int(childMap.Count()), + ) require.Equal(t, expectedChildMapSize, GetMapRootSlabByteSize(childMap)) // Test parent child slab size - expectedParentElementSize := singleElementPrefixSize + digestSize + encodedKeySize + expectedChildMapSize - expectedParentMapSize := mapRootDataSlabPrefixSize + hkeyElementsPrefixSize + - expectedParentElementSize*uint32(parentMap.Count()) + expectedParentMapSize := ComputeMapRootDataSlabByteSizeWithFixSizedElement( + encodedKeySize, expectedChildMapSize, + int(parentMap.Count()), + ) require.Equal(t, expectedParentMapSize, GetMapRootSlabByteSize(parentMap)) testMap(t, storage, typeInfo, address, parentMap, expectedKeyValues, nil, true) @@ -17853,7 +17961,7 @@ func TestNestedThreeLevelChildMapInlinabilityInParentMap(t *testing.T) { } // Create a parent map, with inlined child map, containing inlined grand child map - parentMap, expectedKeyValues := createMapWithEmpty2LevelChildMap(t, storage, address, typeInfo, mapCount, getKeyFunc) + parentMap, expectedKeyValues, elementByteSizesByKey := createMapWithEmpty2LevelChildMap(t, storage, address, typeInfo, mapCount, getKeyFunc) require.Equal(t, uint64(mapCount), parentMap.Count()) require.True(t, IsMapRootDataSlab(parentMap)) @@ -17864,8 +17972,6 @@ func TestNestedThreeLevelChildMapInlinabilityInParentMap(t *testing.T) { children := getInlinedChildMapsFromParentMap(t, address, parentMap) require.Equal(t, mapCount, len(children)) - expectedParentSize := GetMapRootSlabByteSize(parentMap) - // Insert 1 elements to grand child map (both child map and grand child map are still inlined). for childKey, child := range children { childMap := child.m @@ -17912,19 +18018,30 @@ func TestNestedThreeLevelChildMapInlinabilityInParentMap(t *testing.T) { require.Equal(t, 1, getStoredDeltas(storage)) // Test inlined grand child slab size - expectedGrandChildElementSize := singleElementPrefixSize + digestSize + encodedKeySize + encodedValueSize - expectedGrandChildMapSize := inlinedMapDataSlabPrefixSize + hkeyElementsPrefixSize + - expectedGrandChildElementSize*uint32(gchildMap.Count()) + expectedGrandChildMapSize := ComputeInlinedMapSlabByteSizeWithFixSizedElement( + encodedKeySize, + encodedValueSize, + int(gchildMap.Count()), + ) require.Equal(t, expectedGrandChildMapSize, GetMapRootSlabByteSize(gchildMap)) // Test inlined child slab size - expectedChildElementSize := singleElementPrefixSize + digestSize + encodedKeySize + expectedGrandChildMapSize - expectedChildMapSize := inlinedMapDataSlabPrefixSize + hkeyElementsPrefixSize + - expectedChildElementSize*uint32(childMap.Count()) + expectedChildMapSize := ComputeInlinedMapSlabByteSizeWithFixSizedElement( + encodedKeySize, + expectedGrandChildMapSize, + int(childMap.Count()), + ) require.Equal(t, expectedChildMapSize, GetMapRootSlabByteSize(childMap)) // Test parent slab size - expectedParentSize += expectedGrandChildElementSize + elementByteSizesByKey[childKey] = [2]uint32{elementByteSizesByKey[childKey][0], expectedChildMapSize} + + elementByteSizes := make([][2]uint32, 0, len(elementByteSizesByKey)) + for _, v := range elementByteSizesByKey { + elementByteSizes = append(elementByteSizes, v) + } + + expectedParentSize := ComputeMapRootDataSlabByteSize(elementByteSizes) require.Equal(t, expectedParentSize, GetMapRootSlabByteSize(parentMap)) testMap(t, storage, typeInfo, address, parentMap, expectedKeyValues, nil, true) @@ -17935,8 +18052,6 @@ func TestNestedThreeLevelChildMapInlinabilityInParentMap(t *testing.T) { testMap(t, storage, typeInfo, address, parentMap, expectedKeyValues, nil, true) - expectedParentSize = GetMapRootSlabByteSize(parentMap) - // Add 1 element to each child map so child map reaches its max size for childKey, child := range children { @@ -17979,19 +18094,31 @@ func TestNestedThreeLevelChildMapInlinabilityInParentMap(t *testing.T) { require.Equal(t, 1, getStoredDeltas(storage)) // Test inlined grand child slab size - expectedGrandChildElementSize := digestSize + singleElementPrefixSize + encodedKeySize + encodedValueSize - expectedGrandChildMapSize := inlinedMapDataSlabPrefixSize + hkeyElementsPrefixSize + - expectedGrandChildElementSize*uint32(gchildMap.Count()) + expectedGrandChildMapSize := ComputeInlinedMapSlabByteSizeWithFixSizedElement( + encodedKeySize, + encodedValueSize, + int(gchildMap.Count()), + ) require.Equal(t, expectedGrandChildMapSize, GetMapRootSlabByteSize(gchildMap)) // Test inlined child slab size - expectedChildElementSize := digestSize + singleElementPrefixSize + encodedKeySize + encodedValueSize - expectedChildMapSize := inlinedMapDataSlabPrefixSize + hkeyElementsPrefixSize + - expectedChildElementSize + (digestSize + singleElementPrefixSize + encodedKeySize + expectedGrandChildMapSize) + expectedChildMapSize := ComputeInlinedMapSlabByteSize( + [][2]uint32{ + {encodedKeySize, encodedValueSize}, + {encodedKeySize, expectedGrandChildMapSize}, + }, + ) require.Equal(t, expectedChildMapSize, GetMapRootSlabByteSize(childMap)) // Test parent slab size - expectedParentSize += digestSize + singleElementPrefixSize + encodedKeySize + encodedValueSize + elementByteSizesByKey[childKey] = [2]uint32{elementByteSizesByKey[childKey][0], expectedChildMapSize} + + elementByteSizes := make([][2]uint32, 0, len(elementByteSizesByKey)) + for _, v := range elementByteSizesByKey { + elementByteSizes = append(elementByteSizes, v) + } + + expectedParentSize := ComputeMapRootDataSlabByteSize(elementByteSizes) require.Equal(t, expectedParentSize, GetMapRootSlabByteSize(parentMap)) testMap(t, storage, typeInfo, address, parentMap, expectedKeyValues, nil, true) @@ -18047,17 +18174,34 @@ func TestNestedThreeLevelChildMapInlinabilityInParentMap(t *testing.T) { i++ // Test inlined grand child slab size - expectedGrandChildElementSize := singleElementPrefixSize + digestSize + encodedKeySize + encodedValueSize - expectedGrandChildMapSize := inlinedMapDataSlabPrefixSize + hkeyElementsPrefixSize + - expectedGrandChildElementSize*uint32(gchildMap.Count()) + expectedGrandChildMapSize := ComputeInlinedMapSlabByteSizeWithFixSizedElement( + encodedKeySize, + encodedValueSize, + int(gchildMap.Count()), + ) require.Equal(t, expectedGrandChildMapSize, GetMapRootSlabByteSize(gchildMap)) // Test standalone child slab size - expectedChildElementSize := singleElementPrefixSize + digestSize + encodedKeySize + encodedValueSize - expectedChildMapSize := mapRootDataSlabPrefixSize + hkeyElementsPrefixSize + - expectedChildElementSize*2 + (digestSize + singleElementPrefixSize + encodedKeySize + expectedGrandChildMapSize) + expectedChildMapSize := ComputeMapRootDataSlabByteSize( + [][2]uint32{ + {encodedKeySize, encodedValueSize}, + {encodedKeySize, encodedValueSize}, + {encodedKeySize, expectedGrandChildMapSize}, + }, + ) require.Equal(t, expectedChildMapSize, GetMapRootSlabByteSize(childMap)) + // Test parent slab size + elementByteSizesByKey[childKey] = [2]uint32{elementByteSizesByKey[childKey][0], slabIDStorableSize} + + elementByteSizes := make([][2]uint32, 0, len(elementByteSizesByKey)) + for _, v := range elementByteSizesByKey { + elementByteSizes = append(elementByteSizes, v) + } + + expectedParentSize := ComputeMapRootDataSlabByteSize(elementByteSizes) + require.Equal(t, expectedParentSize, GetMapRootSlabByteSize(parentMap)) + testMap(t, storage, typeInfo, address, parentMap, expectedKeyValues, nil, true) } @@ -18065,14 +18209,15 @@ func TestNestedThreeLevelChildMapInlinabilityInParentMap(t *testing.T) { require.Equal(t, 1+mapCount, getStoredDeltas(storage)) // There is 1+mapCount stored slab because all child maps are standalone. // Test parent slab size - expectedParentSize = mapRootDataSlabPrefixSize + hkeyElementsPrefixSize + - (singleElementPrefixSize+digestSize+encodedKeySize+slabIDStorableSize)*mapCount + expectedParentSize := ComputeMapRootDataSlabByteSizeWithFixSizedElement( + encodedKeySize, + slabIDStorableSize, + mapCount, + ) require.Equal(t, expectedParentSize, GetMapRootSlabByteSize(parentMap)) testMap(t, storage, typeInfo, address, parentMap, expectedKeyValues, nil, true) - expectedParentMapSize := GetMapRootSlabByteSize(parentMap) - // Remove one element from child map which triggers standalone child map slab becomes inlined slab again. for childKey, child := range children { childMap := child.m @@ -18118,20 +18263,31 @@ func TestNestedThreeLevelChildMapInlinabilityInParentMap(t *testing.T) { require.Equal(t, gValueID, gchildMap.ValueID()) // value ID is unchanged // Test inlined grand child slab size - expectedGrandChildElementSize := singleElementPrefixSize + digestSize + encodedKeySize + encodedValueSize - expectedGrandChildMapSize := inlinedMapDataSlabPrefixSize + hkeyElementsPrefixSize + - expectedGrandChildElementSize*uint32(gchildMap.Count()) + expectedGrandChildMapSize := ComputeInlinedMapSlabByteSizeWithFixSizedElement( + encodedKeySize, + encodedValueSize, + int(gchildMap.Count()), + ) require.Equal(t, expectedGrandChildMapSize, GetMapRootSlabByteSize(gchildMap)) // Test inlined child slab size - expectedChildElementSize1 := singleElementPrefixSize + digestSize + encodedKeySize + expectedGrandChildMapSize - expectedChildElementSize2 := singleElementPrefixSize + digestSize + encodedKeySize + encodedValueSize - expectedChildMapSize := inlinedMapDataSlabPrefixSize + hkeyElementsPrefixSize + - expectedChildElementSize1 + expectedChildElementSize2*uint32(childMap.Count()-1) + elementByteSizes := make([][2]uint32, int(childMap.Count())) + elementByteSizes[0] = [2]uint32{encodedKeySize, expectedGrandChildMapSize} + for i := 1; i < int(childMap.Count()); i++ { + elementByteSizes[i] = [2]uint32{encodedKeySize, encodedValueSize} + } + expectedChildMapSize := ComputeInlinedMapSlabByteSize(elementByteSizes) require.Equal(t, expectedChildMapSize, GetMapRootSlabByteSize(childMap)) // Test parent child slab size - expectedParentMapSize = expectedParentMapSize - slabIDStorableSize + expectedChildMapSize + elementByteSizesByKey[childKey] = [2]uint32{elementByteSizesByKey[childKey][0], expectedChildMapSize} + + elementByteSizes = make([][2]uint32, 0, len(elementByteSizesByKey)) + for _, v := range elementByteSizesByKey { + elementByteSizes = append(elementByteSizes, v) + } + + expectedParentMapSize := ComputeMapRootDataSlabByteSize(elementByteSizes) require.Equal(t, expectedParentMapSize, GetMapRootSlabByteSize(parentMap)) testMap(t, storage, typeInfo, address, parentMap, expectedKeyValues, nil, true) @@ -18188,20 +18344,31 @@ func TestNestedThreeLevelChildMapInlinabilityInParentMap(t *testing.T) { require.Equal(t, gValueID, gchildMap.ValueID()) // value ID is unchanged // Test inlined grand child slab size - expectedGrandChildElementSize := singleElementPrefixSize + digestSize + encodedKeySize + encodedValueSize - expectedGrandChildMapSize := inlinedMapDataSlabPrefixSize + hkeyElementsPrefixSize + - expectedGrandChildElementSize*uint32(gchildMap.Count()) + expectedGrandChildMapSize := ComputeInlinedMapSlabByteSizeWithFixSizedElement( + encodedKeySize, + encodedValueSize, + int(gchildMap.Count()), + ) require.Equal(t, expectedGrandChildMapSize, GetMapRootSlabByteSize(gchildMap)) // Test inlined child slab size - expectedChildElementSize1 := singleElementPrefixSize + digestSize + encodedKeySize + expectedGrandChildMapSize - expectedChildElementSize2 := singleElementPrefixSize + digestSize + encodedKeySize + encodedValueSize - expectedChildMapSize := inlinedMapDataSlabPrefixSize + hkeyElementsPrefixSize + - expectedChildElementSize1 + expectedChildElementSize2*uint32(childMap.Count()-1) + elementByteSizes := make([][2]uint32, int(childMap.Count())) + elementByteSizes[0] = [2]uint32{encodedKeySize, expectedGrandChildMapSize} + for i := 1; i < int(childMap.Count()); i++ { + elementByteSizes[i] = [2]uint32{encodedKeySize, encodedValueSize} + } + expectedChildMapSize := ComputeInlinedMapSlabByteSize(elementByteSizes) require.Equal(t, expectedChildMapSize, GetMapRootSlabByteSize(childMap)) // Test parent child slab size - expectedParentMapSize -= digestSize + singleElementPrefixSize + encodedKeySize + encodedValueSize + elementByteSizesByKey[childKey] = [2]uint32{elementByteSizesByKey[childKey][0], expectedChildMapSize} + + elementByteSizes = make([][2]uint32, 0, len(elementByteSizesByKey)) + for _, v := range elementByteSizesByKey { + elementByteSizes = append(elementByteSizes, v) + } + + expectedParentMapSize := ComputeMapRootDataSlabByteSize(elementByteSizes) require.Equal(t, expectedParentMapSize, GetMapRootSlabByteSize(parentMap)) testMap(t, storage, typeInfo, address, parentMap, expectedKeyValues, nil, true) @@ -18241,7 +18408,7 @@ func TestNestedThreeLevelChildMapInlinabilityInParentMap(t *testing.T) { } // Create a parent map, with inlined child map, containing inlined grand child map - parentMap, expectedKeyValues := createMapWithEmpty2LevelChildMap(t, storage, address, typeInfo, mapCount, getKeyFunc) + parentMap, expectedKeyValues, _ := createMapWithEmpty2LevelChildMap(t, storage, address, typeInfo, mapCount, getKeyFunc) require.Equal(t, uint64(mapCount), parentMap.Count()) require.True(t, IsMapRootDataSlab(parentMap)) @@ -18294,15 +18461,19 @@ func TestNestedThreeLevelChildMapInlinabilityInParentMap(t *testing.T) { require.Equal(t, cValueID, childMap.ValueID()) // Value ID is unchanged // Test inlined grand child slab size - expectedGrandChildElementSize := singleElementPrefixSize + digestSize + encodedKeySize + encodedValueSize - expectedGrandChildMapSize := inlinedMapDataSlabPrefixSize + hkeyElementsPrefixSize + - expectedGrandChildElementSize*uint32(gchildMap.Count()) + expectedGrandChildMapSize := ComputeInlinedMapSlabByteSizeWithFixSizedElement( + encodedKeySize, + encodedValueSize, + int(gchildMap.Count()), + ) require.Equal(t, expectedGrandChildMapSize, GetMapRootSlabByteSize(gchildMap)) // Test inlined child slab size - expectedChildElementSize := singleElementPrefixSize + digestSize + encodedKeySize + expectedGrandChildMapSize - expectedChildMapSize := inlinedMapDataSlabPrefixSize + hkeyElementsPrefixSize + - expectedChildElementSize*uint32(childMap.Count()) + expectedChildMapSize := ComputeInlinedMapSlabByteSizeWithFixSizedElement( + encodedKeySize, + expectedGrandChildMapSize, + int(childMap.Count()), + ) require.Equal(t, expectedChildMapSize, GetMapRootSlabByteSize(childMap)) testMap(t, storage, typeInfo, address, parentMap, expectedKeyValues, nil, true) @@ -18359,15 +18530,19 @@ func TestNestedThreeLevelChildMapInlinabilityInParentMap(t *testing.T) { require.Equal(t, cValueID, childMap.ValueID()) // Value ID is unchanged // Test inlined grand child slab size - expectedGrandChildElementSize := singleElementPrefixSize + digestSize + encodedKeySize + encodedValueSize - expectedGrandChildMapSize := inlinedMapDataSlabPrefixSize + hkeyElementsPrefixSize + - expectedGrandChildElementSize*uint32(gchildMap.Count()) + expectedGrandChildMapSize := ComputeInlinedMapSlabByteSizeWithFixSizedElement( + encodedKeySize, + encodedValueSize, + int(gchildMap.Count()), + ) require.Equal(t, expectedGrandChildMapSize, GetMapRootSlabByteSize(gchildMap)) // Test standalone child slab size - expectedChildElementSize := singleElementPrefixSize + digestSize + encodedKeySize + expectedGrandChildMapSize - expectedChildMapSize := mapRootDataSlabPrefixSize + hkeyElementsPrefixSize + - expectedChildElementSize*uint32(childMap.Count()) + expectedChildMapSize := ComputeMapRootDataSlabByteSizeWithFixSizedElement( + encodedKeySize, + expectedGrandChildMapSize, + int(childMap.Count()), + ) require.Equal(t, expectedChildMapSize, GetMapRootSlabByteSize(childMap)) testMap(t, storage, typeInfo, address, parentMap, expectedKeyValues, nil, true) @@ -18378,9 +18553,11 @@ func TestNestedThreeLevelChildMapInlinabilityInParentMap(t *testing.T) { require.Equal(t, 1+mapCount, getStoredDeltas(storage)) // Test parent slab size - expectedParentElementSize := singleElementPrefixSize + digestSize + encodedKeySize + slabIDStorableSize - expectedParentMapSize := mapRootDataSlabPrefixSize + hkeyElementsPrefixSize + - expectedParentElementSize*uint32(parentMap.Count()) + expectedParentMapSize := ComputeMapRootDataSlabByteSizeWithFixSizedElement( + encodedKeySize, + slabIDStorableSize, + int(parentMap.Count()), + ) require.Equal(t, expectedParentMapSize, GetMapRootSlabByteSize(parentMap)) testMap(t, storage, typeInfo, address, parentMap, expectedKeyValues, nil, true) @@ -18434,16 +18611,20 @@ func TestNestedThreeLevelChildMapInlinabilityInParentMap(t *testing.T) { require.Equal(t, gValueID, gchildMap.ValueID()) // value ID is unchanged // Test inlined grand child slab size - expectedGrandChildElementSize := singleElementPrefixSize + digestSize + encodedKeySize + encodedValueSize - expectedGrandChildMapSize := inlinedMapDataSlabPrefixSize + hkeyElementsPrefixSize + - expectedGrandChildElementSize*uint32(gchildMap.Count()) + expectedGrandChildMapSize := ComputeInlinedMapSlabByteSizeWithFixSizedElement( + encodedKeySize, + encodedValueSize, + int(gchildMap.Count()), + ) require.Equal(t, expectedGrandChildMapSize, GetMapRootSlabByteSize(gchildMap)) // Test inlined child slab size - expectedChildElementSize1 := singleElementPrefixSize + digestSize + encodedKeySize + expectedGrandChildMapSize - expectedChildElementSize2 := singleElementPrefixSize + digestSize + encodedKeySize + encodedValueSize - expectedChildMapSize := inlinedMapDataSlabPrefixSize + hkeyElementsPrefixSize + - expectedChildElementSize1 + expectedChildElementSize2*uint32(childMap.Count()-1) + elementByteSizes := make([][2]uint32, int(childMap.Count())) + elementByteSizes[0] = [2]uint32{encodedKeySize, expectedGrandChildMapSize} + for i := 1; i < int(childMap.Count()); i++ { + elementByteSizes[i] = [2]uint32{encodedKeySize, encodedValueSize} + } + expectedChildMapSize := ComputeInlinedMapSlabByteSize(elementByteSizes) require.Equal(t, expectedChildMapSize, GetMapRootSlabByteSize(childMap)) testMap(t, storage, typeInfo, address, parentMap, expectedKeyValues, nil, true) @@ -18505,7 +18686,7 @@ func TestNestedThreeLevelChildMapInlinabilityInParentMap(t *testing.T) { testMap(t, storage, typeInfo, address, parentMap, expectedKeyValues, nil, true) } - expectedChildMapSize := uint32(inlinedMapDataSlabPrefixSize + hkeyElementsPrefixSize) + expectedChildMapSize := emptyInlinedMapByteSize require.Equal(t, expectedChildMapSize, GetMapRootSlabByteSize(childMap)) require.Equal(t, uint64(0), childMap.Count()) @@ -18517,19 +18698,21 @@ func TestNestedThreeLevelChildMapInlinabilityInParentMap(t *testing.T) { testMap(t, storage, typeInfo, address, parentMap, expectedKeyValues, nil, true) - expectedChildMapSize := uint32(inlinedMapDataSlabPrefixSize + hkeyElementsPrefixSize) - expectedParentMapSize = mapRootDataSlabPrefixSize + hkeyElementsPrefixSize + - (digestSize+singleElementPrefixSize+encodedKeySize+expectedChildMapSize)*uint32(mapCount) + expectedChildMapSize := emptyInlinedMapByteSize + expectedParentMapSize = ComputeMapRootDataSlabByteSizeWithFixSizedElement( + encodedKeySize, + expectedChildMapSize, + mapCount, + ) require.Equal(t, expectedParentMapSize, GetMapRootSlabByteSize(parentMap)) }) } func TestChildMapWhenParentMapIsModified(t *testing.T) { const ( - mapCount = 2 - keyStringSize = 4 - valueStringSize = 4 - expectedEmptyInlinedMapSize = uint32(inlinedMapDataSlabPrefixSize + hkeyElementsPrefixSize) // 22 + mapCount = 2 + keyStringSize = 4 + valueStringSize = 4 ) // encoded key size is the same for all string keys of the same length. @@ -18575,12 +18758,14 @@ func TestChildMapWhenParentMapIsModified(t *testing.T) { testInlinedMapIDs(t, address, childMap) // Test child map slab size - require.Equal(t, expectedEmptyInlinedMapSize, GetMapRootSlabByteSize(childMap)) + require.Equal(t, emptyInlinedMapByteSize, GetMapRootSlabByteSize(childMap)) // Test parent map slab size - expectedParentElementSize := singleElementPrefixSize + digestSize + encodedKeySize + expectedEmptyInlinedMapSize - expectedParentSize := uint32(mapRootDataSlabPrefixSize+hkeyElementsPrefixSize) + // standalone map data slab with 0 element - expectedParentElementSize*uint32(i+1) + expectedParentSize := ComputeMapRootDataSlabByteSizeWithFixSizedElement( + encodedKeySize, + emptyInlinedMapByteSize, + i+1, + ) require.Equal(t, expectedParentSize, GetMapRootSlabByteSize(parentMap)) } @@ -18642,9 +18827,11 @@ func TestChildMapWhenParentMapIsModified(t *testing.T) { require.Equal(t, childValueID, childMap.ValueID()) // Value ID is unchanged // Test inlined child slab size - expectedChildElementSize := singleElementPrefixSize + digestSize + k.ByteSize() + v.ByteSize() - expectedChildMapSize := inlinedMapDataSlabPrefixSize + hkeyElementsPrefixSize + - expectedChildElementSize*uint32(childMap.Count()) + expectedChildMapSize := ComputeInlinedMapSlabByteSizeWithFixSizedElement( + k.ByteSize(), + v.ByteSize(), + int(childMap.Count()), + ) require.Equal(t, expectedChildMapSize, GetMapRootSlabByteSize(childMap)) testMap(t, storage, typeInfo, address, parentMap, expectedKeyValues, nil, true) @@ -18689,9 +18876,11 @@ func TestChildMapWhenParentMapIsModified(t *testing.T) { require.Equal(t, childValueID, childMap.ValueID()) // Value ID is unchanged // Test inlined child slab size - expectedChildElementSize := singleElementPrefixSize + digestSize + k.ByteSize() + v.ByteSize() - expectedChildMapSize := inlinedMapDataSlabPrefixSize + hkeyElementsPrefixSize + - expectedChildElementSize*uint32(childMap.Count()) + expectedChildMapSize := ComputeInlinedMapSlabByteSizeWithFixSizedElement( + k.ByteSize(), + v.ByteSize(), + int(childMap.Count()), + ) require.Equal(t, expectedChildMapSize, GetMapRootSlabByteSize(childMap)) testMap(t, storage, typeInfo, address, parentMap, expectedKeyValues, nil, true) @@ -18708,9 +18897,7 @@ func createMapWithEmptyChildMap( typeInfo TypeInfo, mapCount int, getKey func() Value, -) (*OrderedMap, map[Value]Value) { - - const expectedEmptyInlinedMapSize = uint32(inlinedMapDataSlabPrefixSize + hkeyElementsPrefixSize) // 22 +) (*OrderedMap, map[Value]Value, map[Value][2]uint32) { // Create parent map parentMap, err := NewMap(storage, address, NewDefaultDigesterBuilder(), typeInfo) @@ -18718,6 +18905,8 @@ func createMapWithEmptyChildMap( expectedKeyValues := make(map[Value]Value) + elementByteSizesByKey := make(map[Value][2]uint32) + for i := 0; i < mapCount; i++ { // Create child map childMap, err := NewMap(storage, address, NewDefaultDigesterBuilder(), typeInfo) @@ -18739,16 +18928,20 @@ func createMapWithEmptyChildMap( testInlinedMapIDs(t, address, childMap) // Test child map slab size - require.Equal(t, expectedEmptyInlinedMapSize, GetMapRootSlabByteSize(childMap)) + require.Equal(t, emptyInlinedMapByteSize, GetMapRootSlabByteSize(childMap)) // Test parent map slab size - expectedParentElementSize := singleElementPrefixSize + digestSize + ks.ByteSize() + expectedEmptyInlinedMapSize - expectedParentSize := uint32(mapRootDataSlabPrefixSize+hkeyElementsPrefixSize) + // standalone map data slab with 0 element - expectedParentElementSize*uint32(i+1) + expectedParentSize := ComputeMapRootDataSlabByteSizeWithFixSizedElement( + ks.ByteSize(), + emptyInlinedMapByteSize, + i+1, + ) require.Equal(t, expectedParentSize, GetMapRootSlabByteSize(parentMap)) + + elementByteSizesByKey[k] = [2]uint32{ks.ByteSize(), emptyInlinedMapByteSize} } - return parentMap, expectedKeyValues + return parentMap, expectedKeyValues, elementByteSizesByKey } func createMapWithEmpty2LevelChildMap( @@ -18758,9 +18951,7 @@ func createMapWithEmpty2LevelChildMap( typeInfo TypeInfo, mapCount int, getKey func() Value, -) (*OrderedMap, map[Value]Value) { - - const expectedEmptyInlinedMapSize = uint32(inlinedMapDataSlabPrefixSize + hkeyElementsPrefixSize) // 22 +) (*OrderedMap, map[Value]Value, map[Value][2]uint32) { // Create parent map parentMap, err := NewMap(storage, address, NewDefaultDigesterBuilder(), typeInfo) @@ -18768,6 +18959,8 @@ func createMapWithEmpty2LevelChildMap( expectedKeyValues := make(map[Value]Value) + elementByteSizesByKey := make(map[Value][2]uint32) + for i := 0; i < mapCount; i++ { // Create child map childMap, err := NewMap(storage, address, NewDefaultDigesterBuilder(), typeInfo) @@ -18801,24 +18994,30 @@ func createMapWithEmpty2LevelChildMap( testInlinedMapIDs(t, address, childMap) // Test grand child map slab size - require.Equal(t, expectedEmptyInlinedMapSize, GetMapRootSlabByteSize(gchildMap)) + require.Equal(t, emptyInlinedMapByteSize, GetMapRootSlabByteSize(gchildMap)) // Test child map slab size - expectedChildElementSize := singleElementPrefixSize + digestSize + ks.ByteSize() + expectedEmptyInlinedMapSize - expectedChildMapSize := inlinedMapDataSlabPrefixSize + hkeyElementsPrefixSize + - expectedChildElementSize*uint32(childMap.Count()) + expectedChildMapSize := ComputeInlinedMapSlabByteSizeWithFixSizedElement( + ks.ByteSize(), + emptyInlinedMapByteSize, + int(childMap.Count()), + ) require.Equal(t, expectedChildMapSize, GetMapRootSlabByteSize(childMap)) // Test parent map slab size - expectedParentElementSize := singleElementPrefixSize + digestSize + ks.ByteSize() + expectedChildMapSize - expectedParentSize := uint32(mapRootDataSlabPrefixSize+hkeyElementsPrefixSize) + // standalone map data slab with 0 element - expectedParentElementSize*uint32(i+1) + expectedParentSize := ComputeMapRootDataSlabByteSizeWithFixSizedElement( + ks.ByteSize(), + expectedChildMapSize, + i+1, + ) require.Equal(t, expectedParentSize, GetMapRootSlabByteSize(parentMap)) + + elementByteSizesByKey[k] = [2]uint32{ks.ByteSize(), expectedChildMapSize} } testNotInlinedMapIDs(t, address, parentMap) - return parentMap, expectedKeyValues + return parentMap, expectedKeyValues, elementByteSizesByKey } type mapInfo struct { diff --git a/utils_test.go b/utils_test.go index a4cead1..41bb134 100644 --- a/utils_test.go +++ b/utils_test.go @@ -497,3 +497,9 @@ func IsMapRootDataSlab(m *OrderedMap) bool { func GetMapRootSlabByteSize(m *OrderedMap) uint32 { return GetMapRootSlab(m).ByteSize() } + +var ( + slabIDStorableByteSize = SlabIDStorable{}.ByteSize() + emptyInlinedArrayByteSize = ComputeInlinedArraySlabByteSize(nil) + emptyInlinedMapByteSize = ComputeInlinedMapSlabByteSize(nil) +)