From 9452f416bfb748f2ecb464c38c495a2c3f1bdf14 Mon Sep 17 00:00:00 2001 From: Alexander Neumann Date: Sat, 13 May 2017 23:17:10 +0200 Subject: [PATCH] s3: Use low level API for saving files benchmark old ns/op new ns/op delta BenchmarkBackendMinio/Save-4 184482294 40663344 -77.96% BenchmarkBackendS3/Save-4 35030825568 54475455819 +55.51% benchmark old MB/s new MB/s speedup BenchmarkBackendMinio/Save-4 90.95 412.64 4.54x BenchmarkBackendS3/Save-4 0.48 0.31 0.65x benchmark old allocs new allocs delta BenchmarkBackendMinio/Save-4 631 560 -11.25% BenchmarkBackendS3/Save-4 646 584 -9.60% benchmark old bytes new bytes delta BenchmarkBackendMinio/Save-4 66818060 50735 -99.92% BenchmarkBackendS3/Save-4 66834000 73024 -99.89% --- src/restic/backend/s3/s3.go | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/src/restic/backend/s3/s3.go b/src/restic/backend/s3/s3.go index 301598d04..bf340e163 100644 --- a/src/restic/backend/s3/s3.go +++ b/src/restic/backend/s3/s3.go @@ -80,6 +80,10 @@ func (be *s3) Location() string { return be.bucketname } +type Sizer interface { + Size() int64 +} + // Save stores data in the backend at the handle. func (be *s3) Save(h restic.Handle, rd io.Reader) (err error) { if err := h.Valid(); err != nil { @@ -88,6 +92,13 @@ func (be *s3) Save(h restic.Handle, rd io.Reader) (err error) { objName := be.Filename(h) + var size int64 + if r, ok := rd.(Sizer); ok { + size = r.Size() + } else { + panic("Save() got passed a reader without a method to determine the data size") + } + debug.Log("Save %v at %v", h, objName) // Check key does not already exist @@ -98,14 +109,14 @@ func (be *s3) Save(h restic.Handle, rd io.Reader) (err error) { } <-be.connChan - defer func() { - be.connChan <- struct{}{} - }() - debug.Log("PutObject(%v, %v)", - be.bucketname, objName) - n, err := be.client.PutObject(be.bucketname, objName, rd, "binary/octet-stream") - debug.Log("%v -> %v bytes, err %#v", objName, n, err) + debug.Log("PutObject(%v, %v)", be.bucketname, objName) + coreClient := minio.Core{be.client} + info, err := coreClient.PutObject(be.bucketname, objName, size, rd, nil, nil, nil) + + // return token + be.connChan <- struct{}{} + debug.Log("%v -> %v bytes, err %#v", objName, info.Size, err) return errors.Wrap(err, "client.PutObject") }