X-Git-Url: https://git.arvados.org/arvados.git/blobdiff_plain/237adbd91e2dc0d15f79390f7e38f70d55372877..127e916894bcd16f6978aa6488c81e79a9ca2812:/sdk/go/keepclient/block_cache.go diff --git a/sdk/go/keepclient/block_cache.go b/sdk/go/keepclient/block_cache.go index 5d8daad60d..539975e161 100644 --- a/sdk/go/keepclient/block_cache.go +++ b/sdk/go/keepclient/block_cache.go @@ -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) }