diff --git a/roaring/roaring.go b/roaring/roaring.go index 7b1d24666..80ac665f5 100644 --- a/roaring/roaring.go +++ b/roaring/roaring.go @@ -1414,7 +1414,7 @@ func (c *container) runRemove(v uint32) bool { } else if v > c.runs[i].start { last := c.runs[i].last c.runs[i].last = v - 1 - c.runs = append(c.runs[:i+1], append([]interval32{{start: v+1, last: last}}, c.runs[i+1:]...)...) + c.runs = append(c.runs[:i+1], append([]interval32{{start: v + 1, last: last}}, c.runs[i+1:]...)...) } return true } @@ -2687,26 +2687,28 @@ func differenceArrayBitmap(a, b *container) *container { func differenceBitmapArray(a, b *container) *container { output := &container{} itr := newBufIterator(newBitmapIterator(a.bitmap)) - array := b.array + i := 0 + va, eof := itr.next() for { - va, eof := itr.next() if eof { break } - if len(array) == 0 { + if i >= len(b.array) { output.add(va) + va, eof = itr.next() continue } - vb := array[0] + vb := b.array[i] if va < vb { output.add(va) + va, eof = itr.next() } else if va > vb { - array = array[1:] - itr.unread() + i++ } else { - array = array[1:] + i++ + va, eof = itr.next() } } return output @@ -2716,19 +2718,25 @@ func differenceBitmapBitmap(a, b *container) *container { output := &container{} itr0 := newBufIterator(newBitmapIterator(a.bitmap)) itr1 := newBufIterator(newBitmapIterator(b.bitmap)) + v0, eof0 := itr0.next() + v1, eof1 := itr1.next() for { - v0, eof0 := itr0.next() - v1, eof1 := itr1.next() - if eof0 { break } else if eof1 { output.add(v0) - } else if v0 < v1 { + v0, eof0 = itr0.next() + continue + } + if v0 < v1 { output.add(v0) - itr1.unread() + v0, eof0 = itr0.next() } else if v0 > v1 { - itr0.unread() + v1, eof1 = itr1.next() + } else { + v0, eof0 = itr0.next() + v1, eof1 = itr1.next() + } } return output diff --git a/roaring/roaring_internal_test.go b/roaring/roaring_internal_test.go index 7d35779ce..77c5af89c 100644 --- a/roaring/roaring_internal_test.go +++ b/roaring/roaring_internal_test.go @@ -1307,6 +1307,58 @@ func TestDifferenceBitmapRun(t *testing.T) { } } +func TestDifferenceBitmapArray(t *testing.T) { + a := &container{bitmap: make([]uint64, bitmapN)} + b := &container{} + tests := []struct { + bitmap []uint64 + array []uint32 + exp []uint32 + }{ + { + bitmap: []uint64{0xFF0F}, + array: []uint32{0, 1, 2, 3, 4, 5, 6, 7, 10}, + exp: []uint32{8, 9, 11, 12, 13, 14, 15}, + }, + } + for i, test := range tests { + a.bitmap = test.bitmap + b.array = test.array + ret := differenceBitmapArray(a, b) + if !reflect.DeepEqual(ret.array, test.exp) { + t.Fatalf("test #%v expected \n%X, but got \n%X", i, test.exp, ret.array) + } + } +} +func TestDifferenceBitmapBitmap(t *testing.T) { + a := &container{bitmap: make([]uint64, bitmapN)} + b := &container{bitmap: make([]uint64, bitmapN)} + tests := []struct { + abitmap []uint64 + bbitmap []uint64 + exp []uint32 + }{ + { + abitmap: []uint64{0xFF00FFFFFFFFFFFF}, + bbitmap: []uint64{0xFFFFFFFFFFFFF000}, + exp: []uint32{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}, + }, + { + abitmap: []uint64{0xF}, + bbitmap: []uint64{}, + exp: []uint32{0, 1, 2, 3}, + }, + } + for i, test := range tests { + a.bitmap = test.abitmap + b.bitmap = test.bbitmap + ret := differenceBitmapBitmap(a, b) + if !reflect.DeepEqual(ret.array, test.exp) { + t.Fatalf("test #%v expected \n%X, but got \n%X", i, test.exp, ret.array) + } + } +} + func TestDifferenceRunRun(t *testing.T) { a := &container{} b := &container{}