introduce RWLock for caching obj.Stat()

This commit is contained in:
trbs 2017-03-14 23:05:51 +01:00
parent b523eef294
commit f1ba45723c
1 changed files with 17 additions and 8 deletions

View File

@ -7,6 +7,7 @@ import (
"path"
"restic"
"strings"
"sync"
"restic/backend"
"restic/errors"
@ -24,8 +25,8 @@ type s3 struct {
connChan chan struct{}
bucketname string
prefix string
cacheObjName string
cacheSize int64
cacheMutex sync.RWMutex
cacheObjSize map[string]int64
}
// Open opens the S3 backend at bucket and region. The bucket is created if it
@ -38,7 +39,12 @@ func Open(cfg Config) (restic.Backend, error) {
return nil, errors.Wrap(err, "minio.New")
}
be := &s3{client: client, bucketname: cfg.Bucket, prefix: cfg.Prefix}
be := &s3{
client: client,
bucketname: cfg.Bucket,
prefix: cfg.Prefix,
cacheObjSize: make(map[string]int64),
}
tr := &http.Transport{MaxIdleConnsPerHost: connLimit}
client.SetCustomTransport(tr)
@ -189,17 +195,20 @@ func (be *s3) Load(h restic.Handle, length int, offset int64) (io.ReadCloser, er
}()
// otherwise use a buffer with ReadAt
if be.cacheObjName == objName {
size = be.cacheSize
} else {
be.cacheMutex.RLock()
size, cacheHit := be.cacheObjSize[objName]
be.cacheMutex.RUnlock()
if !cacheHit {
info, err := obj.Stat()
if err != nil {
_ = obj.Close()
return nil, errors.Wrap(err, "obj.Stat")
}
size = info.Size
be.cacheObjName = objName
be.cacheSize = size
be.cacheMutex.Lock()
be.cacheObjSize[objName] = size
be.cacheMutex.Unlock()
}
if offset > size {