package kvmemcache import ( "time" ) func (c *Cache) getItem(key string) *lruItem { c.lock.Lock() defer c.lock.Unlock() elem, ok := c.cache[key] if !ok { c.stats.Misses++ return nil } item := elem.Value.(*lruItem) if c.ttl != 0 && time.Since(item.createdAt) > c.ttl { c.stats.Expired++ c.evictKey(key) return nil } c.stats.Hits++ c.ll.MoveToFront(elem) return item } func (c *Cache) loadItemFromSource(key string) *lruItem { c.updateLock.Lock(key) defer c.updateLock.Unlock(key) // May have lost update race. if item := c.getItem(key); item != nil { return item } val, err := c.src(key) item := &lruItem{ key: key, value: val, err: err, } if c.ttl != 0 { item.createdAt = time.Now() } c.putItem(key, item) return item } func (c *Cache) putItem(key string, item *lruItem) { c.lock.Lock() defer c.lock.Unlock() c.cache[key] = c.ll.PushFront(item) if c.maxSize > 0 && len(c.cache) > c.maxSize { elem := c.ll.Back() c.ll.Remove(elem) delete(c.cache, elem.Value.(*lruItem).key) } } func (c *Cache) evictKey(key string) { elem, ok := c.cache[key] if !ok { return } delete(c.cache, key) c.ll.Remove(elem) }