objcache: Return io.ReaderAt to avoid Seeking and Reading. (#3735)

master
Harshavardhana 8 years ago committed by GitHub
parent 440866d26c
commit 22909c849e
  1. 19
      cmd/xl-v1-object.go
  2. 2
      pkg/objcache/objcache.go
  3. 4
      pkg/objcache/objcache_test.go

@ -202,19 +202,22 @@ func (xl xlObjects) GetObject(bucket, object string, startOffset int64, length i
// Object cache enabled block. // Object cache enabled block.
if xlMeta.Stat.Size > 0 && xl.objCacheEnabled { if xlMeta.Stat.Size > 0 && xl.objCacheEnabled {
// Validate if we have previous cache. // Validate if we have previous cache.
var cachedBuffer io.ReadSeeker var cachedBuffer io.ReaderAt
cachedBuffer, err = xl.objCache.Open(path.Join(bucket, object), modTime) cachedBuffer, err = xl.objCache.Open(path.Join(bucket, object), modTime)
if err == nil { // Cache hit. if err == nil { // Cache hit
// Advance the buffer to offset as if it was read. // Create a new section reader, starting at an offset with length.
if _, err = cachedBuffer.Seek(startOffset, 0); err != nil { // Seek to the offset. reader := io.NewSectionReader(cachedBuffer, startOffset, length)
return traceError(err)
} // Copy the data out.
// Write the requested length. if _, err = io.Copy(writer, reader); err != nil {
if _, err = io.CopyN(writer, cachedBuffer, length); err != nil {
return traceError(err) return traceError(err)
} }
// Success.
return nil return nil
} // Cache miss. } // Cache miss.
// For unknown error, return and error out. // For unknown error, return and error out.
if err != objcache.ErrKeyNotFoundInCache { if err != objcache.ErrKeyNotFoundInCache {
return traceError(err) return traceError(err)

@ -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 an error ErrNotFoundInCache, if the key does not exist.
// Returns ErrKeyNotFoundInCache if entry's lastAccessedTime is older // Returns ErrKeyNotFoundInCache if entry's lastAccessedTime is older
// than objModTime. // 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. // Entry exists, return the readable buffer.
c.mutex.Lock() c.mutex.Lock()
defer c.mutex.Unlock() defer c.mutex.Unlock()

@ -20,7 +20,6 @@ package objcache
import ( import (
"bytes" "bytes"
"io" "io"
"io/ioutil"
"testing" "testing"
"time" "time"
) )
@ -173,7 +172,8 @@ func TestObjCache(t *testing.T) {
t.Errorf("Test case 4 expected to pass, failed instead %s", err) t.Errorf("Test case 4 expected to pass, failed instead %s", err)
} }
// Reads everything stored for key "test". // Reads everything stored for key "test".
cbytes, err := ioutil.ReadAll(r) cbytes := make([]byte, 5)
_, err = r.ReadAt(cbytes, 0)
if err != nil { if err != nil {
t.Errorf("Test case 4 expected to pass, failed instead %s", err) t.Errorf("Test case 4 expected to pass, failed instead %s", err)
} }

Loading…
Cancel
Save