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 }