toolbox/kvmemcache/internal.go

68 lines
1.2 KiB
Go

package kvmemcache
import (
"time"
)
func (c *Cache) put(key string, value interface{}, err error) {
c.lock.Lock()
defer c.lock.Unlock()
c.stats.Misses++
c.cache[key] = c.ll.PushFront(lruItem{
key: key,
createdAt: time.Now(),
value: value,
err: err,
})
if c.maxSize != 0 && len(c.cache) > c.maxSize {
li := c.ll.Back()
c.ll.Remove(li)
delete(c.cache, li.Value.(lruItem).key)
}
}
func (c *Cache) evict(key string) {
elem := c.cache[key]
if elem != nil {
delete(c.cache, key)
c.ll.Remove(elem)
}
}
func (c *Cache) get(key string) (ok bool, val interface{}, err error) {
c.lock.Lock()
defer c.lock.Unlock()
li := c.cache[key]
if li == nil {
return false, nil, nil
}
item := li.Value.(lruItem)
// Maybe evict.
if c.ttl != 0 && time.Since(item.createdAt) > c.ttl {
c.evict(key)
return false, nil, nil
}
c.stats.Hits++
return true, item.value, item.err
}
func (c *Cache) load(key string) (interface{}, error) {
c.updateLock.Lock(key)
defer c.updateLock.Unlock(key)
// Check again in case we lost the update race.
ok, val, err := c.get(key)
if ok {
return val, err
}
// Won the update race.
val, err = c.src(key)
c.put(key, val, err)
return val, err
}