Merge pull request #949 from tgruben/range-bug

fix overflow in differenceRunBitmap
This commit is contained in:
tgruben 2017-11-14 18:07:20 -06:00 • committed by GitHub
commit 0dfbba370d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 34 additions and 5 deletions

View file

@ -2508,17 +2508,25 @@ func differenceRunArray(a, b *container) *container {
// differenceRunBitmap computes the difference of an run from a bitmap.
func differenceRunBitmap(a, b *container) *container {
// If a is full, difference is the flip of b.
if a.runs[0].start == 0 && a.runs[0].last == 65535 {
if len(a.runs) > 0 && a.runs[0].start == 0 && a.runs[0].last == 65535 {
return b.flipBitmap()
}
output := &container{container_type: ContainerRun}
output.n = a.n
if len(a.runs) == 0 {
return output
}
for j := 0; j < len(a.runs); j++ {
run := a.runs[j]
add := true
for bit := a.runs[j].start; bit <= a.runs[j].last; bit++ {
if b.bitmapContains(bit) {
output.n--
if run.start == bit {
if bit == 65535 { //overflow
add = false
}
run.start++
} else if bit == run.last {
run.last--
@ -2534,10 +2542,15 @@ func differenceRunBitmap(a, b *container) *container {
break
}
}
if bit == 65535 { //overflow
break
}
}
if run.start <= run.last {
output.runs = append(output.runs, run)
if add {
output.runs = append(output.runs, run)
}
}
}

View file

@ -1485,6 +1485,12 @@ func MakeBitmap(start []uint64) []uint64 {
}
return b
}
func MakeLastBitSet() []uint64 {
obj := NewBitmap(65535)
c := obj.container(0)
c.arrayToBitmap()
return c.bitmap
}
func TestDifferenceRunBitmap(t *testing.T) {
a := &container{}
@ -1524,14 +1530,24 @@ func TestDifferenceRunBitmap(t *testing.T) {
bitmap: MakeBitmap([]uint64{0x0, 0x8000000000000000}),
exp: []interval16{{start: 0, last: 65}},
},
{
runs: []interval16{{start: 1, last: 65535}},
bitmap: MakeBitmap([]uint64{0x0000000000000001}),
exp: []interval16{{start: 1, last: 65535}},
},
{
runs: []interval16{{start: 0, last: 65533}, {start: 65535, last: 65535}},
bitmap: MakeLastBitSet(),
exp: []interval16{{start: 0, last: 65533}},
},
}
for i, test := range tests {
a.runs = test.runs
a.n = a.runCountRange(0, 100)
a.n = a.runCountRange(0, 65536)
for i, v := range test.bitmap {
b.bitmap[i] = v
}
b.n = b.bitmapCountRange(0, 100)
b.n = b.bitmapCountRange(0, 65536)
ret := differenceRunBitmap(a, b)
if !reflect.DeepEqual(ret.runs, test.exp) {
t.Fatalf("test #%v expected %v, but got %v", i, test.exp, ret.runs)