From d541e6197382cb76850d9b4f50ee424351522e47 Mon Sep 17 00:00:00 2001 From: Daniel Lemire Date: Mon, 5 Aug 2024 11:38:04 -0400 Subject: [PATCH] more fixes regarding issue 440 --- arraycontainer.go | 2 -- roaring_test.go | 24 ++++++++++++++++++++++++ runcontainer.go | 11 ++++------- 3 files changed, 28 insertions(+), 9 deletions(-) diff --git a/arraycontainer.go b/arraycontainer.go index c07010bf..2e75c5ad 100644 --- a/arraycontainer.go +++ b/arraycontainer.go @@ -1227,12 +1227,10 @@ func (ac *arrayContainer) numberOfRuns() (nr int) { // convert to run or array *if needed* func (ac *arrayContainer) toEfficientContainer() container { numRuns := ac.numberOfRuns() - sizeAsRunContainer := runContainer16SerializedSizeInBytes(numRuns) sizeAsBitmapContainer := bitmapContainerSizeInBytes() card := ac.getCardinality() sizeAsArrayContainer := arrayContainerSizeInBytes(card) - if sizeAsRunContainer < minOfInt(sizeAsBitmapContainer, sizeAsArrayContainer) { return newRunContainer16FromArray(ac) } diff --git a/roaring_test.go b/roaring_test.go index f1b2909b..cd299bc1 100644 --- a/roaring_test.go +++ b/roaring_test.go @@ -49,6 +49,30 @@ func TestIssue440_3(t *testing.T) { require.Equal(t, b1, b2) } +func TestIssue440_4(t *testing.T) { + a := NewBitmap() + a.AddMany([]uint32{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}) + a.RunOptimize() + b1, err := a.MarshalBinary() + require.NoError(t, err) + a.RunOptimize() + b2, err := a.MarshalBinary() + require.NoError(t, err) + require.Equal(t, b1, b2) +} + +func TestIssue440_5(t *testing.T) { + a := NewBitmap() + a.AddMany([]uint32{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}) + a.RunOptimize() + b1, err := a.MarshalBinary() + require.NoError(t, err) + a.RunOptimize() + b2, err := a.MarshalBinary() + require.NoError(t, err) + require.Equal(t, b1, b2) +} + func checkValidity(t *testing.T, rb *Bitmap) { t.Helper() diff --git a/runcontainer.go b/runcontainer.go index d67380e2..6270c8c2 100644 --- a/runcontainer.go +++ b/runcontainer.go @@ -42,7 +42,6 @@ import ( "errors" "fmt" "sort" - "unsafe" ) // runContainer16 does run-length encoding of sets of @@ -1013,12 +1012,10 @@ func newRunContainer16TakeOwnership(iv []interval16) *runContainer16 { } const ( - baseRc16Size = int(unsafe.Sizeof(runContainer16{})) - perIntervalRc16Size = int(unsafe.Sizeof(interval16{})) + baseRc16Size = 2 + perIntervalRc16Size = 4 ) -const baseDiskRc16Size = int(unsafe.Sizeof(uint16(0))) - // see also runContainer16SerializedSizeInBytes(numRuns int) int // getSizeInBytes returns the number of bytes of memory @@ -1030,7 +1027,7 @@ func (rc *runContainer16) getSizeInBytes() int { // runContainer16SerializedSizeInBytes returns the number of bytes of disk // required to hold numRuns in a runContainer16. func runContainer16SerializedSizeInBytes(numRuns int) int { - return perIntervalRc16Size*numRuns + baseDiskRc16Size + return perIntervalRc16Size*numRuns + baseRc16Size } // Add adds a single value k to the set. @@ -2521,7 +2518,7 @@ func (rc *runContainer16) toEfficientContainer() container { sizeAsBitmapContainer := bitmapContainerSizeInBytes() card := rc.getCardinality() sizeAsArrayContainer := arrayContainerSizeInBytes(card) - if sizeAsRunContainer > minOfInt(sizeAsBitmapContainer, sizeAsArrayContainer) { + if sizeAsRunContainer < minOfInt(sizeAsBitmapContainer, sizeAsArrayContainer) { return rc } if card <= arrayDefaultMaxSize {