toolbox/kvmemcache/cache.go

74 lines
1.3 KiB
Go

package kvmemcache
import (
"container/list"
"sync"
"time"
"git.crumpington.com/public/toolbox/keyedmutex"
)
type Cache struct {
updateLock keyedmutex.KeyedMutex
src func(string) (interface{}, error)
ttl time.Duration
maxSize int
// Lock protects cache, ll, and stats.
lock sync.Mutex
cache map[string]*list.Element
ll *list.List
stats Stats
}
type lruItem struct {
key string
createdAt time.Time
value interface{}
err error
}
type Config struct {
MaxSize int
TTL time.Duration // Zero to ignore.
Src func(string) (interface{}, error)
}
type Stats struct {
Hits uint64
Misses uint64
Expired uint64
}
func New(conf Config) *Cache {
return &Cache{
lock: sync.Mutex{},
updateLock: keyedmutex.New(),
src: conf.Src,
ttl: conf.TTL,
maxSize: conf.MaxSize,
cache: make(map[string]*list.Element),
ll: list.New(),
}
}
func (c *Cache) Get(key string) (interface{}, error) {
item := c.getItem(key)
if item == nil {
item = c.loadItemFromSource(key)
}
return item.value, item.err
}
func (c *Cache) Evict(key string) {
c.lock.Lock()
defer c.lock.Unlock()
c.evictKey(key)
}
func (c Cache) Stats() Stats {
c.lock.Lock()
defer c.lock.Unlock()
return c.stats
}