query from cache first when do cache.Take

master
kevin 4 years ago
parent 8d0f7dbb27
commit ff112fdaee

@ -82,12 +82,7 @@ func (c *Cache) Del(key string) {
} }
func (c *Cache) Get(key string) (interface{}, bool) { func (c *Cache) Get(key string) (interface{}, bool) {
c.lock.Lock() value, ok := c.doGet(key)
value, ok := c.data[key]
if ok {
c.lruCache.add(key)
}
c.lock.Unlock()
if ok { if ok {
c.stats.IncrementHit() c.stats.IncrementHit()
} else { } else {
@ -113,12 +108,25 @@ func (c *Cache) Set(key string, value interface{}) {
} }
func (c *Cache) Take(key string, fetch func() (interface{}, error)) (interface{}, error) { func (c *Cache) Take(key string, fetch func() (interface{}, error)) (interface{}, error) {
val, fresh, err := c.barrier.DoEx(key, func() (interface{}, error) { if val, ok := c.doGet(key); ok {
c.stats.IncrementHit()
return val, nil
}
var fresh bool
val, err := c.barrier.Do(key, func() (interface{}, error) {
// because O(1) on map search in memory, and fetch is an IO query
// so we do double check, cache might be taken by another call
if val, ok := c.doGet(key); ok {
return val, nil
}
v, e := fetch() v, e := fetch()
if e != nil { if e != nil {
return nil, e return nil, e
} }
fresh = true
c.Set(key, v) c.Set(key, v)
return v, nil return v, nil
}) })
@ -137,6 +145,18 @@ func (c *Cache) Take(key string, fetch func() (interface{}, error)) (interface{}
return val, nil return val, nil
} }
func (c *Cache) doGet(key string) (interface{}, bool) {
c.lock.Lock()
defer c.lock.Unlock()
value, ok := c.data[key]
if ok {
c.lruCache.add(key)
}
return value, ok
}
func (c *Cache) onEvict(key string) { func (c *Cache) onEvict(key string) {
// already locked // already locked
delete(c.data, key) delete(c.data, key)

Loading…
Cancel
Save