Merge pull request #674 from travisturner/fix-differencearrayrun-logic

bug fix in `differenceArrayRun` logic.
This commit is contained in:
Travis Turner 2017-06-22 16:26:09 -05:00 committed by GitHub
commit 987f7ca3bf
2 changed files with 41 additions and 13 deletions

View file

@ -453,7 +453,6 @@ func (b *Bitmap) Difference(other *Bitmap) *Bitmap {
}
}
return output
}
@ -2488,29 +2487,37 @@ func differenceArrayRun(a, b *container) *container {
i := 0 // array index
j := 0 // run index
// keep all array elements before beginning of runs
for ; i < len(a.array) && a.array[i] < b.runs[j].start; i++ {
output.array = append(output.array, a.array[i])
}
// handle overlap
for ; i < a.n; i++ {
// if array element in run, keep
if !(a.array[i] >= b.runs[j].start && a.array[i] <= b.runs[j].last) {
output.array = append(output.array, a.array[i])
for i < a.n {
// keep all array elements before beginning of runs
if a.array[i] < b.runs[j].start {
output.add(a.array[i])
i++
continue
}
// update current run
if a.array[i] >= b.runs[j].last {
// if array element in run, skip it
if a.array[i] >= b.runs[j].start && a.array[i] <= b.runs[j].last {
i++
continue
}
// if array element larger than current run, check next run
if a.array[i] > b.runs[j].last {
j++
if j == len(b.runs) {
break
}
}
}
i++
if i < len(a.array) {
// keep all array elements after end of runs
output.array = append(output.array, a.array[i:]...)
// TODO: consider handling container.n mutations in one place
// like we do with container.add().
output.n += len(a.array[i:])
}
return output
}

View file

@ -246,6 +246,7 @@ func TestBitmap_Difference(t *testing.T) {
t.Fatalf("unexpected n: %d", n)
}
}
func TestBitmap_Difference_Empty(t *testing.T) {
bm0 := roaring.NewBitmap(0, 2683177)
bm1 := roaring.NewBitmap()
@ -255,6 +256,26 @@ func TestBitmap_Difference_Empty(t *testing.T) {
}
}
func TestBitmap_DifferenceArrayArray(t *testing.T) {
bm0 := roaring.NewBitmap(0, 4, 8, 12, 16, 20)
bm1 := roaring.NewBitmap(1, 3, 6, 9, 12, 15, 18)
result := bm0.Difference(bm1)
if n := result.Count(); n != 5 {
t.Fatalf("unexpected n: %d", n)
}
}
func TestBitmap_DifferenceArrayRun(t *testing.T) {
bm0 := roaring.NewBitmap(0, 4, 8, 12, 16, 20, 36, 40, 44)
bm1 := roaring.NewBitmap(1, 2, 3, 4, 5, 6, 7, 8, 9, 30, 31, 32, 33, 34, 35, 36)
bm1.Optimize() // convert to runs
result := bm0.Difference(bm1)
if n := result.Count(); n != 6 {
t.Fatalf("unexpected n: %d", n)
}
}
func TestBitmap_Union(t *testing.T) {
bm0 := roaring.NewBitmap(0, 1000001, 1000002, 1000003)
bm1 := roaring.NewBitmap(0, 50000, 1000001, 1000002)