cmd/segment-reaper: Fix bitArray.IsSequence method
The bitArray.IsSequence method had a bug that caused that sometimes the test "Bitmask/IsSequence/sequence starts at other index than 0" to fail due to it uses random values. The test mostly found a corner case, I've added new tests to catch the bug and then apply the fix. Change-Id: If01dc07006d261ba40bbd99d36ef776e09ed3efc
This commit is contained in:
parent
e23bd806b4
commit
50e8314279
@ -74,12 +74,32 @@ func (bytes *bitArray) Count() int {
|
||||
// IsSequence returns true if mask has only tracked a correlative sequence of
|
||||
// indexes starting from index 0.
|
||||
func (bytes *bitArray) IsSequence() bool {
|
||||
ones := bytes.Count()
|
||||
zeros := 0
|
||||
for byteIndex := len(*bytes) - 1; byteIndex >= 0 && zeros%8 == 0; byteIndex-- {
|
||||
zeros = bits.LeadingZeros8((*bytes)[byteIndex])
|
||||
// find the last byte of the sequence that contains some one
|
||||
var i int
|
||||
for i = len(*bytes) - 1; i >= 0; i-- {
|
||||
zeros := bits.LeadingZeros8((*bytes)[i])
|
||||
if zeros == 8 {
|
||||
continue
|
||||
}
|
||||
return (zeros + ones) == len(*bytes)*8
|
||||
|
||||
ones := bits.OnesCount8((*bytes)[i])
|
||||
if zeros+ones != 8 {
|
||||
// zeros and ones in this byte aren't in sequence
|
||||
return false
|
||||
}
|
||||
|
||||
break
|
||||
}
|
||||
|
||||
// The rest of the bytes of the sequence must only contains ones
|
||||
i--
|
||||
for ; i >= 0; i-- {
|
||||
if (*bytes)[i] != 255 {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
// Length returns the current size of the array in bits.
|
||||
|
@ -186,36 +186,6 @@ func TestBitmask(t *testing.T) {
|
||||
assert.True(t, ok)
|
||||
})
|
||||
|
||||
t.Run("sequence started index 0", func(t *testing.T) {
|
||||
var (
|
||||
numIndexes = rand.Intn(61) + 2
|
||||
bits bitArray
|
||||
)
|
||||
|
||||
for i := 0; i < numIndexes; i++ {
|
||||
err := bits.Set(i)
|
||||
require.NoError(t, err, "Set")
|
||||
}
|
||||
|
||||
ok := bits.IsSequence()
|
||||
assert.True(t, ok)
|
||||
})
|
||||
|
||||
t.Run("sequence started other index than 0", func(t *testing.T) {
|
||||
var (
|
||||
startIndex = rand.Intn(62) + 1
|
||||
bits bitArray
|
||||
)
|
||||
|
||||
for i := startIndex; i < 64; i++ {
|
||||
err := bits.Set(i)
|
||||
require.NoError(t, err, "Set")
|
||||
}
|
||||
|
||||
ok := bits.IsSequence()
|
||||
assert.False(t, ok)
|
||||
})
|
||||
|
||||
t.Run("no sequence", func(t *testing.T) {
|
||||
var bits bitArray
|
||||
|
||||
@ -250,7 +220,68 @@ func TestBitmask(t *testing.T) {
|
||||
assert.False(t, ok)
|
||||
})
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
startIndex int
|
||||
numIndexes int
|
||||
isSequence bool
|
||||
}{
|
||||
{
|
||||
name: "sequence starts at index 0",
|
||||
startIndex: 0,
|
||||
numIndexes: rand.Intn(5000) + 1,
|
||||
isSequence: true,
|
||||
},
|
||||
{
|
||||
name: "sequence starts at index 8 until index 15",
|
||||
startIndex: 8,
|
||||
numIndexes: 15,
|
||||
isSequence: false,
|
||||
},
|
||||
{
|
||||
name: "sequence starts at index 8 until index 16",
|
||||
startIndex: 8,
|
||||
numIndexes: 16,
|
||||
isSequence: false,
|
||||
},
|
||||
{
|
||||
name: "sequence starts at index 8 until index 17",
|
||||
startIndex: 8,
|
||||
numIndexes: 17,
|
||||
isSequence: false,
|
||||
},
|
||||
{
|
||||
name: "sequence starts at index 8 until index 23",
|
||||
startIndex: 8,
|
||||
numIndexes: 23,
|
||||
isSequence: false,
|
||||
},
|
||||
{
|
||||
name: "sequence starts at other index than 0",
|
||||
startIndex: rand.Intn(1000) + 1,
|
||||
numIndexes: rand.Intn(5000) + 1002,
|
||||
isSequence: false,
|
||||
},
|
||||
}
|
||||
|
||||
for i := range testCases {
|
||||
tc := testCases[i]
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
var bits bitArray
|
||||
for i := tc.startIndex; i < tc.numIndexes; i++ {
|
||||
err := bits.Set(i)
|
||||
require.NoError(t, err, "Set")
|
||||
}
|
||||
|
||||
require.Equalf(t, tc.isSequence, bits.IsSequence(),
|
||||
"startIndex: %d, numIndexes: %d", tc.startIndex, tc.numIndexes,
|
||||
)
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("Unset", func(t *testing.T) {
|
||||
t.Run("ok", func(t *testing.T) {
|
||||
var (
|
||||
|
Loading…
Reference in New Issue
Block a user