From fbdce18f70bf0369c2370e9c58140f1930fc45bb Mon Sep 17 00:00:00 2001 From: Todd Gruben Date: Thu, 3 Aug 2017 14:30:37 -0500 Subject: [PATCH] overflow in intersectionCountRunRun --- roaring/roaring.go | 33 +++++++++++++++--------------- roaring/roaring_internal_test.go | 35 +++++++++++++++++++++++++++++--- 2 files changed, 48 insertions(+), 20 deletions(-) diff --git a/roaring/roaring.go b/roaring/roaring.go index a9284139c..65b47ca7e 100644 --- a/roaring/roaring.go +++ b/roaring/roaring.go @@ -336,7 +336,7 @@ func (b *Bitmap) IntersectionCount(other *Bitmap) uint64 { } else if ki > kj { j++ } else { - n += intersectionCount(b.containers[i], other.containers[j]) + n += uint64(intersectionCount(b.containers[i], other.containers[j])) i, j = i+1, j+1 } } @@ -1717,7 +1717,7 @@ type ContainerInfo struct { Pointer unsafe.Pointer // offset within the mmap } -func intersectionCount(a, b *container) uint64 { +func intersectionCount(a, b *container) int { if a.isArray() { if b.isArray() { return intersectionCountArrayArray(a, b) @@ -1745,7 +1745,7 @@ func intersectionCount(a, b *container) uint64 { } } -func intersectionCountArrayArray(a, b *container) (n uint64) { +func intersectionCountArrayArray(a, b *container) (n int) { na, nb := len(a.array), len(b.array) for i, j := 0, 0; i < na && j < nb; { va, vb := a.array[i], b.array[j] @@ -1761,7 +1761,7 @@ func intersectionCountArrayArray(a, b *container) (n uint64) { return n } -func intersectionCountArrayRun(a, b *container) (n uint64) { +func intersectionCountArrayRun(a, b *container) (n int) { na, nb := len(a.array), len(b.runs) for i, j := 0, 0; i < na && j < nb; { va, vb := a.array[i], b.runs[j] @@ -1777,8 +1777,7 @@ func intersectionCountArrayRun(a, b *container) (n uint64) { return n } -func intersectionCountRunRun(a, b *container) uint64 { - var n uint16 +func intersectionCountRunRun(a, b *container) (n int) { na, nb := len(a.runs), len(b.runs) for i, j := 0, 0; i < na && j < nb; { va, vb := a.runs[i], b.runs[j] @@ -1790,28 +1789,28 @@ func intersectionCountRunRun(a, b *container) uint64 { j++ } else if va.last > vb.last && va.start >= vb.start { // |--vb-|-|-va--| - n += 1 + vb.last - va.start + n += 1 + int(vb.last-va.start) j++ } else if va.last > vb.last && va.start < vb.start { // |--va|--vb--|--| - n += 1 + vb.last - vb.start + n += 1 + int(vb.last-vb.start) j++ } else if va.last <= vb.last && va.start >= vb.start { // |--vb|--va--|--| - n += 1 + va.last - va.start + n += 1 + int(va.last-va.start) i++ } else if va.last <= vb.last && va.start < vb.start { // |--va-|-|-vb--| - n += 1 + va.last - vb.start + n += 1 + int(va.last-vb.start) i++ } } - return uint64(n) + return } -func intersectionCountBitmapRun(a, b *container) (n uint64) { +func intersectionCountBitmapRun(a, b *container) (n int) { for _, iv := range b.runs { - n += uint64(a.bitmapCountRange(int(iv.start), int(iv.last)+1)) + n += a.bitmapCountRange(int(iv.start), int(iv.last)+1) } return n } @@ -1858,20 +1857,20 @@ func intersectionCountArrayBitmapOld(a, b *container) (n uint64) { return n } -func intersectionCountArrayBitmap(a, b *container) (n uint64) { +func intersectionCountArrayBitmap(a, b *container) (n int) { for _, val := range a.array { i := val >> 6 if i >= uint16(len(b.bitmap)) { break } off := val % 64 - n += (b.bitmap[i] & (1 << off)) >> off + n += int((b.bitmap[i] & (1 << off)) >> off) } return n } -func intersectionCountBitmapBitmap(a, b *container) (n uint64) { - return popcntAndSlice(a.bitmap, b.bitmap) +func intersectionCountBitmapBitmap(a, b *container) (n int) { + return int(popcntAndSlice(a.bitmap, b.bitmap)) } func intersect(a, b *container) *container { diff --git a/roaring/roaring_internal_test.go b/roaring/roaring_internal_test.go index 89741b0e3..ea4e5f0ef 100644 --- a/roaring/roaring_internal_test.go +++ b/roaring/roaring_internal_test.go @@ -225,12 +225,39 @@ func TestBitmapCountRange(t *testing.T) { } } +func TestIntersectionCountArrayBitmap3(t *testing.T) { + a, b := &container{}, &container{} + a.container_type = ContainerBitmap + a.bitmap = getFullBitmap() + a.n = maxContainerVal + 1 + + b.container_type = ContainerBitmap + b.bitmap = getFullBitmap() + b.n = maxContainerVal + 1 + res := intersectBitmapBitmap(a, b) + if res.n != res.count() || res.n != maxContainerVal+1 { + t.Fatalf("test #1 intersectCountBitmapBitmap fail orig: %v new: %v exp: %v", res.n, res.count(), maxContainerVal+1) + } + + a.bitmapToRun() + res = intersectBitmapRun(b, a) + if res.n != res.count() || res.n != maxContainerVal+1 { + t.Fatalf("test #2 intersectCountBitmapRun fail orig: %v new: %v exp: %v", res.n, res.count(), maxContainerVal+1) + } + b.bitmapToRun() + res = intersectRunRun(a, b) + n := intersectionCountRunRun(a, b) + if res.n != res.count() || res.n != maxContainerVal+1 || res.n != int(n) { + t.Fatalf("test #3 intersectCountRunRun fail orig: %v new: %v exp: %v", res.n, res.count(), maxContainerVal+1) + } +} + func TestIntersectionCountArrayBitmap2(t *testing.T) { a, b := &container{}, &container{} tests := []struct { array []uint16 bitmap []uint64 - exp uint64 + exp int }{ { array: []uint16{0}, @@ -261,8 +288,10 @@ func TestIntersectionCountArrayBitmap2(t *testing.T) { for i, test := range tests { a.array = test.array + a.container_type = ContainerArray b.bitmap = test.bitmap - ret1 := intersectionCountArrayBitmapOld(a, b) + b.container_type = ContainerBitmap + ret1 := int(intersectionCountArrayBitmapOld(a, b)) ret2 := intersectionCountArrayBitmap(a, b) if ret1 != ret2 || ret2 != test.exp { t.Fatalf("test #%v intersectCountArrayBitmap fail orig: %v new: %v exp: %v", i, ret1, ret2, test.exp) @@ -352,7 +381,7 @@ func TestIntersectionCountRunRun(t *testing.T) { tests := []struct { aruns []interval16 bruns []interval16 - exp uint64 + exp int }{ { aruns: []interval16{},