// getWithPipe invokes getter and copies the resulting data into
// buf. If ctx is done before all data is copied, getWithPipe closes
// the pipe with an error, and returns early with an error.
-func getWithPipe(ctx context.Context, loc string, buf []byte, getter func(context.Context, string, io.Writer) error) (int, error) {
+func getWithPipe(ctx context.Context, loc string, buf []byte, br BlockReader) (int, error) {
piper, pipew := io.Pipe()
go func() {
- pipew.CloseWithError(getter(ctx, loc, pipew))
+ pipew.CloseWithError(br.ReadBlock(ctx, loc, pipew))
}()
done := make(chan struct{})
var size int
// from buf into the pipe. If ctx is done before all data is copied,
// putWithPipe closes the pipe with an error, and returns early with
// an error.
-func putWithPipe(ctx context.Context, loc string, buf []byte, putter func(context.Context, string, io.Reader) error) error {
+func putWithPipe(ctx context.Context, loc string, buf []byte, bw BlockWriter) error {
piper, pipew := io.Pipe()
copyErr := make(chan error)
go func() {
putErr := make(chan error, 1)
go func() {
- putErr <- putter(ctx, loc, piper)
+ putErr <- bw.WriteBlock(ctx, loc, piper)
close(putErr)
}()
"time"
)
+type BlockWriter interface {
+ // WriteBlock reads all data from r, writes it to a backing
+ // store as "loc", and returns the number of bytes written.
+ WriteBlock(ctx context.Context, loc string, r io.Reader) error
+}
+
+type BlockReader interface {
+ // ReadBlock retrieves data previously stored as "loc" and
+ // writes it to w.
+ ReadBlock(ctx context.Context, loc string, w io.Writer) error
+}
+
// A Volume is an interface representing a Keep back-end storage unit:
// for example, a single mounted disk, a RAID array, an Amazon S3 volume,
// etc.
// Get retrieves a block, copies it to the given slice, and returns
// the number of bytes copied.
func (v *UnixVolume) Get(ctx context.Context, loc string, buf []byte) (int, error) {
- return getWithPipe(ctx, loc, buf, v.get)
+ return getWithPipe(ctx, loc, buf, v)
}
-func (v *UnixVolume) get(ctx context.Context, loc string, w io.Writer) error {
+// ReadBlock implements BlockReader.
+func (v *UnixVolume) ReadBlock(ctx context.Context, loc string, w io.Writer) error {
path := v.blockPath(loc)
stat, err := v.stat(path)
if err != nil {
// returns a FullError. If the write fails due to some other error,
// that error is returned.
func (v *UnixVolume) Put(ctx context.Context, loc string, block []byte) error {
- return putWithPipe(ctx, loc, block, v.put)
+ return putWithPipe(ctx, loc, block, v)
}
-func (v *UnixVolume) put(ctx context.Context, loc string, rdr io.Reader) error {
+// ReadBlock implements BlockWriter.
+func (v *UnixVolume) WriteBlock(ctx context.Context, loc string, rdr io.Reader) error {
if v.ReadOnly {
return MethodDisabledError
}