forked from TrueCloudLab/restic
Return bucket readers instead of buffering a key on read.
This commit is contained in:
parent
aaae7f33d3
commit
d30a95e8ad
1 changed files with 15 additions and 20 deletions
|
@ -3,7 +3,9 @@ package s3
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
"io/ioutil"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/mitchellh/goamz/aws"
|
"github.com/mitchellh/goamz/aws"
|
||||||
|
@ -117,40 +119,33 @@ func (b *S3) Create() (backend.Blob, error) {
|
||||||
return &blob, nil
|
return &blob, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *S3) get(t backend.Type, name string) (*s3Blob, error) {
|
|
||||||
blob := &s3Blob{
|
|
||||||
b: b,
|
|
||||||
}
|
|
||||||
|
|
||||||
path := s3path(t, name)
|
|
||||||
<-b.connChan
|
|
||||||
data, err := b.bucket.Get(path)
|
|
||||||
b.connChan <- struct{}{}
|
|
||||||
blob.buf = bytes.NewBuffer(data)
|
|
||||||
return blob, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get returns a reader that yields the content stored under the given
|
// Get returns a reader that yields the content stored under the given
|
||||||
// name. The reader should be closed after draining it.
|
// name. The reader should be closed after draining it.
|
||||||
func (b *S3) Get(t backend.Type, name string) (io.ReadCloser, error) {
|
func (b *S3) Get(t backend.Type, name string) (io.ReadCloser, error) {
|
||||||
return b.get(t, name)
|
path := s3path(t, name)
|
||||||
|
return b.bucket.GetReader(path)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetReader returns an io.ReadCloser for the Blob with the given name of
|
// GetReader returns an io.ReadCloser for the Blob with the given name of
|
||||||
// type t at offset and length. If length is 0, the reader reads until EOF.
|
// type t at offset and length. If length is 0, the reader reads until EOF.
|
||||||
func (b *S3) GetReader(t backend.Type, name string, offset, length uint) (io.ReadCloser, error) {
|
func (b *S3) GetReader(t backend.Type, name string, offset, length uint) (io.ReadCloser, error) {
|
||||||
blob, err := b.get(t, name)
|
rc, err := b.Get(t, name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
blob.buf.Next(int(offset))
|
n, errc := io.CopyN(ioutil.Discard, rc, int64(offset))
|
||||||
|
if errc != nil {
|
||||||
if length == 0 {
|
return nil, errc
|
||||||
return blob, nil
|
} else if n != int64(offset) {
|
||||||
|
return nil, fmt.Errorf("less bytes read than expected, read: %d, expected: %d", n, offset)
|
||||||
}
|
}
|
||||||
|
|
||||||
return backend.LimitReadCloser(blob, int64(length)), nil
|
if length == 0 {
|
||||||
|
return rc, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return backend.LimitReadCloser(rc, int64(length)), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test returns true if a blob of the given type and name exists in the backend.
|
// Test returns true if a blob of the given type and name exists in the backend.
|
||||||
|
|
Loading…
Reference in a new issue