Merge branch 'master' into 9171-add-retries-to-mpool-push-message
This commit is contained in:
@@ -6,7 +6,7 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/libp2p/go-libp2p-core/peer"
|
||||
"github.com/libp2p/go-libp2p/core/peer"
|
||||
ma "github.com/multiformats/go-multiaddr"
|
||||
madns "github.com/multiformats/go-multiaddr-dns"
|
||||
)
|
||||
|
||||
@@ -6,11 +6,11 @@ import (
|
||||
"time"
|
||||
|
||||
logging "github.com/ipfs/go-log/v2"
|
||||
"github.com/libp2p/go-libp2p-core/event"
|
||||
"github.com/libp2p/go-libp2p-core/host"
|
||||
net "github.com/libp2p/go-libp2p-core/network"
|
||||
"github.com/libp2p/go-libp2p-core/peer"
|
||||
dht "github.com/libp2p/go-libp2p-kad-dht"
|
||||
"github.com/libp2p/go-libp2p/core/event"
|
||||
"github.com/libp2p/go-libp2p/core/host"
|
||||
net "github.com/libp2p/go-libp2p/core/network"
|
||||
"github.com/libp2p/go-libp2p/core/peer"
|
||||
"go.opencensus.io/stats"
|
||||
"go.uber.org/fx"
|
||||
"go.uber.org/multierr"
|
||||
|
||||
@@ -0,0 +1,96 @@
|
||||
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 && 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
|
||||
}
|
||||
@@ -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")
|
||||
}
|
||||
Reference in New Issue
Block a user