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 } 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) GetStats() Stats { c.lock.Lock() defer c.lock.Unlock() return c.stats }