diff --git a/cmd/xl-v1-object.go b/cmd/xl-v1-object.go index 134af0a43..1ac3f23fe 100644 --- a/cmd/xl-v1-object.go +++ b/cmd/xl-v1-object.go @@ -202,19 +202,22 @@ func (xl xlObjects) GetObject(bucket, object string, startOffset int64, length i // Object cache enabled block. if xlMeta.Stat.Size > 0 && xl.objCacheEnabled { // Validate if we have previous cache. - var cachedBuffer io.ReadSeeker + var cachedBuffer io.ReaderAt cachedBuffer, err = xl.objCache.Open(path.Join(bucket, object), modTime) - if err == nil { // Cache hit. - // Advance the buffer to offset as if it was read. - if _, err = cachedBuffer.Seek(startOffset, 0); err != nil { // Seek to the offset. - return traceError(err) - } - // Write the requested length. - if _, err = io.CopyN(writer, cachedBuffer, length); err != nil { + if err == nil { // Cache hit + // Create a new section reader, starting at an offset with length. + reader := io.NewSectionReader(cachedBuffer, startOffset, length) + + // Copy the data out. + if _, err = io.Copy(writer, reader); err != nil { return traceError(err) } + + // Success. return nil + } // Cache miss. + // For unknown error, return and error out. if err != objcache.ErrKeyNotFoundInCache { return traceError(err) diff --git a/pkg/objcache/objcache.go b/pkg/objcache/objcache.go index 3a63a68de..d07a86214 100644 --- a/pkg/objcache/objcache.go +++ b/pkg/objcache/objcache.go @@ -217,7 +217,7 @@ func (c *Cache) Create(key string, size int64) (w io.WriteCloser, err error) { // returns an error ErrNotFoundInCache, if the key does not exist. // Returns ErrKeyNotFoundInCache if entry's lastAccessedTime is older // than objModTime. -func (c *Cache) Open(key string, objModTime time.Time) (io.ReadSeeker, error) { +func (c *Cache) Open(key string, objModTime time.Time) (io.ReaderAt, error) { // Entry exists, return the readable buffer. c.mutex.Lock() defer c.mutex.Unlock() diff --git a/pkg/objcache/objcache_test.go b/pkg/objcache/objcache_test.go index f1eed32d3..25cd1c69a 100644 --- a/pkg/objcache/objcache_test.go +++ b/pkg/objcache/objcache_test.go @@ -20,7 +20,6 @@ package objcache import ( "bytes" "io" - "io/ioutil" "testing" "time" ) @@ -173,7 +172,8 @@ func TestObjCache(t *testing.T) { t.Errorf("Test case 4 expected to pass, failed instead %s", err) } // Reads everything stored for key "test". - cbytes, err := ioutil.ReadAll(r) + cbytes := make([]byte, 5) + _, err = r.ReadAt(cbytes, 0) if err != nil { t.Errorf("Test case 4 expected to pass, failed instead %s", err) }