github.com/searKing/golang/go@v1.2.74/exp/sync/lru.go (about)

     1  // Copyright 2022 The searKing Author. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package sync
     6  
     7  import (
     8  	"sync"
     9  
    10  	"github.com/searKing/golang/go/exp/container/lru"
    11  )
    12  
    13  // EvictCallback is used to get a callback when a cache entry is evicted
    14  type EvictCallback[K comparable, V any] func(key K, value V)
    15  
    16  // LRU implements a non-thread safe fixed size LRU cache
    17  type LRU[K comparable, V any] struct {
    18  	c  *lru.LRU[K, V]
    19  	mu sync.Mutex
    20  }
    21  
    22  // NewLRU constructs an LRU of the given size
    23  func NewLRU[K comparable, V any](size int) *LRU[K, V] {
    24  	return &LRU[K, V]{
    25  		c: lru.New[K, V](size),
    26  	}
    27  }
    28  
    29  // SetEvictCallback sets a callback when a cache entry is evicted
    30  func (c *LRU[K, V]) SetEvictCallback(onEvict EvictCallback[K, V]) *LRU[K, V] {
    31  	c.mu.Lock()
    32  	defer c.mu.Unlock()
    33  	if onEvict == nil {
    34  		c.c.SetEvictCallback(nil)
    35  	} else {
    36  		c.c.SetEvictCallbackFunc(func(key K, value V) {
    37  			onEvict(key, value)
    38  		})
    39  	}
    40  	return c
    41  }
    42  
    43  // SetEvictCallbackFunc sets a callback when a cache entry is evicted
    44  func (c *LRU[K, V]) SetEvictCallbackFunc(onEvict func(key K, value V)) *LRU[K, V] {
    45  	c.mu.Lock()
    46  	defer c.mu.Unlock()
    47  	c.c.SetEvictCallbackFunc(onEvict)
    48  	return c
    49  }
    50  
    51  // Init initializes or clears LRU l.
    52  func (c *LRU[K, V]) Init() *LRU[K, V] {
    53  	c.mu.Lock()
    54  	defer c.mu.Unlock()
    55  	c.c.Init()
    56  	return c
    57  }
    58  
    59  // Purge is used to completely clear the cache.
    60  func (c *LRU[K, V]) Purge() {
    61  	c.mu.Lock()
    62  	defer c.mu.Unlock()
    63  	c.c.Purge()
    64  }
    65  
    66  // Add adds a value to the cache.  Returns true if an eviction occurred.
    67  func (c *LRU[K, V]) Add(key K, value V) (evicted bool) {
    68  	c.mu.Lock()
    69  	defer c.mu.Unlock()
    70  	return c.c.Add(key, value)
    71  }
    72  
    73  // Get looks up a key's value from the cache.
    74  func (c *LRU[K, V]) Get(key K) (value V, ok bool) {
    75  	c.mu.Lock()
    76  	defer c.mu.Unlock()
    77  	return c.c.Get(key)
    78  }
    79  
    80  // Contains checks if a key is in the cache, without updating the recent-ness
    81  // or deleting it for being stale.
    82  func (c *LRU[K, V]) Contains(key K) (ok bool) {
    83  	c.mu.Lock()
    84  	defer c.mu.Unlock()
    85  	return c.c.Contains(key)
    86  }
    87  
    88  // Peek returns the key value (or undefined if not found) without updating
    89  // the "recently used"-ness of the key.
    90  func (c *LRU[K, V]) Peek(key K) (value V, ok bool) {
    91  	return c.c.Peek(key)
    92  }
    93  
    94  // Remove removes the provided key from the cache, returning if the
    95  // key was contained.
    96  func (c *LRU[K, V]) Remove(key K) (present bool) {
    97  	c.mu.Lock()
    98  	defer c.mu.Unlock()
    99  	return c.c.Remove(key)
   100  }
   101  
   102  // RemoveOldest removes the oldest item from the cache.
   103  func (c *LRU[K, V]) RemoveOldest() (key K, value V, ok bool) {
   104  	c.mu.Lock()
   105  	defer c.mu.Unlock()
   106  	return c.c.RemoveOldest()
   107  }
   108  
   109  // GetOldest returns the oldest entry
   110  func (c *LRU[K, V]) GetOldest() (key K, value V, ok bool) {
   111  	c.mu.Lock()
   112  	defer c.mu.Unlock()
   113  	return c.c.GetOldest()
   114  }
   115  
   116  // Keys returns a slice of the keys in the cache, from oldest to newest.
   117  func (c *LRU[K, V]) Keys() []K {
   118  	c.mu.Lock()
   119  	defer c.mu.Unlock()
   120  	return c.c.Keys()
   121  }
   122  
   123  // Len returns the number of items in the cache.
   124  func (c *LRU[K, V]) Len() int {
   125  	c.mu.Lock()
   126  	defer c.mu.Unlock()
   127  	return c.c.Len()
   128  }
   129  
   130  // Cap returns the capacity of the cache.
   131  func (c *LRU[K, V]) Cap() int {
   132  	c.mu.Lock()
   133  	defer c.mu.Unlock()
   134  	return c.c.Cap()
   135  }
   136  
   137  // Resize changes the cache size.
   138  func (c *LRU[K, V]) Resize(size int) (evicted int) {
   139  	c.mu.Lock()
   140  	defer c.mu.Unlock()
   141  	return c.c.Resize(size)
   142  }