forked from TrueCloudLab/frostfs-node
131 lines
4 KiB
Go
131 lines
4 KiB
Go
package container
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
v2refs "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/refs"
|
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/client"
|
|
cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
|
|
)
|
|
|
|
// EstimationID is an identity of container load estimation inside Container contract.
|
|
type EstimationID []byte
|
|
|
|
// ListLoadEstimationsByEpoch returns a list of container load estimations for to the specified epoch.
|
|
// The list is composed through Container contract call.
|
|
func (c *Client) ListLoadEstimationsByEpoch(epoch uint64) ([]EstimationID, error) {
|
|
invokePrm := client.TestInvokePrm{}
|
|
invokePrm.SetMethod(listSizesMethod)
|
|
invokePrm.SetArgs(epoch)
|
|
|
|
prms, err := c.client.TestInvoke(invokePrm)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("could not perform test invocation (%s): %w", listSizesMethod, err)
|
|
} else if ln := len(prms); ln != 1 {
|
|
return nil, fmt.Errorf("unexpected stack item count (%s): %d", listSizesMethod, ln)
|
|
}
|
|
|
|
prms, err = client.ArrayFromStackItem(prms[0])
|
|
if err != nil {
|
|
return nil, fmt.Errorf("could not get stack item array from stack item (%s): %w", listSizesMethod, err)
|
|
}
|
|
|
|
res := make([]EstimationID, 0, len(prms))
|
|
for i := range prms {
|
|
id, err := client.BytesFromStackItem(prms[i])
|
|
if err != nil {
|
|
return nil, fmt.Errorf("could not get ID byte array from stack item (%s): %w", listSizesMethod, err)
|
|
}
|
|
|
|
res = append(res, id)
|
|
}
|
|
|
|
return res, nil
|
|
}
|
|
|
|
// Estimation is a structure of single container load estimation
|
|
// reported by storage node.
|
|
type Estimation struct {
|
|
Size uint64
|
|
|
|
Reporter []byte
|
|
}
|
|
|
|
// Estimations is a structure of grouped container load estimation inside Container contract.
|
|
type Estimations struct {
|
|
ContainerID cid.ID
|
|
|
|
Values []Estimation
|
|
}
|
|
|
|
// GetUsedSpaceEstimations returns a list of container load estimations by ID.
|
|
// The list is composed through Container contract call.
|
|
func (c *Client) GetUsedSpaceEstimations(id EstimationID) (*Estimations, error) {
|
|
prm := client.TestInvokePrm{}
|
|
prm.SetMethod(getSizeMethod)
|
|
prm.SetArgs([]byte(id))
|
|
|
|
prms, err := c.client.TestInvoke(prm)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("could not perform test invocation (%s): %w", getSizeMethod, err)
|
|
} else if ln := len(prms); ln != 1 {
|
|
return nil, fmt.Errorf("unexpected stack item count (%s): %d", getSizeMethod, ln)
|
|
}
|
|
|
|
prms, err = client.ArrayFromStackItem(prms[0])
|
|
if err != nil {
|
|
return nil, fmt.Errorf("could not get stack items of estimation fields from stack item (%s): %w", getSizeMethod, err)
|
|
} else if ln := len(prms); ln != 2 {
|
|
return nil, fmt.Errorf("unexpected stack item count of estimations fields (%s)", getSizeMethod)
|
|
}
|
|
|
|
rawCnr, err := client.BytesFromStackItem(prms[0])
|
|
if err != nil {
|
|
return nil, fmt.Errorf("could not get container ID byte array from stack item (%s): %w", getSizeMethod, err)
|
|
}
|
|
|
|
prms, err = client.ArrayFromStackItem(prms[1])
|
|
if err != nil {
|
|
return nil, fmt.Errorf("could not get estimation list array from stack item (%s): %w", getSizeMethod, err)
|
|
}
|
|
|
|
var cnr cid.ID
|
|
|
|
err = cnr.Decode(rawCnr)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("decode container ID: %w", err)
|
|
}
|
|
|
|
v2 := new(v2refs.ContainerID)
|
|
v2.SetValue(rawCnr)
|
|
res := &Estimations{
|
|
ContainerID: cnr,
|
|
Values: make([]Estimation, 0, len(prms)),
|
|
}
|
|
|
|
for i := range prms {
|
|
arr, err := client.ArrayFromStackItem(prms[i])
|
|
if err != nil {
|
|
return nil, fmt.Errorf("could not get estimation struct from stack item (%s): %w", getSizeMethod, err)
|
|
} else if ln := len(arr); ln != 2 {
|
|
return nil, fmt.Errorf("unexpected stack item count of estimation fields (%s)", getSizeMethod)
|
|
}
|
|
|
|
reporter, err := client.BytesFromStackItem(arr[0])
|
|
if err != nil {
|
|
return nil, fmt.Errorf("could not get reporter byte array from stack item (%s): %w", getSizeMethod, err)
|
|
}
|
|
|
|
sz, err := client.IntFromStackItem(arr[1])
|
|
if err != nil {
|
|
return nil, fmt.Errorf("could not get estimation size from stack item (%s): %w", getSizeMethod, err)
|
|
}
|
|
|
|
res.Values = append(res.Values, Estimation{
|
|
Reporter: reporter,
|
|
Size: uint64(sz),
|
|
})
|
|
}
|
|
|
|
return res, nil
|
|
}
|