1 // A Volume is an interface representing a Keep back-end storage unit:
2 // for example, a single mounted disk, a RAID array, an Amazon S3 volume,
13 type Volume interface {
14 // Get a block. IFF the returned error is nil, the caller must
15 // put the returned slice back into the buffer pool when it's
16 // finished with it. (Otherwise, the buffer pool will be
17 // depleted and eventually -- when all available buffers are
18 // used and not returned -- operations will reach deadlock.)
19 Get(loc string) ([]byte, error)
20 // Confirm Get() would return a buffer with exactly the same
21 // content as buf. If so, return nil. If not, return
22 // CollisionError or DiskHashError (depending on whether the
23 // data on disk matches the expected hash), or whatever error
24 // was encountered opening/reading the file.
25 Compare(loc string, data []byte) error
26 Put(loc string, data []byte) error
27 Touch(loc string) error
28 Mtime(loc string) (time.Time, error)
29 IndexTo(prefix string, writer io.Writer) error
30 Delete(loc string) error
31 Status() *VolumeStatus
36 // A VolumeManager tells callers which volumes can read, which volumes
37 // can write, and on which volume the next write should be attempted.
38 type VolumeManager interface {
39 // AllReadable returns all volumes.
40 AllReadable() []Volume
41 // AllWritable returns all volumes that aren't known to be in
42 // a read-only state. (There is no guarantee that a write to
43 // one will succeed, though.)
44 AllWritable() []Volume
45 // NextWritable returns the volume where the next new block
46 // should be written. A VolumeManager can select a volume in
47 // order to distribute activity across spindles, fill up disks
48 // with more free space, etc.
50 // Close shuts down the volume manager cleanly.
54 type RRVolumeManager struct {
60 func MakeRRVolumeManager(volumes []Volume) *RRVolumeManager {
61 vm := &RRVolumeManager{}
62 for _, v := range volumes {
63 vm.readables = append(vm.readables, v)
65 vm.writables = append(vm.writables, v)
71 func (vm *RRVolumeManager) AllReadable() []Volume {
75 func (vm *RRVolumeManager) AllWritable() []Volume {
79 func (vm *RRVolumeManager) NextWritable() Volume {
80 if len(vm.writables) == 0 {
83 i := atomic.AddUint32(&vm.counter, 1)
84 return vm.writables[i%uint32(len(vm.writables))]
87 func (vm *RRVolumeManager) Close() {