@@ -165,6 +165,9 @@ type Uploader struct {
165
165
166
166
// Defines the buffer strategy used when uploading a part
167
167
BufferProvider ReadSeekerWriteToProvider
168
+
169
+ // partPool allows for the re-usage of streaming payload part buffers between upload calls
170
+ partPool * partPool
168
171
}
169
172
170
173
// NewUploader creates a new Uploader instance to upload objects to S3. Pass In
@@ -201,6 +204,8 @@ func newUploader(client s3iface.S3API, options ...func(*Uploader)) *Uploader {
201
204
option (u )
202
205
}
203
206
207
+ u .partPool = newPartPool (u .PartSize )
208
+
204
209
return u
205
210
}
206
211
@@ -283,6 +288,13 @@ func (u Uploader) UploadWithContext(ctx aws.Context, input *UploadInput, opts ..
283
288
for _ , opt := range opts {
284
289
opt (& i .cfg )
285
290
}
291
+
292
+ // If PartSize was changed or partPool was never setup then we need to allocated a new pool
293
+ // so that we return []byte slices of the correct size
294
+ if i .cfg .partPool == nil || i .cfg .partPool .partSize != i .cfg .PartSize {
295
+ i .cfg .partPool = newPartPool (i .cfg .PartSize )
296
+ }
297
+
286
298
i .cfg .RequestOptions = append (i .cfg .RequestOptions , request .WithAppendUserAgent ("S3Manager" ))
287
299
288
300
return i .upload ()
@@ -352,8 +364,6 @@ type uploader struct {
352
364
353
365
readerPos int64 // current reader position
354
366
totalSize int64 // set to -1 if the size is not known
355
-
356
- bufferPool sync.Pool
357
367
}
358
368
359
369
// internal logic for deciding whether to upload a single part or use a
@@ -393,10 +403,6 @@ func (u *uploader) init() error {
393
403
u .cfg .MaxUploadParts = MaxUploadParts
394
404
}
395
405
396
- u .bufferPool = sync.Pool {
397
- New : func () interface {} { return make ([]byte , u .cfg .PartSize ) },
398
- }
399
-
400
406
// Try to get the total size for some optimizations
401
407
return u .initSize ()
402
408
}
@@ -466,12 +472,12 @@ func (u *uploader) nextReader() (io.ReadSeeker, int, func(), error) {
466
472
return reader , int (n ), cleanup , err
467
473
468
474
default :
469
- part := u .bufferPool .Get ().([]byte )
475
+ part := u .cfg . partPool .Get ().([]byte )
470
476
n , err := readFillBuf (r , part )
471
477
u .readerPos += int64 (n )
472
478
473
479
cleanup := func () {
474
- u .bufferPool .Put (part )
480
+ u .cfg . partPool .Put (part )
475
481
}
476
482
477
483
return bytes .NewReader (part [0 :n ]), n , cleanup , err
@@ -751,3 +757,18 @@ func (u *multiuploader) complete() *s3.CompleteMultipartUploadOutput {
751
757
752
758
return resp
753
759
}
760
+
761
+ type partPool struct {
762
+ partSize int64
763
+ sync.Pool
764
+ }
765
+
766
+ func newPartPool (partSize int64 ) * partPool {
767
+ p := & partPool {partSize : partSize }
768
+
769
+ p .New = func () interface {} {
770
+ return make ([]byte , p .partSize )
771
+ }
772
+
773
+ return p
774
+ }
0 commit comments