123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116 |
- package lru
- import (
- "sync"
- "github.com/hashicorp/golang-lru/simplelru"
- )
- // Cache is a thread-safe fixed size LRU cache.
- type Cache struct {
- lru simplelru.LRUCache
- lock sync.RWMutex
- }
- // New creates an LRU of the given size.
- func New(size int) (*Cache, error) {
- return NewWithEvict(size, nil)
- }
- // NewWithEvict constructs a fixed size cache with the given eviction
- // callback.
- func NewWithEvict(size int, onEvicted func(key interface{}, value interface{})) (*Cache, error) {
- lru, err := simplelru.NewLRU(size, simplelru.EvictCallback(onEvicted))
- if err != nil {
- return nil, err
- }
- c := &Cache{
- lru: lru,
- }
- return c, nil
- }
- // Purge is used to completely clear the cache.
- func (c *Cache) Purge() {
- c.lock.Lock()
- c.lru.Purge()
- c.lock.Unlock()
- }
- // Add adds a value to the cache. Returns true if an eviction occurred.
- func (c *Cache) Add(key, value interface{}) (evicted bool) {
- c.lock.Lock()
- evicted = c.lru.Add(key, value)
- c.lock.Unlock()
- return evicted
- }
- // Get looks up a key's value from the cache.
- func (c *Cache) Get(key interface{}) (value interface{}, ok bool) {
- c.lock.Lock()
- value, ok = c.lru.Get(key)
- c.lock.Unlock()
- return value, ok
- }
- // Contains checks if a key is in the cache, without updating the
- // recent-ness or deleting it for being stale.
- func (c *Cache) Contains(key interface{}) bool {
- c.lock.RLock()
- containKey := c.lru.Contains(key)
- c.lock.RUnlock()
- return containKey
- }
- // Peek returns the key value (or undefined if not found) without updating
- // the "recently used"-ness of the key.
- func (c *Cache) Peek(key interface{}) (value interface{}, ok bool) {
- c.lock.RLock()
- value, ok = c.lru.Peek(key)
- c.lock.RUnlock()
- return value, ok
- }
- // ContainsOrAdd checks if a key is in the cache without updating the
- // recent-ness or deleting it for being stale, and if not, adds the value.
- // Returns whether found and whether an eviction occurred.
- func (c *Cache) ContainsOrAdd(key, value interface{}) (ok, evicted bool) {
- c.lock.Lock()
- defer c.lock.Unlock()
- if c.lru.Contains(key) {
- return true, false
- }
- evicted = c.lru.Add(key, value)
- return false, evicted
- }
- // Remove removes the provided key from the cache.
- func (c *Cache) Remove(key interface{}) {
- c.lock.Lock()
- c.lru.Remove(key)
- c.lock.Unlock()
- }
- // RemoveOldest removes the oldest item from the cache.
- func (c *Cache) RemoveOldest() {
- c.lock.Lock()
- c.lru.RemoveOldest()
- c.lock.Unlock()
- }
- // Keys returns a slice of the keys in the cache, from oldest to newest.
- func (c *Cache) Keys() []interface{} {
- c.lock.RLock()
- keys := c.lru.Keys()
- c.lock.RUnlock()
- return keys
- }
- // Len returns the number of items in the cache.
- func (c *Cache) Len() int {
- c.lock.RLock()
- length := c.lru.Len()
- c.lock.RUnlock()
- return length
- }
|