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
|
// IsSequence returns true if mask has only tracked a correlative sequence of
|
||||||
// indexes starting from index 0.
|
// indexes starting from index 0.
|
||||||
func (bytes *bitArray) IsSequence() bool {
|
func (bytes *bitArray) IsSequence() bool {
|
||||||
ones := bytes.Count()
|
// find the last byte of the sequence that contains some one
|
||||||
zeros := 0
|
var i int
|
||||||
for byteIndex := len(*bytes) - 1; byteIndex >= 0 && zeros%8 == 0; byteIndex-- {
|
for i = len(*bytes) - 1; i >= 0; i-- {
|
||||||
zeros = bits.LeadingZeros8((*bytes)[byteIndex])
|
zeros := bits.LeadingZeros8((*bytes)[i])
|
||||||
|
if zeros == 8 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
ones := bits.OnesCount8((*bytes)[i])
|
||||||
|
if zeros+ones != 8 {
|
||||||
|
// zeros and ones in this byte aren't in sequence
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
break
|
||||||
}
|
}
|
||||||
return (zeros + ones) == len(*bytes)*8
|
|
||||||
|
// 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.
|
// Length returns the current size of the array in bits.
|
||||||
|
@ -186,36 +186,6 @@ func TestBitmask(t *testing.T) {
|
|||||||
assert.True(t, ok)
|
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) {
|
t.Run("no sequence", func(t *testing.T) {
|
||||||
var bits bitArray
|
var bits bitArray
|
||||||
|
|
||||||
@ -250,7 +220,68 @@ func TestBitmask(t *testing.T) {
|
|||||||
assert.False(t, ok)
|
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("Unset", func(t *testing.T) {
|
||||||
t.Run("ok", func(t *testing.T) {
|
t.Run("ok", func(t *testing.T) {
|
||||||
var (
|
var (
|
||||||
|
Loading…
Reference in New Issue
Block a user