github.com/nutsdb/nutsdb@v1.0.4/lru.go (about)

     1  package nutsdb
     2  
     3  import (
     4  	"container/list"
     5  	"sync"
     6  )
     7  
     8  // LRUCache is a least recently used (LRU) cache.
     9  type LRUCache struct {
    10  	m   map[interface{}]*list.Element
    11  	l   *list.List
    12  	cap int
    13  	mu  *sync.RWMutex
    14  }
    15  
    16  // New creates a new LRUCache with the specified capacity.
    17  func NewLruCache(cap int) *LRUCache {
    18  	return &LRUCache{
    19  		m:   make(map[interface{}]*list.Element),
    20  		l:   list.New(),
    21  		cap: cap,
    22  		mu:  &sync.RWMutex{},
    23  	}
    24  }
    25  
    26  // Add adds a new entry to the cache.
    27  func (c *LRUCache) Add(key interface{}, value interface{}) {
    28  	c.mu.Lock()
    29  	defer c.mu.Unlock()
    30  
    31  	if c.cap <= 0 {
    32  		return
    33  	}
    34  
    35  	if c.l.Len() >= c.cap {
    36  		c.removeOldest()
    37  	}
    38  
    39  	e := &LruEntry{
    40  		Key:   key,
    41  		Value: value,
    42  	}
    43  	entry := c.l.PushFront(e)
    44  
    45  	c.m[key] = entry
    46  }
    47  
    48  // Get returns the entry associated with the given key, or nil if the key is not in the cache.
    49  func (c *LRUCache) Get(key interface{}) interface{} {
    50  	c.mu.Lock()
    51  	defer c.mu.Unlock()
    52  
    53  	entry, ok := c.m[key]
    54  	if !ok {
    55  		return nil
    56  	}
    57  
    58  	c.l.MoveToFront(entry)
    59  	return entry.Value.(*LruEntry).Value
    60  }
    61  
    62  // Remove removes the entry associated with the given key from the cache.
    63  func (c *LRUCache) Remove(key interface{}) {
    64  	c.mu.Lock()
    65  	defer c.mu.Unlock()
    66  
    67  	entry, ok := c.m[key]
    68  	if !ok {
    69  		return
    70  	}
    71  
    72  	c.l.Remove(entry)
    73  	delete(c.m, key)
    74  }
    75  
    76  // Len returns the number of entries in the cache.
    77  func (c *LRUCache) Len() int {
    78  	c.mu.RLock()
    79  	defer c.mu.RUnlock()
    80  
    81  	return c.l.Len()
    82  }
    83  
    84  // Clear clears the cache.
    85  func (c *LRUCache) Clear() {
    86  	c.mu.Lock()
    87  	defer c.mu.Unlock()
    88  
    89  	c.l.Init()
    90  	c.m = make(map[interface{}]*list.Element)
    91  }
    92  
    93  // removeOldest removes the oldest entry from the cache.
    94  func (c *LRUCache) removeOldest() {
    95  	entry := c.l.Back()
    96  	if entry == nil {
    97  		return
    98  	}
    99  
   100  	key := entry.Value.(*LruEntry).Key
   101  	delete(c.m, key)
   102  
   103  	c.l.Remove(entry)
   104  }
   105  
   106  // LruEntry is a struct that represents an entry in the LRU cache.
   107  type LruEntry struct {
   108  	Key   interface{}
   109  	Value interface{}
   110  }