re-implement differenceRunArray to not use iterator

hopefully less heap allocs and better perf now
This commit is contained in:
Matthew Jaffee 2017-09-22 01:02:41 -05:00 committed by Travis
parent a863f4f422
commit fd73eaa5cb
No known key found for this signature in database
GPG key ID: 7F08008DFD9314C9
2 changed files with 55 additions and 3 deletions

View file

@ -2451,13 +2451,50 @@ func differenceBitmapRun(a, b *container) *container {
return output
}
// differenceRunArray computes the difference of an run from a array.
// differenceRunArray subtracts the bits in an array container from a run
// container.
func differenceRunArray(a, b *container) *container {
if a.n == 0 || b.n == 0 {
return a.clone()
}
itr := newArrayIterator(b.array)
return differenceRunIterator(a, itr)
output := &container{runs: make([]interval16, 0, len(a.runs)), container_type: ContainerRun}
bidx := 0
vb := b.array[bidx]
for _, run := range a.runs {
start := run.start
for vb < run.start {
bidx++
if bidx >= len(b.array) {
break
}
vb = b.array[bidx]
}
for vb >= run.start && vb <= run.last {
if vb == start {
start++
bidx++
if bidx >= len(b.array) {
break
}
vb = b.array[bidx]
continue
}
output.runs = append(output.runs, interval16{start: start, last: vb - 1})
start = vb + 1
bidx++
if bidx >= len(b.array) {
break
}
vb = b.array[bidx]
}
if start <= run.last {
output.runs = append(output.runs, interval16{start: start, last: run.last})
}
}
output.Optimize()
return output
}
// differenceRunBitmap computes the difference of an run from a bitmap.

View file

@ -1449,6 +1449,21 @@ func TestDifferenceRunArray(t *testing.T) {
array: []uint16{0, 9, 10, 11, 12, 13},
exp: []interval16{{start: 1, last: 8}},
},
{
runs: []interval16{{start: 1, last: 12}, {start: 14, last: 14}, {start: 18, last: 18}},
array: []uint16{0, 9, 10, 11, 12, 13, 14, 17},
exp: []interval16{{start: 1, last: 8}, {start: 18, last: 18}},
},
{
runs: []interval16{{start: 1, last: 12}, {start: 14, last: 14}, {start: 18, last: 18}},
array: []uint16{0, 9, 10, 11, 12, 13, 14, 17, 19},
exp: []interval16{{start: 1, last: 8}, {start: 18, last: 18}},
},
{
runs: []interval16{{start: 1, last: 12}, {start: 14, last: 17}, {start: 19, last: 28}},
array: []uint16{0, 9, 10, 11, 12, 13, 14, 17, 19, 25, 27},
exp: []interval16{{start: 1, last: 8}, {start: 15, last: 16}, {start: 20, last: 24}, {start: 26, last: 26}, {start: 28, last: 28}},
},
}
for i, test := range tests {
a.runs = test.runs