From f4f07c0aa2ac6cc7fd7ed4b3c3188a18c9f84204 Mon Sep 17 00:00:00 2001 From: Todd Gruben Date: Sat, 10 Jun 2017 08:17:53 -0500 Subject: [PATCH] extended xor tests; updated comments --- roaring/roaring.go | 24 ++++++++++++++---------- roaring/roaring_internal_test.go | 30 ++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 10 deletions(-) diff --git a/roaring/roaring.go b/roaring/roaring.go index 2da7511b1..25c8c6d53 100644 --- a/roaring/roaring.go +++ b/roaring/roaring.go @@ -2911,6 +2911,7 @@ func assert(condition bool, format string, a ...interface{}) { } } +// xorArrayRun computes the exclusive or of an array and a run container. func xorArrayRun(a, b *container) *container { output := &container{} na, nb := len(a.array), len(b.runs) @@ -2966,7 +2967,8 @@ func xorArrayRun(a, b *container) *container { return output } -func xorCompare(x *stm) (r1 interval32, has_data bool) { +// xorCompare computes first exclusive run between two runs. +func xorCompare(x *xorstm) (r1 interval32, has_data bool) { has_data = false if !x.va_valid || !x.vb_valid { if x.vb_valid { @@ -2984,18 +2986,18 @@ func xorCompare(x *stm) (r1 interval32, has_data bool) { return } - if x.va.last < x.vb.start { //a before + if x.va.last < x.vb.start { //va before x.va_valid = false r1 = x.va has_data = true - } else if x.vb.last < x.va.start { // b before + } else if x.vb.last < x.va.start { //vb before x.vb_valid = false r1 = x.va has_data = true } else if x.va.start == x.vb.start && x.va.last == x.vb.last { // Equal x.va_valid = false x.vb_valid = false - } else if x.va.start <= x.vb.start && x.va.last >= x.vb.last { // b inside + } else if x.va.start <= x.vb.start && x.va.last >= x.vb.last { //vb inside x.vb_valid = false if x.va.start != x.vb.start { r1 = interval32{start: x.va.start, last: x.vb.start - 1} @@ -3006,7 +3008,7 @@ func xorCompare(x *stm) (r1 interval32, has_data bool) { x.va_valid = false } - } else if x.vb.start <= x.va.start && x.vb.last >= x.va.last { //a inside + } else if x.vb.start <= x.va.start && x.vb.last >= x.va.last { //va inside x.va_valid = false if x.vb.start != x.va.start { r1 = interval32{start: x.vb.start, last: x.va.start - 1} @@ -3018,7 +3020,7 @@ func xorCompare(x *stm) (r1 interval32, has_data bool) { x.vb_valid = false } - } else if x.va.start < x.vb.start && x.va.last <= x.vb.last { //a first overlap + } else if x.va.start < x.vb.start && x.va.last <= x.vb.last { //va first overlap x.va_valid = false r1 = interval32{start: x.va.start, last: x.vb.start - 1} has_data = true @@ -3026,7 +3028,7 @@ func xorCompare(x *stm) (r1 interval32, has_data bool) { if x.vb.start > x.vb.last { x.vb_valid = false } - } else if x.vb.start < x.va.start && x.vb.last <= x.va.last { //b first overlap + } else if x.vb.start < x.va.start && x.vb.last <= x.va.last { //vb first overlap x.vb_valid = false r1 = interval32{start: x.vb.start, last: x.va.start - 1} has_data = true @@ -3038,11 +3040,13 @@ func xorCompare(x *stm) (r1 interval32, has_data bool) { return } -type stm struct { +//stm is state machine used to "xor" iterate over runs. +type xorstm struct { va_valid, vb_valid bool va, vb interval32 } +// xorRunRun computes the exclusive or of two run containers. func xorRunRun(a, b *container) *container { na, nb := len(a.runs), len(b.runs) if na == 0 { @@ -3055,9 +3059,9 @@ func xorRunRun(a, b *container) *container { last_i, last_j := -1, -1 - state := &stm{} + state := &xorstm{} - for i, j := 0, 0; i < na || j < nb; { //how to terminate? + for i, j := 0, 0; i < na || j < nb; { if i < na && last_i != i { state.va = a.runs[i] state.va_valid = true diff --git a/roaring/roaring_internal_test.go b/roaring/roaring_internal_test.go index c9607f5a8..deb92f34e 100644 --- a/roaring/roaring_internal_test.go +++ b/roaring/roaring_internal_test.go @@ -1314,6 +1314,36 @@ func TestXorRunRun(t *testing.T) { bruns: []interval32{{start: 5, last: 10}}, exp: []interval32{{start: 5, last: 10}}, }, + { + aruns: []interval32{{start: 0, last: 4}}, + bruns: []interval32{{start: 6, last: 10}}, + exp: []interval32{{start: 0, last: 4}, {start: 6, last: 10}}, + }, + { + aruns: []interval32{{start: 0, last: 6}}, + bruns: []interval32{{start: 4, last: 10}}, + exp: []interval32{{start: 0, last: 3}, {start: 7, last: 10}}, + }, + { + aruns: []interval32{{start: 4, last: 10}}, + bruns: []interval32{{start: 0, last: 6}}, + exp: []interval32{{start: 0, last: 3}, {start: 7, last: 10}}, + }, + { + aruns: []interval32{{start: 0, last: 10}}, + bruns: []interval32{{start: 0, last: 6}}, + exp: []interval32{{start: 7, last: 10}}, + }, + { + aruns: []interval32{{start: 0, last: 6}}, + bruns: []interval32{{start: 0, last: 10}}, + exp: []interval32{{start: 7, last: 10}}, + }, + { + aruns: []interval32{{start: 0, last: 6}}, + bruns: []interval32{{start: 0, last: 10}}, + exp: []interval32{{start: 7, last: 10}}, + }, { aruns: []interval32{{start: 5, last: 12}}, bruns: []interval32{{start: 5, last: 10}},