Add ReaderAt support to content store
Signed-off-by: Derek McGowan <derek@mcgstyle.net>
This commit is contained in:
@@ -30,6 +30,7 @@ var (
|
||||
|
||||
type Provider interface {
|
||||
Reader(ctx context.Context, dgst digest.Digest) (io.ReadCloser, error)
|
||||
ReaderAt(ctx context.Context, dgst digest.Digest) (io.ReaderAt, error)
|
||||
}
|
||||
|
||||
type Ingester interface {
|
||||
|
||||
26
content/readerat.go
Normal file
26
content/readerat.go
Normal file
@@ -0,0 +1,26 @@
|
||||
package content
|
||||
|
||||
import (
|
||||
"io"
|
||||
"os"
|
||||
)
|
||||
|
||||
// readerat implements io.ReaderAt in a completely stateless manner by opening
|
||||
// the referenced file for each call to ReadAt.
|
||||
type readerAt struct {
|
||||
f string
|
||||
}
|
||||
|
||||
func (ra readerAt) ReadAt(p []byte, offset int64) (int, error) {
|
||||
fp, err := os.Open(ra.f)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
defer fp.Close()
|
||||
|
||||
if _, err := fp.Seek(offset, io.SeekStart); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return fp.Read(p)
|
||||
}
|
||||
@@ -58,11 +58,7 @@ func (s *store) info(dgst digest.Digest, fi os.FileInfo) Info {
|
||||
}
|
||||
}
|
||||
|
||||
// Open returns an io.ReadCloser for the blob.
|
||||
//
|
||||
// TODO(stevvooe): This would work much better as an io.ReaderAt in practice.
|
||||
// Right now, we are doing type assertion to tease that out, but it won't scale
|
||||
// well.
|
||||
// Reader returns an io.ReadCloser for the blob.
|
||||
func (s *store) Reader(ctx context.Context, dgst digest.Digest) (io.ReadCloser, error) {
|
||||
fp, err := os.Open(s.blobPath(dgst))
|
||||
if err != nil {
|
||||
@@ -75,6 +71,11 @@ func (s *store) Reader(ctx context.Context, dgst digest.Digest) (io.ReadCloser,
|
||||
return fp, nil
|
||||
}
|
||||
|
||||
// ReaderAt returns an io.ReaderAt for the blob.
|
||||
func (s *store) ReaderAt(ctx context.Context, dgst digest.Digest) (io.ReaderAt, error) {
|
||||
return readerAt{f: s.blobPath(dgst)}, nil
|
||||
}
|
||||
|
||||
// Delete removes a blob by its digest.
|
||||
//
|
||||
// While this is safe to do concurrently, safe exist-removal logic must hold
|
||||
|
||||
Reference in New Issue
Block a user