frostfs-node/pkg/morph/client/container/containers_of.go
Ekaterina Lebedeva c0221d76e6 [#1577] node/container: Fix typo
Signed-off-by: Ekaterina Lebedeva <ekaterina.lebedeva@yadro.com>
2024-12-28 12:05:01 +03:00

66 lines
2 KiB
Go

package container
import (
"errors"
cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/user"
"github.com/nspcc-dev/neo-go/pkg/rpcclient/unwrap"
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
)
// ContainersOf returns a list of container identifiers belonging
// to the specified user of FrostFS system. If idUser is nil, returns the list of all containers.
//
// If remote RPC does not support neo-go session API, fallback to List() method.
func (c *Client) ContainersOf(idUser *user.ID) ([]cid.ID, error) {
var cidList []cid.ID
var err error
cb := func(id cid.ID) error {
cidList = append(cidList, id)
return nil
}
if err = c.IterateContainersOf(idUser, cb); err != nil {
return nil, err
}
return cidList, nil
}
// iterateContainers iterates over a list of container identifiers
// belonging to the specified user of FrostFS system and executes
// `cb` on each element. If idUser is nil, calls it on the list of all containers.
func (c *Client) IterateContainersOf(idUser *user.ID, cb func(item cid.ID) error) error {
var rawID []byte
if idUser != nil {
rawID = idUser.WalletBytes()
}
itemCb := func(item stackitem.Item) error {
id, err := getCIDfromStackItem(item)
if err != nil {
return err
}
if err = cb(id); err != nil {
return err
}
return nil
}
// We would like to have batch size as big as possible,
// to reduce the number of round-trips and avoid creating sessions.
// The limit depends on 2 things:
// 1. VM limits: max 2048 items on stack.
// 2. JSON encoded size for the item with type = 128k.
// It turns out, that for container ID the second limit is hit first,
// 512 is big enough value and it is beautiful.
const batchSize = 512
cnrHash := c.client.ContractAddress()
err := c.client.Morph().TestInvokeIterator(itemCb, batchSize, cnrHash, containersOfMethod, rawID)
if err != nil && errors.Is(err, unwrap.ErrNoSessionID) {
return c.iterate(idUser, cb)
}
return err
}