[#337] engine: Add container listing for both engine and shard

Container listing already supported in the metabase for `engine.List`
operation. To get container statistics engine should provide both the
option to get container volume estimation and list of all containers.

Signed-off-by: Alex Vanin <alexey@nspcc.ru>
This commit is contained in:
Alex Vanin 2021-01-22 16:21:45 +03:00 committed by Alex Vanin
parent 3926e76c32
commit de1f601765
2 changed files with 85 additions and 0 deletions

View file

@ -14,6 +14,12 @@ type ContainerSizeRes struct {
size uint64 size uint64
} }
type ListContainersPrm struct{}
type ListContainersRes struct {
containers []*container.ID
}
func (p *ContainerSizePrm) WithContainerID(cid *container.ID) *ContainerSizePrm { func (p *ContainerSizePrm) WithContainerID(cid *container.ID) *ContainerSizePrm {
if p != nil { if p != nil {
p.cid = cid p.cid = cid
@ -26,6 +32,10 @@ func (r *ContainerSizeRes) Size() uint64 {
return r.size return r.size
} }
func (r *ListContainersRes) Containers() []*container.ID {
return r.containers
}
// ContainerSize returns sum of estimation container sizes among all shards. // ContainerSize returns sum of estimation container sizes among all shards.
func (e *StorageEngine) ContainerSize(prm *ContainerSizePrm) *ContainerSizeRes { func (e *StorageEngine) ContainerSize(prm *ContainerSizePrm) *ContainerSizeRes {
return &ContainerSizeRes{ return &ContainerSizeRes{
@ -57,3 +67,46 @@ func (e *StorageEngine) containerSize(id *container.ID) (total uint64) {
return total return total
} }
// ListContainers returns unique container IDs presented in the engine objects.
func (e *StorageEngine) ListContainers(_ *ListContainersPrm) *ListContainersRes {
return &ListContainersRes{
containers: e.listContainers(),
}
}
// ListContainers returns unique container IDs presented in the engine objects.
func ListContainers(e *StorageEngine) []*container.ID {
return e.ListContainers(&ListContainersPrm{}).Containers()
}
func (e *StorageEngine) listContainers() []*container.ID {
uniqueIDs := make(map[string]*container.ID)
e.iterateOverUnsortedShards(func(s *shard.Shard) (stop bool) {
cnrs, err := shard.ListContainers(s)
if err != nil {
e.log.Warn("can't get list of containers",
zap.Stringer("shard_id", s.ID()),
zap.String("error", err.Error()))
return false
}
for i := range cnrs {
id := cnrs[i].String()
if _, ok := uniqueIDs[id]; !ok {
uniqueIDs[id] = cnrs[i]
}
}
return false
})
result := make([]*container.ID, 0, len(uniqueIDs))
for _, v := range uniqueIDs {
result = append(result, v)
}
return result
}

View file

@ -3,11 +3,23 @@ package shard
import ( import (
"fmt" "fmt"
"github.com/nspcc-dev/neofs-api-go/pkg/container"
"github.com/nspcc-dev/neofs-api-go/pkg/object" "github.com/nspcc-dev/neofs-api-go/pkg/object"
meta "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/metabase" meta "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/metabase"
"github.com/pkg/errors"
"go.uber.org/zap" "go.uber.org/zap"
) )
type ListContainersPrm struct{}
type ListContainersRes struct {
containers []*container.ID
}
func (r *ListContainersRes) Containers() []*container.ID {
return r.containers
}
func (s *Shard) List() (*SelectRes, error) { func (s *Shard) List() (*SelectRes, error) {
lst, err := s.metaBase.Containers() lst, err := s.metaBase.Containers()
if err != nil { if err != nil {
@ -32,3 +44,23 @@ func (s *Shard) List() (*SelectRes, error) {
return res, nil return res, nil
} }
func (s *Shard) ListContainers(_ *ListContainersPrm) (*ListContainersRes, error) {
containers, err := s.metaBase.Containers()
if err != nil {
return nil, errors.Wrap(err, "could not get list of containers")
}
return &ListContainersRes{
containers: containers,
}, nil
}
func ListContainers(s *Shard) ([]*container.ID, error) {
res, err := s.ListContainers(&ListContainersPrm{})
if err != nil {
return nil, err
}
return res.Containers(), nil
}