CountRange was incorrect if rangekey was prior to inital container

This commit is contained in:
Todd Gruben 2017-08-09 14:06:22 -05:00
parent a5d2a7a705
commit 93257af5d2
3 changed files with 37 additions and 4 deletions

View file

@ -274,7 +274,8 @@ func (f *Fragment) openCache() error {
// Read in all rows by ID.
// This will cause them to be added to the cache.
for _, id := range pb.IDs {
n := f.row(id, false, false).Count()
//n := f.row(id, false, false).Count()
n := f.storage.CountRange(id*SliceWidth, (id+1)*SliceWidth)
f.cache.BulkAdd(id, n)
}
f.cache.Invalidate()

View file

@ -197,9 +197,14 @@ func (b *Bitmap) Count() (n uint64) {
// CountRange returns the number of bits set between [start, end).
func (b *Bitmap) CountRange(start, end uint64) (n uint64) {
if len(b.keys) == 0 {
return
}
skey := highbits(start)
ekey := highbits(end)
i := search64(b.keys, highbits(start))
j := search64(b.keys, highbits(end))
i := search64(b.keys, skey)
j := search64(b.keys, ekey)
// If range is entirely in one container then just count that range.
if i >= 0 && i == j {
@ -208,7 +213,13 @@ func (b *Bitmap) CountRange(start, end uint64) (n uint64) {
// Count first partial container.
if i < 0 {
i = -i
// start is before container, so we should start counting
// at first container that has value
if skey < b.keys[0] {
i = -1
} else {
i = -i
}
} else {
n += uint64(b.containers[i].countRange(int(lowbits(start)), maxContainerVal+1))
}

View file

@ -191,6 +191,27 @@ func TestBitmap_Max(t *testing.T) {
}
}
}
func TestBitmap_BitmapCountRangeBug(t *testing.T) {
s := uint64(2009 * 1048576)
e := uint64(2010 * 1048576)
start := s + (39314024 % 1048576)
bm0 := roaring.NewBitmap()
for i := uint64(0); i < 65536; i++ {
if (i+1)%4096 == 0 {
start += 16384
} else {
start += 2
}
bm0.Add(start)
}
a := bm0.Count()
r := bm0.CountRange(s, e)
if a != r {
t.Fatalf("Counts != CountRange %v %v", a, r)
}
}
func TestBitmap_BitmapCountRange(t *testing.T) {
bm0 := roaring.NewBitmap(0, 2683177)