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 }