69 lines
1.2 KiB
Go
69 lines
1.2 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)
|
|
}
|
|
|
|
func New(conf Config) *Cache {
|
|
return &Cache{
|
|
updateLock: keyedmutex.New(),
|
|
src: conf.Src,
|
|
ttl: conf.TTL,
|
|
maxSize: conf.MaxSize,
|
|
lock: sync.Mutex{},
|
|
cache: make(map[string]*list.Element, conf.MaxSize+1),
|
|
ll: list.New(),
|
|
}
|
|
}
|
|
|
|
func (c *Cache) Get(key string) (interface{}, error) {
|
|
ok, val, err := c.get(key)
|
|
if ok {
|
|
return val, err
|
|
}
|
|
|
|
return c.load(key)
|
|
}
|
|
|
|
func (c *Cache) Evict(key string) {
|
|
c.lock.Lock()
|
|
defer c.lock.Unlock()
|
|
c.evict(key)
|
|
}
|
|
|
|
func (c *Cache) Stats() Stats {
|
|
c.lock.Lock()
|
|
defer c.lock.Unlock()
|
|
return c.stats
|
|
}
|