From 50dab75c829666441a7c3c02157275c26b7fa733 Mon Sep 17 00:00:00 2001 From: Todd Gruben Date: Fri, 15 Sep 2017 21:57:23 -0500 Subject: [PATCH] optimize unionArrayBitmap --- roaring/roaring.go | 31 ++++++------------------------- roaring/roaring_internal_test.go | 16 ++++++++++------ 2 files changed, 16 insertions(+), 31 deletions(-) diff --git a/roaring/roaring.go b/roaring/roaring.go index 0ee541514..151ab7f2c 100644 --- a/roaring/roaring.go +++ b/roaring/roaring.go @@ -2378,33 +2378,14 @@ func (c *container) bitmapZeroRange(i, j uint64) { } func unionArrayBitmap(a, b *container) *container { - output := &container{container_type: ContainerArray} - itr := newBufBitmapIterator(newBitmapIterator(b.bitmap)) - for i := 0; ; { - vb, eof := itr.next() - if i >= len(a.array) && eof { - break - } else if i >= len(a.array) { - output.add(vb) - continue - } else if eof { - output.add(a.array[i]) - i++ - continue - } - - va := a.array[i] - if va < vb { - output.add(va) - i++ - itr.unread() - } else if va > vb { - output.add(vb) - } else { - output.add(va) - i++ + output := b.clone() + for _, v := range a.array { + if !output.bitmapContains(v) { + output.bitmap[v/64] |= (1 << uint64(v%64)) + output.n++ } } + return output } diff --git a/roaring/roaring_internal_test.go b/roaring/roaring_internal_test.go index d33a4d513..e711fecc8 100644 --- a/roaring/roaring_internal_test.go +++ b/roaring/roaring_internal_test.go @@ -647,7 +647,6 @@ func TestIntersectBitmapRunArray(t *testing.T) { func TestUnionMixed(t *testing.T) { a := &container{} b := &container{} - c := &container{} a.runs = []interval16{{start: 5, last: 10}} a.container_type = ContainerRun @@ -669,24 +668,30 @@ func TestUnionMixed(t *testing.T) { if !reflect.DeepEqual(res.runs, []interval16{{start: 5, last: 10}}) { t.Fatalf("test #3 expected %v, but got %v", []interval16{{start: 5, last: 10}}, res.runs) } - c.bitmap = []uint64{0x3} + + c := &container{bitmap: make([]uint64, bitmapN)} + c.bitmap[0] = uint64(0x3) c.n = 2 c.container_type = ContainerBitmap + expected := make([]uint64, bitmapN) + expected[0] = uint64(2019) + res = union(c, a) - if !reflect.DeepEqual(res.bitmap, []uint64{2019}) { + if !reflect.DeepEqual(res.bitmap, expected) { t.Fatalf("test #4 expected %v, but got %v", []uint64{2019}, res.bitmap) } res = union(a, c) - if !reflect.DeepEqual(res.bitmap, []uint64{2019}) { + if !reflect.DeepEqual(res.bitmap, expected) { t.Fatalf("test #5 expected %v, but got %v", []uint64{2019}, res.bitmap) } - res = union(b, c) + res.bitmapToArray() //just added so test setup was easier if !reflect.DeepEqual(res.array, []uint16{0, 1, 4, 5, 7, 10, 11, 12}) { t.Fatalf("test #6 expected %v, but got %v", []uint16{0, 1, 4, 5, 7, 10, 11, 12}, res.array) } res = union(c, b) + res.bitmapToArray() //just added so test setup was easier if !reflect.DeepEqual(res.array, []uint16{0, 1, 4, 5, 7, 10, 11, 12}) { t.Fatalf("test #6 expected %v, but got %v", []uint16{0, 1, 4, 5, 7, 10, 11, 12}, res.array) } @@ -793,7 +798,6 @@ func TestDifferenceMixed(t *testing.T) { } res = difference(c, b) - fmt.Println(res) if !reflect.DeepEqual(res.array, []uint16{5}) { t.Fatalf("test #7 expected %v, but got %v", []uint16{5}, res.array) }