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 }