72 lines
1.1 KiB
Go
72 lines
1.1 KiB
Go
package kvmemcache
|
|
|
|
import "time"
|
|
|
|
func (c *Cache) getItem(key string) *lruItem {
|
|
c.lock.Lock()
|
|
defer c.lock.Unlock()
|
|
|
|
li, ok := c.cache[key]
|
|
if !ok {
|
|
c.stats.Misses++
|
|
return nil
|
|
}
|
|
|
|
item := li.Value.(*lruItem)
|
|
if c.ttl != 0 && time.Since(item.createdAt) > c.ttl {
|
|
c.evictKey(key)
|
|
c.stats.Misses++
|
|
return nil
|
|
}
|
|
|
|
c.stats.Hits++
|
|
c.ll.MoveToFront(li)
|
|
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 {
|
|
li := c.ll.Back()
|
|
c.ll.Remove(li)
|
|
delete(c.cache, li.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)
|
|
}
|