forked from TrueCloudLab/frostfs-node
[#539] getsvc: Write payload direct to out stream
To reduce memory allocations. Signed-off-by: Dmitrii Stepanov <d.stepanov@yadro.com>
This commit is contained in:
parent
286242cad0
commit
99bb488ebd
4 changed files with 27 additions and 28 deletions
|
@ -113,9 +113,10 @@ func (r *request) HeadObject(ctx context.Context, id oid.ID) (*objectSDK.Object,
|
||||||
return w.Object(), nil
|
return w.Object(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *request) GetObject(ctx context.Context, id oid.ID, rng *objectSDK.Range, payloadBuffer []byte) (*objectSDK.Object, error) {
|
func (r *request) GetObjectAndWritePayload(ctx context.Context, id oid.ID, rng *objectSDK.Range, writer ChunkWriter) (*objectSDK.Object, error) {
|
||||||
w := NewSimpleObjectWriter()
|
w := &payloadWriter{
|
||||||
w.SetPayloadBuffer(payloadBuffer)
|
origin: writer,
|
||||||
|
}
|
||||||
|
|
||||||
p := r.prm
|
p := r.prm
|
||||||
p.common = p.common.WithLocalOnly(false)
|
p.common = p.common.WithLocalOnly(false)
|
||||||
|
@ -128,7 +129,7 @@ func (r *request) GetObject(ctx context.Context, id oid.ID, rng *objectSDK.Range
|
||||||
if err := r.getObjectWithIndependentRequest(ctx, p); err != nil {
|
if err := r.getObjectWithIndependentRequest(ctx, p); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return w.Object(), nil
|
return w.obj, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *request) getObjectWithIndependentRequest(ctx context.Context, prm RequestParameters) error {
|
func (r *request) getObjectWithIndependentRequest(ctx context.Context, prm RequestParameters) error {
|
||||||
|
|
|
@ -10,7 +10,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
type objectGetter interface {
|
type objectGetter interface {
|
||||||
GetObject(ctx context.Context, id oid.ID, rng *objectSDK.Range, buffer []byte) (*objectSDK.Object, error)
|
GetObjectAndWritePayload(ctx context.Context, id oid.ID, rng *objectSDK.Range, writer ChunkWriter) (*objectSDK.Object, error)
|
||||||
HeadObject(ctx context.Context, id oid.ID) (*objectSDK.Object, error)
|
HeadObject(ctx context.Context, id oid.ID) (*objectSDK.Object, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -77,10 +77,12 @@ func (a *assembler) getLastPartOrLinkObjectID() (oid.ID, bool) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *assembler) initializeFromSourceObjectID(ctx context.Context, id oid.ID) (*oid.ID, []oid.ID, error) {
|
func (a *assembler) initializeFromSourceObjectID(ctx context.Context, id oid.ID) (*oid.ID, []oid.ID, error) {
|
||||||
sourceObject, err := a.getChildObject(ctx, id, nil, true, nil)
|
w := NewSimpleObjectWriter()
|
||||||
|
sourceObject, err := a.getChildObject(ctx, id, nil, true, w)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
sourceObject.SetPayload(w.pld)
|
||||||
|
|
||||||
parentObject := sourceObject.Parent()
|
parentObject := sourceObject.Parent()
|
||||||
if parentObject == nil {
|
if parentObject == nil {
|
||||||
|
@ -131,8 +133,8 @@ func (a *assembler) initializeFromSourceObjectID(ctx context.Context, id oid.ID)
|
||||||
return nil, sourceObject.Children(), nil
|
return nil, sourceObject.Children(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *assembler) getChildObject(ctx context.Context, id oid.ID, rng *objectSDK.Range, verifyIsChild bool, payloadBuffer []byte) (*objectSDK.Object, error) {
|
func (a *assembler) getChildObject(ctx context.Context, id oid.ID, rng *objectSDK.Range, verifyIsChild bool, writer ChunkWriter) (*objectSDK.Object, error) {
|
||||||
obj, err := a.objGetter.GetObject(ctx, id, rng, payloadBuffer)
|
obj, err := a.objGetter.GetObjectAndWritePayload(ctx, id, rng, writer)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -176,23 +178,16 @@ func (a *assembler) assemleObjectByPreviousIDInReverse(ctx context.Context, prev
|
||||||
func (a *assembler) assemblePayloadByObjectIDs(ctx context.Context, writer ObjectWriter, partIDs []oid.ID, partRanges []objectSDK.Range, verifyIsChild bool) error {
|
func (a *assembler) assemblePayloadByObjectIDs(ctx context.Context, writer ObjectWriter, partIDs []oid.ID, partRanges []objectSDK.Range, verifyIsChild bool) error {
|
||||||
withRng := len(partRanges) > 0 && a.rng != nil
|
withRng := len(partRanges) > 0 && a.rng != nil
|
||||||
|
|
||||||
var buffer []byte
|
|
||||||
for i := range partIDs {
|
for i := range partIDs {
|
||||||
var r *objectSDK.Range
|
var r *objectSDK.Range
|
||||||
if withRng {
|
if withRng {
|
||||||
r = &partRanges[i]
|
r = &partRanges[i]
|
||||||
}
|
}
|
||||||
|
|
||||||
child, err := a.getChildObject(ctx, partIDs[i], r, verifyIsChild, buffer)
|
_, err := a.getChildObject(ctx, partIDs[i], r, verifyIsChild, writer)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := writer.WriteChunk(ctx, child.Payload()); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
buffer = child.Payload()
|
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -629,7 +629,6 @@ func TestGetRemoteSmall(t *testing.T) {
|
||||||
|
|
||||||
*c1, *c2 = *c2, *c1
|
*c1, *c2 = *c2, *c1
|
||||||
|
|
||||||
w.SetPayloadBuffer(make([]byte, 0))
|
|
||||||
err = svc.Get(ctx, p)
|
err = svc.Get(ctx, p)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, obj, w.Object())
|
require.Equal(t, obj, w.Object())
|
||||||
|
|
|
@ -49,19 +49,9 @@ func NewSimpleObjectWriter() *SimpleObjectWriter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *SimpleObjectWriter) SetPayloadBuffer(buffer []byte) {
|
|
||||||
if buffer != nil {
|
|
||||||
s.pld = buffer[:0]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *SimpleObjectWriter) WriteHeader(_ context.Context, obj *objectSDK.Object) error {
|
func (s *SimpleObjectWriter) WriteHeader(_ context.Context, obj *objectSDK.Object) error {
|
||||||
s.obj = obj
|
s.obj = obj
|
||||||
|
|
||||||
if s.pld == nil {
|
|
||||||
s.pld = make([]byte, 0, obj.PayloadSize())
|
s.pld = make([]byte, 0, obj.PayloadSize())
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -90,3 +80,17 @@ func (h *hasherWrapper) WriteChunk(_ context.Context, p []byte) error {
|
||||||
_, err := h.hash.Write(p)
|
_, err := h.hash.Write(p)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type payloadWriter struct {
|
||||||
|
origin ChunkWriter
|
||||||
|
obj *objectSDK.Object
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *payloadWriter) WriteChunk(ctx context.Context, p []byte) error {
|
||||||
|
return w.origin.WriteChunk(ctx, p)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w *payloadWriter) WriteHeader(_ context.Context, o *objectSDK.Object) error {
|
||||||
|
w.obj = o
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue