fix roaring array append

This commit fixes a bug where appends to an array container did
not cause it to roll over to a bitmap container when it reached
the max array size.
This commit is contained in:
Ben Johnson 2016-01-09 12:27:20 -07:00
parent 9bbf9f1955
commit 039ca1d91b
2 changed files with 22 additions and 11 deletions

View file

@ -439,7 +439,7 @@ func (c *container) add(v uint16) {
func (c *container) arrayAdd(v uint16) {
// Optimize appending to the end of an array container.
if c.n > 0 && c.isArray() && c.array[c.n-1] < v {
if c.n > 0 && c.n < arrayMaxSize && c.isArray() && c.array[c.n-1] < v {
c.unmap()
c.array = append(c.array, v)
c.n++

View file

@ -117,21 +117,27 @@ func testBitmapQuick(t *testing.T, n int, min, max uint64) {
return true
}, &quick.Config{
Values: func(values []reflect.Value, rand *rand.Rand) {
values[0] = reflect.ValueOf(GenerateUint64Slice(n, min, max, rand))
values[0] = reflect.ValueOf(GenerateUint64Slice(n, min, max, false, rand))
},
})
}
func TestBitmap_Marshal_Quick_Array1(t *testing.T) { testBitmapMarshalQuick(t, 1000, 1000, 2000) }
func TestBitmap_Marshal_Quick_Array2(t *testing.T) { testBitmapMarshalQuick(t, 10000, 0, 1000) }
func TestBitmap_Marshal_Quick_Bitmap1(t *testing.T) { testBitmapMarshalQuick(t, 10000, 0, 10000) }
func TestBitmap_Marshal_Quick_Bitmap2(t *testing.T) { testBitmapMarshalQuick(t, 10000, 10000, 20000) }
func TestBitmap_Marshal_Quick_Array1(t *testing.T) { testBitmapMarshalQuick(t, 1000, 1000, 2000, false) }
func TestBitmap_Marshal_Quick_Array2(t *testing.T) { testBitmapMarshalQuick(t, 10000, 0, 1000, false) }
func TestBitmap_Marshal_Quick_Bitmap1(t *testing.T) { testBitmapMarshalQuick(t, 10000, 0, 10000, false) }
func TestBitmap_Marshal_Quick_Bitmap2(t *testing.T) {
testBitmapMarshalQuick(t, 10000, 10000, 20000, false)
}
func TestBitmap_Marshal_Quick_LargeValue(t *testing.T) {
testBitmapMarshalQuick(t, 100, 0, math.MaxInt64)
testBitmapMarshalQuick(t, 100, 0, math.MaxInt64, false)
}
func TestBitmap_Marshal_Quick_Bitmap_Sorted(t *testing.T) {
testBitmapMarshalQuick(t, 10000, 0, 10000, true)
}
// Ensure a bitmap can be marshaled and unmarshaled.
func testBitmapMarshalQuick(t *testing.T, n int, min, max uint64) {
func testBitmapMarshalQuick(t *testing.T, n int, min, max uint64, sorted bool) {
if testing.Short() {
t.Skip("short")
}
@ -186,18 +192,23 @@ func testBitmapMarshalQuick(t *testing.T, n int, min, max uint64) {
return true
}, &quick.Config{
Values: func(values []reflect.Value, rand *rand.Rand) {
values[0] = reflect.ValueOf(GenerateUint64Slice(n, min, max, rand))
values[1] = reflect.ValueOf(GenerateUint64Slice(100, min, max, rand))
values[0] = reflect.ValueOf(GenerateUint64Slice(n, min, max, sorted, rand))
values[1] = reflect.ValueOf(GenerateUint64Slice(100, min, max, sorted, rand))
},
})
}
// GenerateUint64Slice generates between [0, n) random uint64 numbers between min and max.
func GenerateUint64Slice(n int, min, max uint64, rand *rand.Rand) []uint64 {
func GenerateUint64Slice(n int, min, max uint64, sorted bool, rand *rand.Rand) []uint64 {
a := make([]uint64, rand.Intn(n))
for i := range a {
a[i] = min + uint64(rand.Int63n(int64(max-min)))
}
if sorted {
sort.Sort(uint64Slice(a))
}
return a
}