[#328] container/load: Implement PlacementBuilder for used space router

Implement wrapper over netmap and container storages on app-side that builds
placement vectors by next steps:

 * read container from storage;
 * read network map from storage by epoch number;
 * build container nodes according to placement policy;
 * build placement vectors with epoch-dependent pivot.

Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
This commit is contained in:
Leonard Lyubich 2021-02-01 15:07:07 +03:00 committed by Leonard Lyubich
parent 6f552c8599
commit 910017b72f

View file

@ -2,10 +2,14 @@ package main
import (
"context"
"strconv"
apiClient "github.com/nspcc-dev/neofs-api-go/pkg/client"
containerSDK "github.com/nspcc-dev/neofs-api-go/pkg/container"
"github.com/nspcc-dev/neofs-api-go/pkg/netmap"
containerGRPC "github.com/nspcc-dev/neofs-api-go/v2/container/grpc"
containerCore "github.com/nspcc-dev/neofs-node/pkg/core/container"
netmapCore "github.com/nspcc-dev/neofs-node/pkg/core/netmap"
"github.com/nspcc-dev/neofs-node/pkg/morph/client"
"github.com/nspcc-dev/neofs-node/pkg/morph/client/container"
"github.com/nspcc-dev/neofs-node/pkg/morph/client/container/wrapper"
@ -14,6 +18,7 @@ import (
loadcontroller "github.com/nspcc-dev/neofs-node/pkg/services/container/announcement/load/controller"
containerMorph "github.com/nspcc-dev/neofs-node/pkg/services/container/morph"
"github.com/nspcc-dev/neofs-node/pkg/util/logger"
"github.com/pkg/errors"
"go.uber.org/zap"
)
@ -99,3 +104,50 @@ func (r *remoteLoadAnnounceWriter) Put(a containerSDK.UsedSpaceAnnouncement) err
func (r *remoteLoadAnnounceWriter) Close() error {
return r.client.AnnounceContainerUsedSpace(r.ctx, r.buf)
}
type loadPlacementBuilder struct {
log *logger.Logger
nmSrc netmapCore.Source
cnrSrc containerCore.Source
}
func (l *loadPlacementBuilder) BuildPlacement(epoch uint64, cid *containerSDK.ID) ([]netmap.Nodes, error) {
cnrNodes, nm, err := l.buildPlacement(epoch, cid)
if err != nil {
return nil, err
}
const pivotPrefix = "load_announcement_"
pivot := []byte(
pivotPrefix + strconv.FormatUint(epoch, 10),
)
placement, err := nm.GetPlacementVectors(cnrNodes, pivot)
if err != nil {
return nil, errors.Wrap(err, "could not build placement vectors")
}
return placement, nil
}
func (l *loadPlacementBuilder) buildPlacement(epoch uint64, cid *containerSDK.ID) (netmap.ContainerNodes, *netmap.Netmap, error) {
cnr, err := l.cnrSrc.Get(cid)
if err != nil {
return nil, nil, err
}
nm, err := l.nmSrc.GetNetMapByEpoch(epoch)
if err != nil {
return nil, nil, errors.Wrap(err, "could not get network map")
}
cnrNodes, err := nm.GetContainerNodes(cnr.PlacementPolicy(), cid.ToV2().GetValue())
if err != nil {
return nil, nil, errors.Wrap(err, "could not build container nodes")
}
return cnrNodes, nm, nil
}