12483: More loading speed.
[arvados.git] / sdk / go / keepclient / block_cache.go
index 5d8daad60d4be6dfad3a6f3c2003f759f2967956..539975e1616637cad2d002c8e9e7d697c0820f63 100644 (file)
@@ -18,9 +18,8 @@ type BlockCache struct {
        // default size (currently 4) is used instead.
        MaxBlocks int
 
-       cache     map[string]*cacheBlock
-       mtx       sync.Mutex
-       setupOnce sync.Once
+       cache map[string]*cacheBlock
+       mtx   sync.Mutex
 }
 
 const defaultMaxBlocks = 4
@@ -50,12 +49,27 @@ func (c *BlockCache) Sweep() {
        }
 }
 
+// ReadAt returns data from the cache, first retrieving it from Keep if
+// necessary.
+func (c *BlockCache) ReadAt(kc *KeepClient, locator string, p []byte, off int) (int, error) {
+       buf, err := c.Get(kc, locator)
+       if err != nil {
+               return 0, err
+       }
+       if off > len(buf) {
+               return 0, io.ErrUnexpectedEOF
+       }
+       return copy(p, buf[off:]), nil
+}
+
 // Get returns data from the cache, first retrieving it from Keep if
 // necessary.
 func (c *BlockCache) Get(kc *KeepClient, locator string) ([]byte, error) {
-       c.setupOnce.Do(c.setup)
        cacheKey := locator[:32]
        c.mtx.Lock()
+       if c.cache == nil {
+               c.cache = make(map[string]*cacheBlock)
+       }
        b, ok := c.cache[cacheKey]
        if !ok || b.err != nil {
                b = &cacheBlock{
@@ -93,16 +107,12 @@ func (c *BlockCache) Get(kc *KeepClient, locator string) ([]byte, error) {
        return b.data, b.err
 }
 
-func (c *BlockCache) setup() {
+func (c *BlockCache) Clear() {
        c.mtx.Lock()
-       c.cache = make(map[string]*cacheBlock)
+       c.cache = nil
        c.mtx.Unlock()
 }
 
-func (c *BlockCache) Clear() {
-       c.setup()
-}
-
 type timeSlice []time.Time
 
 func (ts timeSlice) Len() int { return len(ts) }