74 lines
1.2 KiB
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)
|
|
}
|