fixed seeking end of run container iteration bug when next container exists and ensure roaringparanoia panics before other ops

This commit is contained in:
shaqque 2019-06-24 15:18:03 -05:00
parent a6ba7e339c
commit 86e703637b
2 changed files with 27 additions and 16 deletions

View file

@ -431,6 +431,12 @@ func (b *Bitmap) Size() int {
// CountRange returns the number of bits set between [start, end).
func (b *Bitmap) CountRange(start, end uint64) (n uint64) {
if roaringParanoia {
if start > end {
panic(fmt.Sprintf("counting in range but %v > %v", start, end))
}
}
if b.Containers.Size() == 0 {
return
}
@ -452,11 +458,7 @@ func (b *Bitmap) CountRange(start, end uint64) (n uint64) {
// TODO remove once we've validated this stuff works
panic("should be impossible for k to be less than skey")
}
if roaringParanoia {
if start > end {
panic(fmt.Sprintf("counting in range but %v > %v", start, end))
}
}
// k > ekey handles the case when start > end and where start and end
// are in different containers. Same container case is already handled above.
if k > ekey {
@ -1380,6 +1382,9 @@ func (itr *Iterator) Seek(seek uint64) {
itr.c = nil
return
}
itr.key, itr.c = itr.citer.Value()
itr.j = -1
return
}
// Set iterator to next value in the Bitmap.
itr.j = j
@ -1387,7 +1392,7 @@ func (itr *Iterator) Seek(seek uint64) {
return
}
// If it's a bitmap container then move to index before the value and call next().
// If it's a bitmap container then move to index before the value.
if itr.key > hb {
itr.j = -1
return
@ -1540,14 +1545,14 @@ func (c *Container) count() (n int32) {
// countRange counts the number of bits set between [start, end).
func (c *Container) countRange(start, end int32) (n int32) {
if c == nil {
return 0
}
if roaringParanoia {
if start > end {
panic(fmt.Sprintf("counting in range but %v > %v", start, end))
}
}
if c == nil {
return 0
}
if c.isArray() {
return c.arrayCountRange(start, end)
} else if c.isRun() {

View file

@ -2132,19 +2132,16 @@ func TestIteratorBitmap(t *testing.T) {
// Test for seeking value not in bitmap, where next container that the iterator should
// go to has values with low bits smaller than the low bits of seek.
for i := uint64(65536*3 + 2); i < 65536*3+7; i++ {
if i != 65536*3+5 {
for i := uint64(65536*3 + 2); i < 65536*3+4110; i++ {
if i != 65536*3+5 && i != 65536*3+7 {
if _, err := b.Add(i); err != nil {
t.Fatalf("adding bit: %v", err)
}
}
}
for i := uint64(65536*3 + 8); i < 65536*3+4110; i++ {
if _, err := b.Add(i); err != nil {
t.Fatalf("adding bit: %v", err)
}
}
// We expect this to be a bitmap container because more than
// 4096 bits have been set, but Optimize() has not been called.
if !b.Containers.Get(3).isBitmap() {
t.Fatalf("wrong container type")
}
@ -2214,6 +2211,15 @@ func TestIteratorRuns(t *testing.T) {
t.Fatalf("iterator did not seek correctly to end of run: %v\n", itr)
}
itr.Seek(1007)
if !(itr.key == 1 && itr.j == -1 && itr.k == -1) {
t.Fatalf("iterator did not seek correctly to end of run: %v\n", itr)
}
val, eof = itr.Next()
if !(val == 100000 && !eof) {
t.Fatalf("iterator did not next correctly across containers: %v, %v", val, itr)
}
itr.Seek(100005)
if !(itr.key == 1 && itr.j == 0 && itr.k == 4) {
t.Fatalf("iterator did not seek correctly in multiple containers: %v\n", itr)