optimzed differenceRunBitmap

This commit is contained in:
Todd Gruben 2017-09-20 13:23:09 -05:00 committed by Travis
parent 3f3cc60531
commit de2f16b617
No known key found for this signature in database
GPG key ID: 7F08008DFD9314C9
2 changed files with 51 additions and 11 deletions

View file

@ -2531,15 +2531,46 @@ func differenceRunArray(a, b *container) *container {
// differenceRunBitmap computes the difference of an run from a bitmap.
func differenceRunBitmap(a, b *container) *container {
if a.n == 0 || b.n == 0 {
return a.clone()
}
// If a is full, difference is the flip of b.
if a.runs[0].start == 0 && a.runs[0].last == 65535 {
return b.flipBitmap()
}
itr := newBufBitmapIterator(newBitmapIterator(b.bitmap))
return differenceRunIterator(a, itr)
output := &container{container_type: ContainerRun}
output.n = a.n
for j := 0; j < len(a.runs); j++ {
run := a.runs[j]
for bit := a.runs[j].start; bit <= a.runs[j].last; bit++ {
if b.bitmapContains(bit) {
output.n--
if run.start == bit {
run.start++
} else if bit == run.last {
run.last--
} else {
run.last = bit - 1
if run.last >= run.start {
output.runs = append(output.runs, run)
}
run.start = bit + 1
run.last = a.runs[j].last
}
if run.start > run.last {
break
}
}
}
if run.start <= run.last {
output.runs = append(output.runs, run)
}
}
if output.n < ArrayMaxSize && int(len(output.runs)) > output.n/2 {
output.runToArray()
} else if len(output.runs) > RunMaxSize {
output.runToBitmap()
}
return output
}
func differenceRunIterator(a *container, itr containerIterator) *container {

View file

@ -1464,6 +1464,15 @@ func TestDifferenceRunArray(t *testing.T) {
}
}
}
func MakeBitmap(start []uint64) []uint64 {
b := make([]uint64, bitmapN)
for i, v := range start {
b[i] = v
}
return b
}
func TestDifferenceRunBitmap(t *testing.T) {
a := &container{}
@ -1475,32 +1484,32 @@ func TestDifferenceRunBitmap(t *testing.T) {
}{
{
runs: []interval16{{start: 0, last: 63}},
bitmap: []uint64{0x0000FFFF000000F0},
bitmap: MakeBitmap([]uint64{0x0000FFFF000000F0}),
exp: []interval16{{start: 0, last: 3}, {start: 8, last: 31}, {start: 48, last: 63}},
},
{
runs: []interval16{{start: 0, last: 63}},
bitmap: []uint64{0x8000000000000000},
bitmap: MakeBitmap([]uint64{0x8000000000000000}),
exp: []interval16{{start: 0, last: 62}},
},
{
runs: []interval16{{start: 0, last: 63}},
bitmap: []uint64{0x0000000000000001},
bitmap: MakeBitmap([]uint64{0x0000000000000001}),
exp: []interval16{{start: 1, last: 63}},
},
{
runs: []interval16{{start: 0, last: 63}},
bitmap: []uint64{0x0, 0x0000000000000001},
bitmap: MakeBitmap([]uint64{0x0, 0x0000000000000001}),
exp: []interval16{{start: 0, last: 63}},
},
{
runs: []interval16{{start: 0, last: 65}},
bitmap: []uint64{0x0, 0x0000000000000001},
bitmap: MakeBitmap([]uint64{0x0, 0x0000000000000001}),
exp: []interval16{{start: 0, last: 63}, {start: 65, last: 65}},
},
{
runs: []interval16{{start: 0, last: 65}},
bitmap: []uint64{0x0, 0x8000000000000000},
bitmap: MakeBitmap([]uint64{0x0, 0x8000000000000000}),
exp: []interval16{{start: 0, last: 65}},
},
}