1c30414a6c
Core changes: * avoid package-colliding variable naming * avoid using pointers to IDs where unnecessary * avoid using `idSDK` import alias pattern * use `EncodeToString` for protocol string calculation and `String` for printing Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
64 lines
1.3 KiB
Go
64 lines
1.3 KiB
Go
package audit
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"sort"
|
|
"strings"
|
|
|
|
cid "github.com/nspcc-dev/neofs-sdk-go/container/id"
|
|
"go.uber.org/zap"
|
|
)
|
|
|
|
var ErrInvalidIRNode = errors.New("node is not in the inner ring list")
|
|
|
|
func (ap *Processor) selectContainersToAudit(epoch uint64) ([]cid.ID, error) {
|
|
containers, err := ap.containerClient.List(nil)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("can't get list of containers to start audit: %w", err)
|
|
}
|
|
|
|
// consider getting extra information about container complexity from
|
|
// audit contract there
|
|
ap.log.Debug("container listing finished",
|
|
zap.Int("total amount", len(containers)),
|
|
)
|
|
|
|
sort.Slice(containers, func(i, j int) bool {
|
|
return strings.Compare(containers[i].EncodeToString(), containers[j].EncodeToString()) < 0
|
|
})
|
|
|
|
ind := ap.irList.InnerRingIndex()
|
|
irSize := ap.irList.InnerRingSize()
|
|
|
|
if ind < 0 || ind >= irSize {
|
|
return nil, ErrInvalidIRNode
|
|
}
|
|
|
|
return Select(containers, epoch, uint64(ind), uint64(irSize)), nil
|
|
}
|
|
|
|
func Select(ids []cid.ID, epoch, index, size uint64) []cid.ID {
|
|
if index >= size {
|
|
return nil
|
|
}
|
|
|
|
var a, b uint64
|
|
|
|
ln := uint64(len(ids))
|
|
pivot := ln % size
|
|
delta := ln / size
|
|
|
|
index = (index + epoch) % size
|
|
if index < pivot {
|
|
a = delta + 1
|
|
} else {
|
|
a = delta
|
|
b = pivot
|
|
}
|
|
|
|
from := a*index + b
|
|
to := a*(index+1) + b
|
|
|
|
return ids[from:to]
|
|
}
|