toolbox/kvmemcache/internal.go

74 lines
1.2 KiB
Go

package kvmemcache
import (
"time"
)
func (c *Cache) getItem(key string) *lruItem {
c.lock.Lock()
defer c.lock.Unlock()
elem, ok := c.cache[key]
if !ok {
c.stats.Misses++
return nil
}
item := elem.Value.(*lruItem)
if c.ttl != 0 && time.Since(item.createdAt) > c.ttl {
c.stats.Expired++
c.evictKey(key)
return nil
}
c.stats.Hits++
c.ll.MoveToFront(elem)
return item
}
func (c *Cache) loadItemFromSource(key string) *lruItem {
c.updateLock.Lock(key)
defer c.updateLock.Unlock(key)
// May have lost update race.
if item := c.getItem(key); item != nil {
return item
}
val, err := c.src(key)
item := &lruItem{
key: key,
value: val,
err: err,
}
if c.ttl != 0 {
item.createdAt = time.Now()
}
c.putItem(key, item)
return item
}
func (c *Cache) putItem(key string, item *lruItem) {
c.lock.Lock()
defer c.lock.Unlock()
c.cache[key] = c.ll.PushFront(item)
if c.maxSize > 0 && len(c.cache) > c.maxSize {
elem := c.ll.Back()
c.ll.Remove(elem)
delete(c.cache, elem.Value.(*lruItem).key)
}
}
func (c *Cache) evictKey(key string) {
elem, ok := c.cache[key]
if !ok {
return
}
delete(c.cache, key)
c.ll.Remove(elem)
}