2021-01-22 11:37:28 +00:00
|
|
|
package engine
|
|
|
|
|
|
|
|
import (
|
2023-06-06 09:27:19 +00:00
|
|
|
"context"
|
|
|
|
|
2023-03-07 13:38:26 +00:00
|
|
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/shard"
|
|
|
|
cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
|
2021-01-22 11:37:28 +00:00
|
|
|
"go.uber.org/zap"
|
|
|
|
)
|
|
|
|
|
2021-11-10 15:26:12 +00:00
|
|
|
// ContainerSizePrm groups parameters of ContainerSize operation.
|
2021-01-22 11:37:28 +00:00
|
|
|
type ContainerSizePrm struct {
|
2022-05-31 17:00:41 +00:00
|
|
|
cnr cid.ID
|
2021-01-22 11:37:28 +00:00
|
|
|
}
|
|
|
|
|
2021-11-10 15:26:12 +00:00
|
|
|
// ContainerSizeRes resulting values of ContainerSize operation.
|
2021-01-22 11:37:28 +00:00
|
|
|
type ContainerSizeRes struct {
|
|
|
|
size uint64
|
|
|
|
}
|
|
|
|
|
2021-11-10 15:26:12 +00:00
|
|
|
// ListContainersPrm groups parameters of ListContainers operation.
|
2021-01-22 13:21:45 +00:00
|
|
|
type ListContainersPrm struct{}
|
|
|
|
|
2022-04-21 11:28:05 +00:00
|
|
|
// ListContainersRes groups the resulting values of ListContainers operation.
|
2021-01-22 13:21:45 +00:00
|
|
|
type ListContainersRes struct {
|
2022-05-31 17:00:41 +00:00
|
|
|
containers []cid.ID
|
2021-01-22 13:21:45 +00:00
|
|
|
}
|
|
|
|
|
2022-04-21 11:28:05 +00:00
|
|
|
// SetContainerID sets the identifier of the container to estimate the size.
|
2022-05-31 17:00:41 +00:00
|
|
|
func (p *ContainerSizePrm) SetContainerID(cnr cid.ID) {
|
|
|
|
p.cnr = cnr
|
2021-01-22 11:37:28 +00:00
|
|
|
}
|
|
|
|
|
2021-11-10 15:26:12 +00:00
|
|
|
// Size returns calculated estimation of the container size.
|
|
|
|
func (r ContainerSizeRes) Size() uint64 {
|
2021-01-22 11:37:28 +00:00
|
|
|
return r.size
|
|
|
|
}
|
|
|
|
|
2022-04-21 11:28:05 +00:00
|
|
|
// Containers returns a list of identifiers of the containers in which local objects are stored.
|
2022-05-31 17:00:41 +00:00
|
|
|
func (r ListContainersRes) Containers() []cid.ID {
|
2021-01-22 13:21:45 +00:00
|
|
|
return r.containers
|
|
|
|
}
|
|
|
|
|
2022-04-21 11:28:05 +00:00
|
|
|
// ContainerSize returns the sum of estimation container sizes among all shards.
|
2021-11-09 15:46:12 +00:00
|
|
|
//
|
2021-11-10 15:26:12 +00:00
|
|
|
// Returns an error if executions are blocked (see BlockExecution).
|
2022-05-31 11:56:59 +00:00
|
|
|
func (e *StorageEngine) ContainerSize(prm ContainerSizePrm) (res ContainerSizeRes, err error) {
|
2021-11-10 15:26:12 +00:00
|
|
|
err = e.execIfNotBlocked(func() error {
|
|
|
|
res, err = e.containerSize(prm)
|
|
|
|
return err
|
2021-11-09 15:46:12 +00:00
|
|
|
})
|
|
|
|
|
|
|
|
return
|
2021-01-22 11:37:28 +00:00
|
|
|
}
|
|
|
|
|
2021-11-10 15:26:12 +00:00
|
|
|
// ContainerSize calls ContainerSize method on engine to calculate sum of estimation container sizes among all shards.
|
2022-05-31 17:00:41 +00:00
|
|
|
func ContainerSize(e *StorageEngine, id cid.ID) (uint64, error) {
|
2021-11-10 15:26:12 +00:00
|
|
|
var prm ContainerSizePrm
|
|
|
|
|
|
|
|
prm.SetContainerID(id)
|
|
|
|
|
|
|
|
res, err := e.ContainerSize(prm)
|
|
|
|
if err != nil {
|
|
|
|
return 0, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return res.Size(), nil
|
2021-01-22 11:37:28 +00:00
|
|
|
}
|
|
|
|
|
2022-05-31 11:56:59 +00:00
|
|
|
func (e *StorageEngine) containerSize(prm ContainerSizePrm) (res ContainerSizeRes, err error) {
|
2021-11-09 15:46:12 +00:00
|
|
|
if e.metrics != nil {
|
2023-06-13 16:48:15 +00:00
|
|
|
defer elapsed("EstimateContainerSize", e.metrics.AddMethodDuration)()
|
2021-11-09 15:46:12 +00:00
|
|
|
}
|
|
|
|
|
2022-01-31 14:58:32 +00:00
|
|
|
e.iterateOverUnsortedShards(func(sh hashedShard) (stop bool) {
|
2022-07-13 12:38:03 +00:00
|
|
|
var csPrm shard.ContainerSizePrm
|
2022-07-13 12:43:04 +00:00
|
|
|
csPrm.SetContainerID(prm.cnr)
|
2022-07-13 12:38:03 +00:00
|
|
|
|
|
|
|
csRes, err := sh.Shard.ContainerSize(csPrm)
|
2022-10-26 12:23:12 +00:00
|
|
|
if err != nil {
|
2022-01-31 14:58:32 +00:00
|
|
|
e.reportShardError(sh, "can't get container size", err,
|
2022-10-26 12:23:12 +00:00
|
|
|
zap.Stringer("container_id", prm.cnr))
|
2021-01-22 11:37:28 +00:00
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
2022-07-13 12:38:03 +00:00
|
|
|
res.size += csRes.Size()
|
2021-01-22 11:37:28 +00:00
|
|
|
|
|
|
|
return false
|
|
|
|
})
|
|
|
|
|
2022-05-31 11:56:59 +00:00
|
|
|
return
|
2021-01-22 11:37:28 +00:00
|
|
|
}
|
2021-01-22 13:21:45 +00:00
|
|
|
|
2022-04-21 11:28:05 +00:00
|
|
|
// ListContainers returns a unique container IDs presented in the engine objects.
|
2021-11-09 15:46:12 +00:00
|
|
|
//
|
2021-11-10 15:26:12 +00:00
|
|
|
// Returns an error if executions are blocked (see BlockExecution).
|
2023-06-06 09:27:19 +00:00
|
|
|
func (e *StorageEngine) ListContainers(ctx context.Context, _ ListContainersPrm) (res ListContainersRes, err error) {
|
2021-11-10 15:26:12 +00:00
|
|
|
err = e.execIfNotBlocked(func() error {
|
2023-06-06 09:27:19 +00:00
|
|
|
res, err = e.listContainers(ctx)
|
2021-11-10 15:26:12 +00:00
|
|
|
return err
|
2021-11-09 15:46:12 +00:00
|
|
|
})
|
|
|
|
|
|
|
|
return
|
2021-01-22 13:21:45 +00:00
|
|
|
}
|
|
|
|
|
2022-04-21 11:28:05 +00:00
|
|
|
// ListContainers calls ListContainers method on engine to get a unique container IDs presented in the engine objects.
|
2023-06-06 09:27:19 +00:00
|
|
|
func ListContainers(ctx context.Context, e *StorageEngine) ([]cid.ID, error) {
|
2021-11-10 15:26:12 +00:00
|
|
|
var prm ListContainersPrm
|
|
|
|
|
2023-06-06 09:27:19 +00:00
|
|
|
res, err := e.ListContainers(ctx, prm)
|
2021-11-10 15:26:12 +00:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return res.Containers(), nil
|
2021-01-22 13:21:45 +00:00
|
|
|
}
|
|
|
|
|
2023-06-06 09:27:19 +00:00
|
|
|
func (e *StorageEngine) listContainers(ctx context.Context) (ListContainersRes, error) {
|
2021-11-09 15:46:12 +00:00
|
|
|
if e.metrics != nil {
|
2023-06-13 16:48:15 +00:00
|
|
|
defer elapsed("ListContainers", e.metrics.AddMethodDuration)()
|
2021-11-09 15:46:12 +00:00
|
|
|
}
|
|
|
|
|
2022-05-31 17:00:41 +00:00
|
|
|
uniqueIDs := make(map[string]cid.ID)
|
2021-01-22 13:21:45 +00:00
|
|
|
|
2022-01-31 14:58:32 +00:00
|
|
|
e.iterateOverUnsortedShards(func(sh hashedShard) (stop bool) {
|
2023-06-06 09:27:19 +00:00
|
|
|
res, err := sh.Shard.ListContainers(ctx, shard.ListContainersPrm{})
|
2021-01-22 13:21:45 +00:00
|
|
|
if err != nil {
|
2022-10-26 12:23:12 +00:00
|
|
|
e.reportShardError(sh, "can't get list of containers", err)
|
2021-01-22 13:21:45 +00:00
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
2022-07-13 12:38:03 +00:00
|
|
|
for _, cnr := range res.Containers() {
|
|
|
|
id := cnr.EncodeToString()
|
2021-01-22 13:21:45 +00:00
|
|
|
if _, ok := uniqueIDs[id]; !ok {
|
2022-07-13 12:38:03 +00:00
|
|
|
uniqueIDs[id] = cnr
|
2021-01-22 13:21:45 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return false
|
|
|
|
})
|
|
|
|
|
2022-05-31 17:00:41 +00:00
|
|
|
result := make([]cid.ID, 0, len(uniqueIDs))
|
2021-01-22 13:21:45 +00:00
|
|
|
for _, v := range uniqueIDs {
|
|
|
|
result = append(result, v)
|
|
|
|
}
|
|
|
|
|
2022-05-31 11:56:59 +00:00
|
|
|
return ListContainersRes{
|
2021-11-09 15:46:12 +00:00
|
|
|
containers: result,
|
2021-11-10 15:26:12 +00:00
|
|
|
}, nil
|
2021-01-22 13:21:45 +00:00
|
|
|
}
|