From a0d98cfb30c48f121751885b93d0d1c0aae2011f Mon Sep 17 00:00:00 2001 From: Todd Gruben Date: Thu, 15 Jun 2017 11:13:34 -0500 Subject: [PATCH] support for difference of run and bitmap --- roaring/roaring.go | 55 ++++++++++++++++++++++++++------ roaring/roaring_internal_test.go | 28 ++++++++++++++-- 2 files changed, 71 insertions(+), 12 deletions(-) diff --git a/roaring/roaring.go b/roaring/roaring.go index f5bda8cf6..354bda36e 100644 --- a/roaring/roaring.go +++ b/roaring/roaring.go @@ -2540,7 +2540,6 @@ func differenceRunArray(a, b *container) *container { // differenceRunBitmap computes the difference of an run from a bitmap. func differenceRunBitmap(a, b *container) *container { - // TODO if a.n == 0 || b.n == 0 { return a.clone() } @@ -2548,16 +2547,54 @@ func differenceRunBitmap(a, b *container) *container { output := &container{runs: make([]interval32, 0, a.n)} itr := newBufIterator(newBitmapIterator(b.bitmap)) - for i := 0; ; { - vb, eof := itr.next() - if eof { - break + vb, eof := itr.next() + j := 0 + vr := a.runs[j] + working := !eof + for working { + switch { + case vb < vr.start: //before + case vb > vr.last: //after + if vr.start <= vr.last { + output.n += output.runAppendInterval(vr) + } + j++ + if j < len(a.runs) { + vr = a.runs[j] + } else { + working = false + } + case vb == vr.start: //begining of run + vr.start++ + case vb == a.runs[j].last: //end of run + vr.last-- + if vr.last >= vr.start { + output.n += output.runAppendInterval(vr) + } + j++ + if j < len(a.runs) { + vr = a.runs[j] + } else { + working = false + } + case vb > vr.start: //inside run + output.n += output.runAppendInterval(interval32{start: vr.start, last: vb - 1}) + vr.start = vb + 1 + + } + vb, eof = itr.next() + if eof { + working = false } - fmt.Println(i, vb) - - i++ } - + if vr.start <= vr.last { + output.n += output.runAppendInterval(vr) + } + if output.n < ArrayMaxSize && len(output.runs) > output.n/2 { + output.runToArray() + } else if len(output.runs) > RunMaxSize { + output.runToBitmap() + } return output } diff --git a/roaring/roaring_internal_test.go b/roaring/roaring_internal_test.go index 0c4bf8e0d..29b95f52d 100644 --- a/roaring/roaring_internal_test.go +++ b/roaring/roaring_internal_test.go @@ -1164,8 +1164,6 @@ func TestDifferenceRunArray(t *testing.T) { } } -/* - func TestDifferenceRunBitmap(t *testing.T) { a := &container{} b := &container{bitmap: make([]uint64, bitmapN)} @@ -1179,6 +1177,31 @@ func TestDifferenceRunBitmap(t *testing.T) { bitmap: []uint64{0x0000FFFF000000F0}, exp: []interval32{{start: 0, last: 3}, {start: 8, last: 31}, {start: 48, last: 63}}, }, + { + runs: []interval32{{start: 0, last: 63}}, + bitmap: []uint64{0x8000000000000000}, + exp: []interval32{{start: 0, last: 62}}, + }, + { + runs: []interval32{{start: 0, last: 63}}, + bitmap: []uint64{0x0000000000000001}, + exp: []interval32{{start: 1, last: 63}}, + }, + { + runs: []interval32{{start: 0, last: 63}}, + bitmap: []uint64{0x0, 0x0000000000000001}, + exp: []interval32{{start: 0, last: 63}}, + }, + { + runs: []interval32{{start: 0, last: 65}}, + bitmap: []uint64{0x0, 0x0000000000000001}, + exp: []interval32{{start: 0, last: 63}, {start: 65, last: 65}}, + }, + { + runs: []interval32{{start: 0, last: 65}}, + bitmap: []uint64{0x0, 0x8000000000000000}, + exp: []interval32{{start: 0, last: 65}}, + }, } for i, test := range tests { a.runs = test.runs @@ -1193,7 +1216,6 @@ func TestDifferenceRunBitmap(t *testing.T) { } } } -*/ func TestDifferenceBitmapRun(t *testing.T) { a := &container{bitmap: make([]uint64, bitmapN)}