numassigner: SectorNumReserveCount

This commit is contained in:
Łukasz Magiera
2022-08-24 11:25:37 -04:00
parent b290dac3cb
commit 335f5df3ec
13 changed files with 272 additions and 100 deletions
+100
View File
@@ -0,0 +1,100 @@
package strle
import (
"encoding/json"
"fmt"
"strconv"
"strings"
"golang.org/x/xerrors"
"github.com/filecoin-project/go-bitfield"
rlepluslazy "github.com/filecoin-project/go-bitfield/rle"
)
func HumanRangesToBitField(h string) (bitfield.BitField, error) {
var runs []rlepluslazy.Run
var last uint64
strRanges := strings.Split(h, ",")
for i, strRange := range strRanges {
lr := strings.Split(strRange, "-")
var start, end uint64
var err error
switch len(lr) {
case 1: // one number
start, err = strconv.ParseUint(lr[0], 10, 64)
if err != nil {
return bitfield.BitField{}, xerrors.Errorf("parsing left side of run %d: %w", i, err)
}
end = start
case 2: // x-y
start, err = strconv.ParseUint(lr[0], 10, 64)
if err != nil {
return bitfield.BitField{}, xerrors.Errorf("parsing left side of run %d: %w", i, err)
}
end, err = strconv.ParseUint(lr[1], 10, 64)
if err != nil {
return bitfield.BitField{}, xerrors.Errorf("parsing right side of run %d: %w", i, err)
}
}
if start < last {
return bitfield.BitField{}, xerrors.Errorf("run %d start(%d) was less than last run end(%d)", i, start, last)
}
if start == last && last > 0 {
return bitfield.BitField{}, xerrors.Errorf("run %d start(%d) was equal to last run end(%d)", i, start, last)
}
if start > end {
return bitfield.BitField{}, xerrors.Errorf("run start(%d) can't be greater than run end(%d) (run %d)", start, end, i)
}
if start > last {
runs = append(runs, rlepluslazy.Run{Val: false, Len: start - last})
}
runs = append(runs, rlepluslazy.Run{Val: true, Len: end - start + 1})
last = end + 1
}
return bitfield.NewFromIter(&rlepluslazy.RunSliceIterator{Runs: runs})
}
func BitfieldToHumanRanges(bf bitfield.BitField) (string, error) {
bj, err := bf.MarshalJSON()
if err != nil {
return "", err
}
var bints []int64
if err := json.Unmarshal(bj, &bints); err != nil {
return "", err
}
var at int64
var out string
for i, bi := range bints {
at += bi
if i%2 == 0 {
if i > 0 {
out += ","
}
out += fmt.Sprint(at)
continue
}
if bi > 1 {
out += "-"
out += fmt.Sprint(at - 1)
}
}
return out, err
}
+57
View File
@@ -0,0 +1,57 @@
package strle
import (
"testing"
"github.com/stretchr/testify/require"
"github.com/filecoin-project/go-bitfield"
)
func TestHumanBitfield(t *testing.T) {
check := func(ints []uint64, out string) {
bf := bitfield.NewFromSet(ints)
h, err := BitfieldToHumanRanges(bf)
require.NoError(t, err)
require.Equal(t, out, h)
}
check([]uint64{2, 3, 4}, "2-4")
check([]uint64{2, 3, 4, 8, 9, 10, 11}, "2-4,8-11")
check([]uint64{2}, "2")
check([]uint64{0}, "0")
check([]uint64{0, 1, 2}, "0-2")
check([]uint64{0, 1, 5, 9, 11, 13, 14, 19}, "0-1,5,9,11,13-14,19")
}
func TestHumanBitfieldRoundtrip(t *testing.T) {
check := func(ints []uint64, out string) {
parsed, err := HumanRangesToBitField(out)
require.NoError(t, err)
h, err := BitfieldToHumanRanges(parsed)
require.NoError(t, err)
require.Equal(t, out, h)
bf := bitfield.NewFromSet(ints)
ins, err := bitfield.IntersectBitField(bf, parsed)
require.NoError(t, err)
// if intersected bitfield has the same length as both bitfields they are the same
ic, err := ins.Count()
require.NoError(t, err)
pc, err := parsed.Count()
require.NoError(t, err)
require.Equal(t, uint64(len(ints)), ic)
require.Equal(t, ic, pc)
}
check([]uint64{2, 3, 4}, "2-4")
check([]uint64{2, 3, 4, 8, 9, 10, 11}, "2-4,8-11")
check([]uint64{2}, "2")
check([]uint64{0}, "0")
check([]uint64{0, 1, 2}, "0-2")
check([]uint64{0, 1, 5, 9, 11, 13, 14, 19}, "0-1,5,9,11,13-14,19")
}