diff --git a/pkg/services/object/get/assemble.go b/pkg/services/object/get/assemble.go index 777822ac3..43f2c470b 100644 --- a/pkg/services/object/get/assemble.go +++ b/pkg/services/object/get/assemble.go @@ -113,8 +113,9 @@ func (r *request) HeadObject(ctx context.Context, id oid.ID) (*objectSDK.Object, return w.Object(), nil } -func (r *request) GetObject(ctx context.Context, id oid.ID, rng *objectSDK.Range) (*objectSDK.Object, error) { +func (r *request) GetObject(ctx context.Context, id oid.ID, rng *objectSDK.Range, payloadBuffer []byte) (*objectSDK.Object, error) { w := NewSimpleObjectWriter() + w.SetPayloadBuffer(payloadBuffer) p := r.prm p.common = p.common.WithLocalOnly(false) diff --git a/pkg/services/object/get/assembler.go b/pkg/services/object/get/assembler.go index 321d4b16d..2299751e1 100644 --- a/pkg/services/object/get/assembler.go +++ b/pkg/services/object/get/assembler.go @@ -10,7 +10,7 @@ import ( ) type objectGetter interface { - GetObject(ctx context.Context, id oid.ID, rng *objectSDK.Range) (*objectSDK.Object, error) + GetObject(ctx context.Context, id oid.ID, rng *objectSDK.Range, buffer []byte) (*objectSDK.Object, error) HeadObject(ctx context.Context, id oid.ID) (*objectSDK.Object, error) } @@ -77,7 +77,7 @@ func (a *assembler) getLastPartOrLinkObjectID() (oid.ID, bool) { } func (a *assembler) initializeFromSourceObjectID(ctx context.Context, id oid.ID) (*oid.ID, []oid.ID, error) { - sourceObject, err := a.getChildObject(ctx, id, nil, true) + sourceObject, err := a.getChildObject(ctx, id, nil, true, nil) if err != nil { return nil, nil, err } @@ -131,8 +131,8 @@ func (a *assembler) initializeFromSourceObjectID(ctx context.Context, id oid.ID) return nil, sourceObject.Children(), nil } -func (a *assembler) getChildObject(ctx context.Context, id oid.ID, rng *objectSDK.Range, verifyIsChild bool) (*objectSDK.Object, error) { - obj, err := a.objGetter.GetObject(ctx, id, rng) +func (a *assembler) getChildObject(ctx context.Context, id oid.ID, rng *objectSDK.Range, verifyIsChild bool, payloadBuffer []byte) (*objectSDK.Object, error) { + obj, err := a.objGetter.GetObject(ctx, id, rng, payloadBuffer) if err != nil { return nil, err } @@ -176,13 +176,14 @@ 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 { withRng := len(partRanges) > 0 && a.rng != nil + var buffer []byte for i := range partIDs { var r *objectSDK.Range if withRng { r = &partRanges[i] } - child, err := a.getChildObject(ctx, partIDs[i], r, verifyIsChild) + child, err := a.getChildObject(ctx, partIDs[i], r, verifyIsChild, buffer) if err != nil { return err } @@ -190,6 +191,8 @@ func (a *assembler) assemblePayloadByObjectIDs(ctx context.Context, writer Objec if err := writer.WriteChunk(ctx, child.Payload()); err != nil { return err } + + buffer = child.Payload() } return nil } diff --git a/pkg/services/object/get/get_test.go b/pkg/services/object/get/get_test.go index 9c5506064..b6b77506e 100644 --- a/pkg/services/object/get/get_test.go +++ b/pkg/services/object/get/get_test.go @@ -629,6 +629,7 @@ func TestGetRemoteSmall(t *testing.T) { *c1, *c2 = *c2, *c1 + w.SetPayloadBuffer(make([]byte, 0)) err = svc.Get(ctx, p) require.NoError(t, err) require.Equal(t, obj, w.Object()) diff --git a/pkg/services/object/get/writer.go b/pkg/services/object/get/writer.go index 1b842adeb..0f8c71f7b 100644 --- a/pkg/services/object/get/writer.go +++ b/pkg/services/object/get/writer.go @@ -49,10 +49,18 @@ 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 { s.obj = obj - s.pld = make([]byte, 0, obj.PayloadSize()) + if s.pld == nil { + s.pld = make([]byte, 0, obj.PayloadSize()) + } return nil }