-// If the block could not be opened or read, Read returns a nil slice
-// and the os.Error that was generated.
-//
-// If the block is present but its content hash does not match loc,
-// Read returns the block and a CorruptError. It is the caller's
-// responsibility to decide what (if anything) to do with the
-// corrupted data block.
-//
-func (v *UnixVolume) Read(loc string) ([]byte, error) {
- buf, err := ioutil.ReadFile(v.blockPath(loc))
- return buf, err
+// Get returns a nil buffer IFF it returns a non-nil error.
+func (v *UnixVolume) Get(loc string) ([]byte, error) {
+ path := v.blockPath(loc)
+ stat, err := v.stat(path)
+ if err != nil {
+ return nil, v.translateError(err)
+ }
+ buf := bufs.Get(int(stat.Size()))
+ err = v.getFunc(path, func(rdr io.Reader) error {
+ _, err = io.ReadFull(rdr, buf)
+ return err
+ })
+ if err != nil {
+ bufs.Put(buf)
+ return nil, err
+ }
+ return buf, nil
+}
+
+// Compare returns nil if Get(loc) would return the same content as
+// expect. It is functionally equivalent to Get() followed by
+// bytes.Compare(), but uses less memory.
+func (v *UnixVolume) Compare(loc string, expect []byte) error {
+ path := v.blockPath(loc)
+ if _, err := v.stat(path); err != nil {
+ return v.translateError(err)
+ }
+ return v.getFunc(path, func(rdr io.Reader) error {
+ return compareReaderWithBuf(rdr, expect, loc[:32])
+ })