From c5a0f23257e13d6829dc3ba07f6294f3faf559ce Mon Sep 17 00:00:00 2001 From: Matt Jaffee Date: Tue, 30 May 2017 15:05:08 -0500 Subject: [PATCH] clean up unionRunRun --- roaring/roaring.go | 76 +++++++++----------------------- roaring/roaring_internal_test.go | 26 ++++++++++- 2 files changed, 47 insertions(+), 55 deletions(-) diff --git a/roaring/roaring.go b/roaring/roaring.go index 201e2be21..c032a83cd 100644 --- a/roaring/roaring.go +++ b/roaring/roaring.go @@ -1862,73 +1862,41 @@ func unionArrayArray(a, b *container) *container { func unionArrayRun(a, b *container) *container { return nil +func (c *container) runAppendInterval(v interval32) { + if len(c.runs) == 0 { + c.runs = append(c.runs, v) + } else { + lastidx := len(c.runs) - 1 + if c.runs[lastidx].last+1 >= v.start && v.last > c.runs[lastidx].last { + c.runs[lastidx].last = v.last + } else if c.runs[lastidx].last+1 < v.start { + c.runs = append(c.runs, v) + } + } } func unionRunRun(a, b *container) *container { na, nb := len(a.runs), len(b.runs) - if na == 0 { - return b.clone() - } else if nb == 0 { - return a.clone() - } output := &container{ runs: make([]interval32, 0, na+nb), } i, j := 0, 0 - if a.runs[0].start < b.runs[0].start { - output.runs = append(output.runs, a.runs[0]) - i = 1 - } else { - output.runs = append(output.runs, b.runs[0]) - j = 1 - } - for i < na && j < nb { - va, vb := a.runs[i], b.runs[j] - lastrun := output.runs[len(output.runs)-1] - if va.start < vb.start { - if va.start <= lastrun.last+1 { - if lastrun.last < va.last { - lastrun.last = va.last - output.runs[len(output.runs)-1] = lastrun - } - } else { - output.runs = append(output.runs, va) - } + var va, vb interval32 + for i < na || j < nb { + if i < na { + va = a.runs[i] + } + if j < nb { + vb = b.runs[j] + } + if i < na && (j >= nb || va.start < vb.start) { + output.runAppendInterval(va) i++ } else { - if vb.start <= lastrun.last+1 { - if lastrun.last < vb.last { - lastrun.last = vb.last - output.runs[len(output.runs)-1] = lastrun - } - } else { - output.runs = append(output.runs, vb) - } + output.runAppendInterval(vb) j++ } } - var k int - var rest []interval32 - if i < na { - k = i - rest = a.runs - } else { - k = j - rest = b.runs - } - for k < len(rest) { - vk := rest[k] - lastrun := output.runs[len(output.runs)-1] - if vk.start <= lastrun.last+1 { - if lastrun.last < vk.last { - lastrun.last = vk.last - output.runs[len(output.runs)-1] = lastrun - } - } else { - output.runs = append(output.runs, vk) - } - k++ - } return output } diff --git a/roaring/roaring_internal_test.go b/roaring/roaring_internal_test.go index 0231bf93f..5c8e46f93 100644 --- a/roaring/roaring_internal_test.go +++ b/roaring/roaring_internal_test.go @@ -549,6 +549,31 @@ func TestUnionRunRun(t *testing.T) { bruns: []interval32{{start: 5, last: 10}}, exp: []interval32{{start: 1, last: 3}, {start: 5, last: 12}}, }, + { + aruns: []interval32{{start: 1, last: 3}, {start: 5, last: 5}, {start: 7, last: 8}, {start: 9, last: 12}}, + bruns: []interval32{{start: 2, last: 65535}}, + exp: []interval32{{start: 1, last: 65535}}, + }, + { + aruns: []interval32{{start: 2, last: 65535}}, + bruns: []interval32{{start: 1, last: 3}, {start: 5, last: 5}, {start: 7, last: 8}, {start: 9, last: 12}}, + exp: []interval32{{start: 1, last: 65535}}, + }, + { + aruns: []interval32{{start: 1, last: 3}, {start: 5, last: 5}, {start: 7, last: 8}, {start: 9, last: 12}}, + bruns: []interval32{{start: 0, last: 65535}}, + exp: []interval32{{start: 0, last: 65535}}, + }, + { + aruns: []interval32{{start: 0, last: 65535}}, + bruns: []interval32{{start: 1, last: 3}, {start: 5, last: 5}, {start: 7, last: 8}, {start: 9, last: 12}}, + exp: []interval32{{start: 0, last: 65535}}, + }, + { + aruns: []interval32{{start: 1, last: 3}, {start: 5, last: 5}, {start: 7, last: 9}, {start: 12, last: 22}}, + bruns: []interval32{{start: 2, last: 8}, {start: 16, last: 27}, {start: 33, last: 34}}, + exp: []interval32{{start: 1, last: 9}, {start: 12, last: 27}, {start: 33, last: 34}}, + }, } for i, test := range tests { a.runs = test.aruns @@ -558,5 +583,4 @@ func TestUnionRunRun(t *testing.T) { t.Fatalf("test #%v expected %v, but got %v", i, test.exp, ret.runs) } } - }