Skip to content

Commit

Permalink
storage: Peek API talks about close explicitly.
Browse files Browse the repository at this point in the history
Opens the way to a storage implementation that makes reuse of buffers.
  • Loading branch information
warpfork committed Oct 14, 2021
1 parent 522500c commit 3bb477f
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 3 deletions.
7 changes: 6 additions & 1 deletion storage/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,13 @@ type VectorWritableStorage interface {
// The PeekableStorage.Peek method is essentially the same as ReadableStorage.Get --
// but by contrast, ReadableStorage is expected to return a safe copy.
// PeekableStorage can be used when the caller knows they will not mutate the returned slice.
//
// An io.Closer is returned along with the byte slice.
// The Close method on the Closer must be called when the caller is done with the byte slice;
// otherwise, memory leaks may result.
// (Implementers of this interface may be expecting to reuse the byte slice after Close is called.)
type PeekableStorage interface {
Peek(ctx context.Context, key string) ([]byte, error)
Peek(ctx context.Context, key string) ([]byte, io.Closer, error)
}

// the following are all hypothetical additional future interfaces (in varying degress of speculativeness):
Expand Down
14 changes: 12 additions & 2 deletions storage/funcs.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,11 +95,21 @@ func PutVec(ctx context.Context, store WritableStorage, key string, blobVec [][]
// This function will feature-detect the PeekableStorage interface, and use that if possible;
// otherwise it will fall back to using basic ReadableStorage methods transparently
// (meaning that a no-copy fastpath simply wasn't available).
func Peek(ctx context.Context, store ReadableStorage, key string) ([]byte, error) {
//
// An io.Closer is returned along with the byte slice.
// The Close method on the Closer must be called when the caller is done with the byte slice;
// otherwise, memory leaks may result.
// (Implementers of this interface may be expecting to reuse the byte slice after Close is called.)
func Peek(ctx context.Context, store ReadableStorage, key string) ([]byte, io.Closer, error) {
// Prefer the feature itself, first.
if peekable, ok := store.(PeekableStorage); ok {
return peekable.Peek(ctx, key)
}
// Fallback to basic.
return store.Get(ctx, key)
bs, err := store.Get(ctx, key)
return bs, noopCloser{}, err
}

type noopCloser struct{}

func (noopCloser) Close() error { return nil }

0 comments on commit 3bb477f

Please sign in to comment.