frostfs-node/pkg/local_object_storage/blobovnicza/get_range.go

71 lines
1.8 KiB
Go

package blobovnicza
import (
objectSDK "github.com/nspcc-dev/neofs-api-go/pkg/object"
"github.com/nspcc-dev/neofs-node/pkg/core/object"
"github.com/pkg/errors"
)
// GetRangePrm groups the parameters of GetRange operation.
type GetRangePrm struct {
addr *objectSDK.Address
rng *objectSDK.Range
}
// GetRangeRes groups resulting values of GetRange operation.
type GetRangeRes struct {
rngData []byte
}
// SetAddress sets address of the requested object.
func (p *GetRangePrm) SetAddress(addr *objectSDK.Address) {
p.addr = addr
}
// SetAddress sets range of the requested payload data .
func (p *GetRangePrm) SetRange(rng *objectSDK.Range) {
p.rng = rng
}
// RangeData returns the requested payload data range.
func (p *GetRangeRes) RangeData() []byte {
return p.rngData
}
// Get reads the object from Blobovnicza by address.
//
// Returns any error encountered that
// did not allow to completely read the object.
//
// Returns ErrNotFound if requested object is not
// presented in Blobovnicza. Returns ErrRangeOutOfBounds
// if requested range is outside the payload.
func (b *Blobovnicza) GetRange(prm *GetRangePrm) (*GetRangeRes, error) {
res, err := b.Get(&GetPrm{
addr: prm.addr,
})
if err != nil {
return nil, err
}
// FIXME: code below is incorrect because Get returns raw object data
// so we should unmarshal payload from it before. If blobovnicza
// stores objects in non-protocol format (e.g. compressed)
// then it should not provide GetRange method.
from := prm.rng.GetOffset()
to := from + prm.rng.GetLength()
payload := res.obj
if from > to {
return nil, errors.Errorf("invalid range [%d:%d]", from, to)
} else if uint64(len(payload)) < to {
return nil, object.ErrRangeOutOfBounds
}
return &GetRangeRes{
rngData: payload[from:to],
}, nil
}