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