unionArrayRun implementation

This commit is contained in:
Matt Jaffee 2017-05-30 15:57:32 -05:00
parent c5a0f23257
commit 97346baa94
2 changed files with 65 additions and 3 deletions

View file

@ -1860,8 +1860,31 @@ func unionArrayArray(a, b *container) *container {
return output
}
// unionArrayRun optimistically assumes that the result will be a run container,
// and converts to a bitmap or array container afterwards if necessary.
func unionArrayRun(a, b *container) *container {
return nil
output := &container{}
na, nb := len(a.array), len(b.runs)
var vb interval32
var va uint32
for i, j := 0, 0; i < na || j < nb; {
if i < na {
va = a.array[i]
}
if j < nb {
vb = b.runs[j]
}
if i < na && (j >= nb || va < vb.start) {
output.runAppendInterval(interval32{start: va, last: va})
i++
} else {
output.runAppendInterval(vb)
j++
}
}
return output
}
func (c *container) runAppendInterval(v interval32) {
if len(c.runs) == 0 {
c.runs = append(c.runs, v)
@ -1880,9 +1903,8 @@ func unionRunRun(a, b *container) *container {
output := &container{
runs: make([]interval32, 0, na+nb),
}
i, j := 0, 0
var va, vb interval32
for i < na || j < nb {
for i, j := 0, 0; i < na || j < nb; {
if i < na {
va = a.runs[i]
}

View file

@ -584,3 +584,43 @@ func TestUnionRunRun(t *testing.T) {
}
}
}
func TestUnionArrayRun(t *testing.T) {
a := &container{}
b := &container{}
tests := []struct {
array []uint32
runs []interval32
exp []interval32
}{
{
array: []uint32{1, 4, 5, 7, 10, 11, 12},
runs: []interval32{{start: 5, last: 10}},
exp: []interval32{{start: 1, last: 1}, {start: 4, last: 12}},
},
{
array: []uint32{},
runs: []interval32{{start: 5, last: 10}},
exp: []interval32{{start: 5, last: 10}},
},
{
array: []uint32{1, 4, 5, 7, 10, 11, 12},
runs: []interval32{},
exp: []interval32{{start: 1, last: 1}, {start: 4, last: 5}, {start: 7, last: 7}, {start: 10, last: 12}},
},
{
array: []uint32{0, 1, 4, 5, 7, 10, 11, 12},
runs: []interval32{{start: 0, last: 5}, {start: 7, last: 7}},
exp: []interval32{{start: 0, last: 5}, {start: 7, last: 7}, {start: 10, last: 12}},
},
}
for i, test := range tests {
a.array = test.array
b.runs = test.runs
ret := unionArrayRun(a, b)
if !reflect.DeepEqual(ret.runs, test.exp) {
t.Fatalf("test #%v expected %v, but got %v", i, test.exp, ret.array)
}
}
}