[#235] services/object: Implement new GetRange algorithm

Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
This commit is contained in:
Leonard Lyubich 2020-12-07 20:49:47 +03:00 committed by Alex Vanin
parent 91d8e0a4de
commit 1d23483828
37 changed files with 703 additions and 1125 deletions

View file

@ -15,7 +15,7 @@ import (
type simpleObjectWriter struct {
obj *object.RawObject
payload []byte
pld []byte
}
type clientCacheWrapper struct {
@ -36,20 +36,28 @@ type headSvcWrapper struct {
svc *headsvc.Service
}
type rangeWriter struct {
ObjectWriter
chunkWriter ChunkWriter
}
func newSimpleObjectWriter() *simpleObjectWriter {
return new(simpleObjectWriter)
return &simpleObjectWriter{
obj: object.NewRaw(),
}
}
func (s *simpleObjectWriter) WriteHeader(obj *object.Object) error {
s.obj = object.NewRawFromObject(obj)
s.payload = make([]byte, 0, obj.PayloadSize())
s.pld = make([]byte, 0, obj.PayloadSize())
return nil
}
func (s *simpleObjectWriter) WriteChunk(p []byte) error {
s.payload = append(s.payload, p...)
s.pld = append(s.pld, p...)
return nil
}
@ -58,8 +66,8 @@ func (s *simpleObjectWriter) Close() error {
}
func (s *simpleObjectWriter) object() *object.Object {
if len(s.payload) > 0 {
s.obj.SetPayload(s.payload)
if len(s.pld) > 0 {
s.obj.SetPayload(s.pld)
}
return s.obj.Object()
@ -73,31 +81,60 @@ func (c *clientCacheWrapper) get(key *ecdsa.PrivateKey, addr string) (getClient,
}, err
}
func (c *clientWrapper) GetObject(ctx context.Context, p Prm) (*objectSDK.Object, error) {
func (c *clientWrapper) GetObject(ctx context.Context, p RangePrm) (*objectSDK.Object, error) {
// we don't specify payload writer because we accumulate
// the object locally (even huge).
return c.client.GetObject(ctx,
new(client.GetObjectParams).
WithAddress(p.addr).
WithRawFlag(true),
p.callOpts...,
)
if p.rng != nil {
data, err := c.client.ObjectPayloadRangeData(ctx,
new(client.RangeDataParams).
WithAddress(p.Address()).
WithRange(p.rng).
WithRaw(p.RawFlag()),
p.callOpts...,
)
if err != nil {
return nil, err
}
return payloadOnlyObject(data), nil
} else {
// we don't specify payload writer because we accumulate
// the object locally (even huge).
return c.client.GetObject(ctx,
new(client.GetObjectParams).
WithAddress(p.Address()).
WithRawFlag(p.RawFlag()),
p.callOpts...,
)
}
}
func (e *storageEngineWrapper) Get(addr *objectSDK.Address) (*object.Object, error) {
r, err := e.engine.Get(new(engine.GetPrm).
WithAddress(addr),
)
if err != nil {
return nil, err
}
func (e *storageEngineWrapper) Get(p RangePrm) (*object.Object, error) {
if p.rng != nil {
r, err := e.engine.GetRange(new(engine.RngPrm).
WithAddress(p.Address()).
WithPayloadRange(p.rng),
)
if err != nil {
return nil, err
}
return r.Object(), nil
return r.Object(), nil
} else {
r, err := e.engine.Get(new(engine.GetPrm).
WithAddress(p.Address()),
)
if err != nil {
return nil, err
}
return r.Object(), nil
}
}
func (s *headSvcWrapper) head(ctx context.Context, p Prm) (*object.Object, error) {
r, err := s.svc.Head(ctx, new(headsvc.Prm).
WithAddress(p.addr).
WithAddress(p.Address()).
WithCommonPrm(p.common).
Short(false),
)
@ -108,3 +145,14 @@ func (s *headSvcWrapper) head(ctx context.Context, p Prm) (*object.Object, error
return r.Header(), nil
}
func (w *rangeWriter) WriteChunk(p []byte) error {
return w.chunkWriter.WriteChunk(p)
}
func payloadOnlyObject(payload []byte) *objectSDK.Object {
rawObj := object.NewRaw()
rawObj.SetPayload(payload)
return rawObj.Object().SDK()
}