package engine import ( "context" "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/shard" cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id" "go.uber.org/zap" ) // ContainerSizePrm groups parameters of ContainerSize operation. type ContainerSizePrm struct { cnr cid.ID } // ContainerSizeRes resulting values of ContainerSize operation. type ContainerSizeRes struct { size uint64 } // ListContainersPrm groups parameters of ListContainers operation. type ListContainersPrm struct{} // ListContainersRes groups the resulting values of ListContainers operation. type ListContainersRes struct { containers []cid.ID } // SetContainerID sets the identifier of the container to estimate the size. func (p *ContainerSizePrm) SetContainerID(cnr cid.ID) { p.cnr = cnr } // Size returns calculated estimation of the container size. func (r ContainerSizeRes) Size() uint64 { return r.size } // Containers returns a list of identifiers of the containers in which local objects are stored. func (r ListContainersRes) Containers() []cid.ID { return r.containers } // ContainerSize returns the sum of estimation container sizes among all shards. // // Returns an error if executions are blocked (see BlockExecution). func (e *StorageEngine) ContainerSize(prm ContainerSizePrm) (res ContainerSizeRes, err error) { err = e.execIfNotBlocked(func() error { res, err = e.containerSize(prm) return err }) return } // ContainerSize calls ContainerSize method on engine to calculate sum of estimation container sizes among all shards. func ContainerSize(e *StorageEngine, id cid.ID) (uint64, error) { var prm ContainerSizePrm prm.SetContainerID(id) res, err := e.ContainerSize(prm) if err != nil { return 0, err } return res.Size(), nil } func (e *StorageEngine) containerSize(prm ContainerSizePrm) (res ContainerSizeRes, err error) { if e.metrics != nil { defer elapsed("EstimateContainerSize", e.metrics.AddMethodDuration)() } e.iterateOverUnsortedShards(func(sh hashedShard) (stop bool) { var csPrm shard.ContainerSizePrm csPrm.SetContainerID(prm.cnr) csRes, err := sh.Shard.ContainerSize(csPrm) if err != nil { e.reportShardError(sh, "can't get container size", err, zap.Stringer("container_id", prm.cnr)) return false } res.size += csRes.Size() return false }) return } // ListContainers returns a unique container IDs presented in the engine objects. // // Returns an error if executions are blocked (see BlockExecution). func (e *StorageEngine) ListContainers(ctx context.Context, _ ListContainersPrm) (res ListContainersRes, err error) { err = e.execIfNotBlocked(func() error { res, err = e.listContainers(ctx) return err }) return } // ListContainers calls ListContainers method on engine to get a unique container IDs presented in the engine objects. func ListContainers(ctx context.Context, e *StorageEngine) ([]cid.ID, error) { var prm ListContainersPrm res, err := e.ListContainers(ctx, prm) if err != nil { return nil, err } return res.Containers(), nil } func (e *StorageEngine) listContainers(ctx context.Context) (ListContainersRes, error) { if e.metrics != nil { defer elapsed("ListContainers", e.metrics.AddMethodDuration)() } uniqueIDs := make(map[string]cid.ID) e.iterateOverUnsortedShards(func(sh hashedShard) (stop bool) { res, err := sh.Shard.ListContainers(ctx, shard.ListContainersPrm{}) if err != nil { e.reportShardError(sh, "can't get list of containers", err) return false } for _, cnr := range res.Containers() { id := cnr.EncodeToString() if _, ok := uniqueIDs[id]; !ok { uniqueIDs[id] = cnr } } return false }) result := make([]cid.ID, 0, len(uniqueIDs)) for _, v := range uniqueIDs { result = append(result, v) } return ListContainersRes{ containers: result, }, nil }