lru.go

  1package lru
  2
  3import (
  4	"sync"
  5
  6	"github.com/hashicorp/golang-lru/simplelru"
  7)
  8
  9// Cache is a thread-safe fixed size LRU cache.
 10type Cache struct {
 11	lru  simplelru.LRUCache
 12	lock sync.RWMutex
 13}
 14
 15// New creates an LRU of the given size.
 16func New(size int) (*Cache, error) {
 17	return NewWithEvict(size, nil)
 18}
 19
 20// NewWithEvict constructs a fixed size cache with the given eviction
 21// callback.
 22func NewWithEvict(size int, onEvicted func(key interface{}, value interface{})) (*Cache, error) {
 23	lru, err := simplelru.NewLRU(size, simplelru.EvictCallback(onEvicted))
 24	if err != nil {
 25		return nil, err
 26	}
 27	c := &Cache{
 28		lru: lru,
 29	}
 30	return c, nil
 31}
 32
 33// Purge is used to completely clear the cache.
 34func (c *Cache) Purge() {
 35	c.lock.Lock()
 36	c.lru.Purge()
 37	c.lock.Unlock()
 38}
 39
 40// Add adds a value to the cache.  Returns true if an eviction occurred.
 41func (c *Cache) Add(key, value interface{}) (evicted bool) {
 42	c.lock.Lock()
 43	defer c.lock.Unlock()
 44	return c.lru.Add(key, value)
 45}
 46
 47// Get looks up a key's value from the cache.
 48func (c *Cache) Get(key interface{}) (value interface{}, ok bool) {
 49	c.lock.Lock()
 50	defer c.lock.Unlock()
 51	return c.lru.Get(key)
 52}
 53
 54// Contains checks if a key is in the cache, without updating the
 55// recent-ness or deleting it for being stale.
 56func (c *Cache) Contains(key interface{}) bool {
 57	c.lock.RLock()
 58	defer c.lock.RUnlock()
 59	return c.lru.Contains(key)
 60}
 61
 62// Peek returns the key value (or undefined if not found) without updating
 63// the "recently used"-ness of the key.
 64func (c *Cache) Peek(key interface{}) (value interface{}, ok bool) {
 65	c.lock.RLock()
 66	defer c.lock.RUnlock()
 67	return c.lru.Peek(key)
 68}
 69
 70// ContainsOrAdd checks if a key is in the cache  without updating the
 71// recent-ness or deleting it for being stale,  and if not, adds the value.
 72// Returns whether found and whether an eviction occurred.
 73func (c *Cache) ContainsOrAdd(key, value interface{}) (ok, evicted bool) {
 74	c.lock.Lock()
 75	defer c.lock.Unlock()
 76
 77	if c.lru.Contains(key) {
 78		return true, false
 79	}
 80	evicted = c.lru.Add(key, value)
 81	return false, evicted
 82}
 83
 84// Remove removes the provided key from the cache.
 85func (c *Cache) Remove(key interface{}) {
 86	c.lock.Lock()
 87	c.lru.Remove(key)
 88	c.lock.Unlock()
 89}
 90
 91// RemoveOldest removes the oldest item from the cache.
 92func (c *Cache) RemoveOldest() {
 93	c.lock.Lock()
 94	c.lru.RemoveOldest()
 95	c.lock.Unlock()
 96}
 97
 98// Keys returns a slice of the keys in the cache, from oldest to newest.
 99func (c *Cache) Keys() []interface{} {
100	c.lock.RLock()
101	defer c.lock.RUnlock()
102	return c.lru.Keys()
103}
104
105// Len returns the number of items in the cache.
106func (c *Cache) Len() int {
107	c.lock.RLock()
108	defer c.lock.RUnlock()
109	return c.lru.Len()
110}