From 0c3f61a42675f704ee3b9c6fd29660941dbcd70e Mon Sep 17 00:00:00 2001 From: Matt Jaffee Date: Thu, 18 May 2017 17:22:13 -0500 Subject: [PATCH] implement intersectArrayRun --- roaring/roaring.go | 42 ++++++++++++++++++++++++++++++++ roaring/roaring_internal_test.go | 40 ++++++++++++++++++++++++++++++ 2 files changed, 82 insertions(+) diff --git a/roaring/roaring.go b/roaring/roaring.go index 09d173ede..1d8ef1223 100644 --- a/roaring/roaring.go +++ b/roaring/roaring.go @@ -1603,12 +1603,24 @@ func intersect(a, b *container) *container { if a.isArray() { if b.isArray() { return intersectArrayArray(a, b) + } else if b.isRun() { + return intersectArrayRun(a, b) } else { return intersectArrayBitmap(a, b) } + } else if a.isRun() { + if b.isArray() { + return intersectArrayRun(b, a) + } else if b.isRun() { + return intersectRunRun(a, b) + } else { + return intersectBitmapRun(b, a) + } } else { if b.isArray() { return intersectArrayBitmap(b, a) + } else if b.isRun() { + return intersectBitmapRun(a, b) } else { return intersectBitmapBitmap(a, b) } @@ -1633,6 +1645,36 @@ func intersectArrayArray(a, b *container) *container { return output } +func intersectArrayRun(a, b *container) *container { + output := &container{} + 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] + if va < vb.start { + i++ + } else if va > vb.last { + j++ + } else { + output.array = append(output.array, va) + output.n++ + i++ + } + } + return output +} + +func intersectRunRun(a, b *container) *container { + output := &container{} + // TODO + return output +} + +func intersectBitmapRun(a, b *container) *container { + output := &container{} + // TODO + return output +} + func intersectArrayBitmap(a, b *container) *container { output := &container{} itr := newBufIterator(newBitmapIterator(b.bitmap)) diff --git a/roaring/roaring_internal_test.go b/roaring/roaring_internal_test.go index ec022305c..8f771a1fe 100644 --- a/roaring/roaring_internal_test.go +++ b/roaring/roaring_internal_test.go @@ -350,3 +350,43 @@ func TestIntersectionCountRunRun(t *testing.T) { } } } + +func TestIntersectArrayRun(t *testing.T) { + a := &container{} + b := &container{} + tests := []struct { + array []uint32 + runs []interval32 + exp []uint32 + }{ + { + array: []uint32{1, 4, 5, 7, 10, 11, 12}, + runs: []interval32{{start: 5, last: 10}}, + exp: []uint32{5, 7, 10}, + }, + { + array: []uint32{}, + runs: []interval32{{start: 5, last: 10}}, + exp: []uint32(nil), + }, + { + array: []uint32{1, 4, 5, 7, 10, 11, 12}, + runs: []interval32{}, + exp: []uint32(nil), + }, + { + array: []uint32{0, 1, 4, 5, 7, 10, 11, 12}, + runs: []interval32{{start: 0, last: 5}, {start: 7, last: 7}}, + exp: []uint32{0, 1, 4, 5, 7}, + }, + } + + for i, test := range tests { + a.array = test.array + b.runs = test.runs + ret := intersectArrayRun(a, b) + if !reflect.DeepEqual(ret.array, test.exp) { + t.Fatalf("test #%v expected %v, but got %v", i, test.exp, ret.array) + } + } +}