Mike Burrows | bfd646d | 2015-06-19 13:44:18 -0700 | [diff] [blame] | 1 | // Copyright 2015 The Vanadium Authors. All rights reserved. |
| 2 | // Use of this source code is governed by a BSD-style |
| 3 | // license that can be found in the LICENSE file. |
| 4 | |
| 5 | // Package localblobstore is the interface to a local blob store. |
| 6 | // Implementations include fs_cablobstore. |
| 7 | package localblobstore |
| 8 | |
| 9 | import "v.io/v23/context" |
| 10 | |
| 11 | // A BlobStore represents a simple, content-addressable store. |
| 12 | type BlobStore interface { |
| 13 | // NewBlobReader() returns a pointer to a newly allocated BlobReader on |
| 14 | // the specified blobName. BlobReaders should not be used concurrently |
| 15 | // by multiple threads. Returned handles should be closed with |
| 16 | // Close(). |
| 17 | NewBlobReader(ctx *context.T, blobName string) (br BlobReader, err error) |
| 18 | |
| 19 | // NewBlobWriter() returns a pointer to a newly allocated BlobWriter on |
| 20 | // a newly created blob name, which can be found using the Name() |
| 21 | // method. BlobWriters should not be used concurrently by multiple |
| 22 | // threads. The returned handle should be closed with either the |
| 23 | // Close() or CloseWithoutFinalize() method to avoid leaking file |
| 24 | // handles. |
| 25 | NewBlobWriter(ctx *context.T) (bw BlobWriter, err error) |
| 26 | |
| 27 | // ResumeBlobWriter() returns a pointer to a newly allocated BlobWriter on |
| 28 | // an old, but unfinalized blob name. |
| 29 | ResumeBlobWriter(ctx *context.T, blobName string) (bw BlobWriter, err error) |
| 30 | |
| 31 | // DeleteBlob() deletes the named blob from the BlobStore. |
| 32 | DeleteBlob(ctx *context.T, blobName string) (err error) |
| 33 | |
| 34 | // GC() removes old temp files and content-addressed blocks that are no |
| 35 | // longer referenced by any blob. It may be called concurrently with |
| 36 | // other calls to GC(), and with uses of BlobReaders and BlobWriters. |
| 37 | GC(ctx *context.T) error |
| 38 | |
| 39 | // ListBlobIds() returns an iterator that can be used to enumerate the |
| 40 | // blobs in a BlobStore. Expected use is: |
| 41 | // |
| 42 | // iter := bs.ListBlobIds(ctx) |
| 43 | // for iter.Advance() { |
| 44 | // // Process iter.Value() here. |
| 45 | // } |
| 46 | // if iter.Err() != nil { |
| 47 | // // The loop terminated early due to an error. |
| 48 | // } |
| 49 | ListBlobIds(ctx *context.T) (iter Iter) |
| 50 | |
| 51 | // ListCAIds() returns an iterator that can be used to enumerate the |
| 52 | // content-addressable fragments in a BlobStore. Expected use is: |
| 53 | // |
| 54 | // iter := bs.ListCAIds(ctx) |
| 55 | // for iter.Advance() { |
| 56 | // // Process iter.Value() here. |
| 57 | // } |
| 58 | // if iter.Err() != nil { |
| 59 | // // The loop terminated early due to an error. |
| 60 | // } |
| 61 | ListCAIds(ctx *context.T) (iter Iter) |
| 62 | |
| 63 | // Root() returns the name of the root directory where the BlobStore is stored. |
| 64 | Root() string |
| 65 | } |
| 66 | |
| 67 | // A BlobReader allows a blob to be read using the standard ReadAt(), Read(), |
| 68 | // and Seek() calls. A BlobReader can be created with NewBlobReader(), and |
| 69 | // should be closed with the Close() method to avoid leaking file handles. |
| 70 | type BlobReader interface { |
| 71 | // ReadAt() fills b[] with up to len(b) bytes of data starting at |
| 72 | // position "at" within the blob that the BlobReader indicates, and |
| 73 | // returns the number of bytes read. |
| 74 | ReadAt(b []byte, at int64) (n int, err error) |
| 75 | |
| 76 | // Read() fills b[] with up to len(b) bytes of data starting at the |
| 77 | // current seek position of the BlobReader within the blob that the |
| 78 | // BlobReader indicates, and then both returns the number of bytes read |
| 79 | // and advances the BlobReader's seek position by that amount. |
| 80 | Read(b []byte) (n int, err error) |
| 81 | |
| 82 | // Seek() sets the seek position of the BlobReader to offset if |
| 83 | // whence==0, offset+current_seek_position if whence==1, and |
| 84 | // offset+end_of_blob if whence==2, and then returns the current seek |
| 85 | // position. |
| 86 | Seek(offset int64, whence int) (result int64, err error) |
| 87 | |
| 88 | // Close() indicates that the client will perform no further operations |
| 89 | // on the BlobReader. It releases any resources held by the |
| 90 | // BlobReader. |
| 91 | Close() error |
| 92 | |
| 93 | // Name() returns the BlobReader's name. |
| 94 | Name() string |
| 95 | |
| 96 | // Size() returns the BlobReader's size. |
| 97 | Size() int64 |
| 98 | |
| 99 | // IsFinalized() returns whether the BlobReader has been finalized. |
| 100 | IsFinalized() bool |
| 101 | |
| 102 | // Hash() returns the BlobReader's hash. It may be nil if the blob is |
| 103 | // not finalized. |
| 104 | Hash() []byte |
| 105 | } |
| 106 | |
| 107 | // A BlockOrFile represents a vector of bytes, and contains either a data |
| 108 | // block (as a []byte), or a (file name, size, offset) triple. |
| 109 | type BlockOrFile struct { |
| 110 | Block []byte // If FileName is empty, the bytes represented. |
| 111 | FileName string // If non-empty, the name of the file containing the bytes. |
| 112 | Size int64 // If FileName is non-empty, the number of bytes (or -1 for "all") |
| 113 | Offset int64 // If FileName is non-empty, the offset of the relevant bytes within the file. |
| 114 | } |
| 115 | |
| 116 | // A BlobWriter allows a blob to be written. If a blob has not yet been |
| 117 | // finalized, it also allows that blob to be extended. A BlobWriter may be |
| 118 | // created with NewBlobWriter(), and should be closed with Close() or |
| 119 | // CloseWithoutFinalize(). |
| 120 | type BlobWriter interface { |
| 121 | // AppendBlob() adds a (substring of a) pre-existing blob to the blob |
| 122 | // being written by the BlobWriter. The fragments of the pre-existing |
| 123 | // blob are not physically copied; they are referenced by both blobs. |
| 124 | AppendBlob(blobName string, size int64, offset int64) (err error) |
| 125 | |
| 126 | // AppendFragment() appends a fragment to the blob being written by the |
| 127 | // BlobWriter, where the fragment is composed of the byte vectors |
| 128 | // described by the elements of item[]. The fragment is copied into |
| 129 | // the blob store. |
| 130 | AppendFragment(item ...BlockOrFile) (err error) |
| 131 | |
| 132 | // Close() finalizes the BlobWriter, and indicates that the client will |
| 133 | // perform no further append operations on the BlobWriter. Any |
| 134 | // internal open file handles are closed. |
| 135 | Close() (err error) |
| 136 | |
| 137 | // CloseWithoutFinalize() indicates that the client will perform no |
| 138 | // further append operations on the BlobWriter, but does not finalize |
| 139 | // the blob. Any internal open file handles are closed. Clients are |
| 140 | // expected to need this operation infrequently. |
| 141 | CloseWithoutFinalize() (err error) |
| 142 | |
| 143 | // Name() returns the BlobWriter's name. |
| 144 | Name() string |
| 145 | |
| 146 | // Size() returns the BlobWriter's size. |
| 147 | Size() int64 |
| 148 | |
| 149 | // IsFinalized() returns whether the BlobWriter has been finalized. |
| 150 | IsFinalized() bool |
| 151 | |
| 152 | // Hash() returns the BlobWriter's hash, reflecting the bytes written so far. |
| 153 | Hash() []byte |
| 154 | } |
| 155 | |
| 156 | // A Iter represents an iterator that allows the client to enumerate |
| 157 | // all the blobs of fragments in a BlobStore. |
| 158 | type Iter interface { |
| 159 | // Advance() stages an item so that it may be retrieved via Value. |
| 160 | // Returns true iff there is an item to retrieve. Advance must be |
| 161 | // called before Value is called. |
| 162 | Advance() (advanced bool) |
| 163 | |
| 164 | // Value() returns the item that was staged by Advance. May panic if |
| 165 | // Advance returned false or was not called. Never blocks. |
| 166 | Value() (name string) |
| 167 | |
| 168 | // Err() returns any error encountered by Advance. Never blocks. |
| 169 | Err() error |
| 170 | } |