diff --git a/api/layer/multipart_upload.go b/api/layer/multipart_upload.go index c4213864..946b3b99 100644 --- a/api/layer/multipart_upload.go +++ b/api/layer/multipart_upload.go @@ -312,13 +312,25 @@ func (n *layer) uploadPart(ctx context.Context, multipartInfo *data.MultipartInf }, } - chunk := n.buffers.Get().(*[]byte) + var ( + chunk *[]byte + isReturnToPool bool + ) + + if p.Size > n.neoFS.MaxObjectSize()/2 { + chunk = n.buffers.Get().(*[]byte) + isReturnToPool = true + } else { + smallChunk := make([]byte, p.Size) + chunk = &smallChunk + } + var totalBytes int // slice part manually. Simultaneously considering the part is a single object for user. for { prm.Multipart.SplitPreviousID = &splitPreviousID - if !splitFirstID.Equals(oid.ID{}) { + if !splitFirstID.IsZero() { prm.Multipart.SplitFirstID = &splitFirstID } @@ -350,7 +362,10 @@ func (n *layer) uploadPart(ctx context.Context, multipartInfo *data.MultipartInf break } - n.buffers.Put(chunk) + + if isReturnToPool { + n.buffers.Put(chunk) + } reqInfo := api.GetReqInfo(ctx) n.log.Debug("upload part", diff --git a/internal/neofs/neofs.go b/internal/neofs/neofs.go index b69f0dff..660ca5a6 100644 --- a/internal/neofs/neofs.go +++ b/internal/neofs/neofs.go @@ -335,8 +335,20 @@ func (x *NeoFS) CreateObject(ctx context.Context, prm layer.PrmObjectCreate) (oi opts.SetCurrentNeoFSEpoch(x.epochGetter.CurrentEpoch()) opts.SetPayloadSize(prm.PayloadSize) - data := x.buffers.Get() - chunk := data.(*[]byte) + var ( + chunk *[]byte + returnToPool bool + ) + + if prm.PayloadSize > 0 && prm.PayloadSize < uint64(x.MaxObjectSize()/2) { + c := make([]byte, prm.PayloadSize) + chunk = &c + } else { + data := x.buffers.Get() + chunk = data.(*[]byte) + returnToPool = true + } + opts.SetPayloadBuffer(*chunk) if x.cfg.IsHomomorphicEnabled { @@ -348,7 +360,9 @@ func (x *NeoFS) CreateObject(ctx context.Context, prm layer.PrmObjectCreate) (oi } objID, err := slicer.Put(ctx, x.pool, obj, x.signer(ctx), prm.Payload, opts) - x.buffers.Put(chunk) + if returnToPool { + x.buffers.Put(chunk) + } if err != nil { return oid.ID{}, fmt.Errorf("slicer put: %w", err) @@ -373,11 +387,24 @@ func (x *NeoFS) CreateObject(ctx context.Context, prm layer.PrmObjectCreate) (oi return oid.ID{}, fmt.Errorf("put init: %w", err) } - data := x.buffers.Get() - chunk := data.(*[]byte) + var ( + chunk *[]byte + returnToPool bool + ) + + if prm.PayloadSize > 0 && prm.PayloadSize < uint64(x.MaxObjectSize()/2) { + c := make([]byte, prm.PayloadSize) + chunk = &c + } else { + data := x.buffers.Get() + chunk = data.(*[]byte) + returnToPool = true + } _, err = io.CopyBuffer(writer, prm.Payload, *chunk) - x.buffers.Put(chunk) + if returnToPool { + x.buffers.Put(chunk) + } if err != nil { return oid.ID{}, fmt.Errorf("copy payload with buffer: %w", err)