fixed overflow in interval16 runlen; added rle tests

This commit is contained in:
Todd Gruben 2017-08-01 16:25:11 -05:00
parent 6c4f37ae70
commit a3f3ca3c5a
3 changed files with 41 additions and 4 deletions

View file

@ -948,7 +948,7 @@ type interval16 struct {
// runlen returns the count of integers in the interval.
func (iv interval16) runlen() int {
return int(1 + iv.last - iv.start)
return 1 + int(iv.last-iv.start)
}
// newContainer returns a new instance of container.
@ -958,17 +958,17 @@ func newContainer() *container {
// isArray returns true if the container is an array container.
func (c *container) isArray() bool {
return c.bitmap == nil && c.runs == nil
return c.container_type == ContainerArray
}
// isBitmap returns true if the container is a bitmap container.
func (c *container) isBitmap() bool {
return c.array == nil && c.runs == nil
return c.container_type == ContainerBitmap
}
// isRun returns true if the container is a run-length-encoded container.
func (c *container) isRun() bool {
return c.array == nil && c.bitmap == nil
return c.container_type == ContainerRun
}
// unmap creates copies of the containers data in the heap.
@ -1507,6 +1507,7 @@ func (c *container) bitmapToRun() {
}
if current == maxBitmap {
// bitmap[1023] == maxBitmap
c.runs = append(c.runs, interval16{start, maxContainerVal})
break

View file

@ -1022,6 +1022,15 @@ func TestRunToBitmap(t *testing.T) {
}
}
func getFullBitmap() []uint64 {
x := make([]uint64, 1024, 1024)
for i := range x {
x[i] = uint64(0xFFFFFFFFFFFFFFFF)
}
return x
}
func TestBitmapToRun(t *testing.T) {
a := &container{}
tests := []struct {
@ -1072,6 +1081,10 @@ func TestBitmapToRun(t *testing.T) {
bitmap: make([]uint64, bitmapN),
exp: []interval16{{start: 65408, last: 65535}},
},
{
bitmap: getFullBitmap(),
exp: []interval16{{start: 0, last: 65535}},
},
}
tests[8].bitmap[1022] = 0xFFFFFFFFFFFFFFFF
tests[8].bitmap[1023] = 0xFFFFFFFFFFFFFFFF
@ -1084,10 +1097,15 @@ func TestBitmapToRun(t *testing.T) {
n += int(popcount(v))
}
a.n = n
x := a.bitmap
a.bitmapToRun()
if !reflect.DeepEqual(a.runs, test.exp) {
t.Fatalf("test #%v expected %v, but got %v", i, test.exp, a.runs)
}
a.runToBitmap()
if !reflect.DeepEqual(a.bitmap, x) {
t.Fatalf("test #%v expected %v, but got %v", i, a.bitmap, x)
}
}
}

View file

@ -87,6 +87,24 @@ func TestCheckRun(t *testing.T) {
t.Fatalf("%v\n", err)
}
}
func TestCheckFullRun(t *testing.T) {
b := roaring.NewBitmap()
for i := uint64(0); i < 2097152; i++ {
if i%16384 == 0 {
b.Optimize() // convert to runs
}
b.Add(i)
}
err := b.Check()
if err != nil {
t.Fatalf("Before %v\n", err)
}
b.Optimize() // convert to runs
err = b.Check()
if err != nil {
t.Fatalf("After %v\n", err)
}
}
// Ensure that we can transition between runs and arrays when materializing the bitmap.
func TestContainerTransitions(t *testing.T) {