diff options
Diffstat (limited to 'vendor/codeberg.org/gruf/go-cache/v3/simple/cache.go')
-rw-r--r-- | vendor/codeberg.org/gruf/go-cache/v3/simple/cache.go | 454 |
1 files changed, 0 insertions, 454 deletions
diff --git a/vendor/codeberg.org/gruf/go-cache/v3/simple/cache.go b/vendor/codeberg.org/gruf/go-cache/v3/simple/cache.go deleted file mode 100644 index 1452a0648..000000000 --- a/vendor/codeberg.org/gruf/go-cache/v3/simple/cache.go +++ /dev/null @@ -1,454 +0,0 @@ -package simple - -import ( - "sync" - - "codeberg.org/gruf/go-maps" -) - -// Entry represents an item in the cache. -type Entry struct { - Key any - Value any -} - -// Cache is the underlying Cache implementation, providing both the base Cache interface and unsafe access to underlying map to allow flexibility in building your own. -type Cache[Key comparable, Value any] struct { - // Evict is the hook that is called when an item is evicted from the cache. - Evict func(Key, Value) - - // Invalid is the hook that is called when an item's data in the cache is invalidated, includes Add/Set. - Invalid func(Key, Value) - - // Cache is the underlying hashmap used for this cache. - Cache maps.LRUMap[Key, *Entry] - - // Embedded mutex. - sync.Mutex -} - -// New returns a new initialized Cache with given initial length, maximum capacity and item TTL. -func New[K comparable, V any](len, cap int) *Cache[K, V] { - c := new(Cache[K, V]) - c.Init(len, cap) - return c -} - -// Init will initialize this cache with given initial length, maximum capacity and item TTL. -func (c *Cache[K, V]) Init(len, cap int) { - c.SetEvictionCallback(nil) - c.SetInvalidateCallback(nil) - c.Cache.Init(len, cap) -} - -// SetEvictionCallback: implements cache.Cache's SetEvictionCallback(). -func (c *Cache[K, V]) SetEvictionCallback(hook func(K, V)) { - c.locked(func() { c.Evict = hook }) -} - -// SetInvalidateCallback: implements cache.Cache's SetInvalidateCallback(). -func (c *Cache[K, V]) SetInvalidateCallback(hook func(K, V)) { - c.locked(func() { c.Invalid = hook }) -} - -// Get: implements cache.Cache's Get(). -func (c *Cache[K, V]) Get(key K) (V, bool) { - var ( - // did exist in cache? - ok bool - - // cached value. - v V - ) - - c.locked(func() { - var item *Entry - - // Check for item in cache - item, ok = c.Cache.Get(key) - if !ok { - return - } - - // Set item value. - v = item.Value.(V) - }) - - return v, ok -} - -// Add: implements cache.Cache's Add(). -func (c *Cache[K, V]) Add(key K, value V) bool { - var ( - // did exist in cache? - ok bool - - // was entry evicted? - ev bool - - // evicted key values. - evcK K - evcV V - - // hook func ptrs. - evict func(K, V) - ) - - c.locked(func() { - // Check if in cache. - ok = c.Cache.Has(key) - if ok { - return - } - - // Alloc new entry. - new := GetEntry() - new.Key = key - new.Value = value - - // Add new entry to cache and catched any evicted item. - c.Cache.SetWithHook(key, new, func(_ K, item *Entry) { - evcK = item.Key.(K) - evcV = item.Value.(V) - ev = true - PutEntry(item) - }) - - // Set hook func ptr. - evict = c.Evict - }) - - if ev && evict != nil { - // Pass to eviction hook. - evict(evcK, evcV) - } - - return !ok -} - -// Set: implements cache.Cache's Set(). -func (c *Cache[K, V]) Set(key K, value V) { - var ( - // did exist in cache? - ok bool - - // was entry evicted? - ev bool - - // old value. - oldV V - - // evicted key values. - evcK K - evcV V - - // hook func ptrs. - invalid func(K, V) - evict func(K, V) - ) - - c.locked(func() { - var item *Entry - - // Check for item in cache - item, ok = c.Cache.Get(key) - - if ok { - // Set old value. - oldV = item.Value.(V) - - // Update the existing item. - item.Value = value - } else { - // Alloc new entry. - new := GetEntry() - new.Key = key - new.Value = value - - // Add new entry to cache and catched any evicted item. - c.Cache.SetWithHook(key, new, func(_ K, item *Entry) { - evcK = item.Key.(K) - evcV = item.Value.(V) - ev = true - PutEntry(item) - }) - } - - // Set hook func ptrs. - invalid = c.Invalid - evict = c.Evict - }) - - if ok && invalid != nil { - // Pass to invalidate hook. - invalid(key, oldV) - } - - if ev && evict != nil { - // Pass to eviction hook. - evict(evcK, evcV) - } -} - -// CAS: implements cache.Cache's CAS(). -func (c *Cache[K, V]) CAS(key K, old V, new V, cmp func(V, V) bool) bool { - var ( - // did exist in cache? - ok bool - - // swapped value. - oldV V - - // hook func ptrs. - invalid func(K, V) - ) - - c.locked(func() { - var item *Entry - - // Check for item in cache - item, ok = c.Cache.Get(key) - if !ok { - return - } - - // Set old value. - oldV = item.Value.(V) - - // Perform the comparison - if !cmp(old, oldV) { - var zero V - oldV = zero - return - } - - // Update value. - item.Value = new - - // Set hook func ptr. - invalid = c.Invalid - }) - - if ok && invalid != nil { - // Pass to invalidate hook. - invalid(key, oldV) - } - - return ok -} - -// Swap: implements cache.Cache's Swap(). -func (c *Cache[K, V]) Swap(key K, swp V) V { - var ( - // did exist in cache? - ok bool - - // swapped value. - oldV V - - // hook func ptrs. - invalid func(K, V) - ) - - c.locked(func() { - var item *Entry - - // Check for item in cache - item, ok = c.Cache.Get(key) - if !ok { - return - } - - // Set old value. - oldV = item.Value.(V) - - // Update value. - item.Value = swp - - // Set hook func ptr. - invalid = c.Invalid - }) - - if ok && invalid != nil { - // Pass to invalidate hook. - invalid(key, oldV) - } - - return oldV -} - -// Has: implements cache.Cache's Has(). -func (c *Cache[K, V]) Has(key K) (ok bool) { - c.locked(func() { - ok = c.Cache.Has(key) - }) - return -} - -// Invalidate: implements cache.Cache's Invalidate(). -func (c *Cache[K, V]) Invalidate(key K) (ok bool) { - var ( - // old value. - oldV V - - // hook func ptrs. - invalid func(K, V) - ) - - c.locked(func() { - var item *Entry - - // Check for item in cache - item, ok = c.Cache.Get(key) - if !ok { - return - } - - // Set old value. - oldV = item.Value.(V) - - // Remove from cache map - _ = c.Cache.Delete(key) - - // Free entry - PutEntry(item) - - // Set hook func ptrs. - invalid = c.Invalid - }) - - if ok && invalid != nil { - // Pass to invalidate hook. - invalid(key, oldV) - } - - return -} - -// InvalidateAll: implements cache.Cache's InvalidateAll(). -func (c *Cache[K, V]) InvalidateAll(keys ...K) (ok bool) { - var ( - // deleted items. - items []*Entry - - // hook func ptrs. - invalid func(K, V) - ) - - // Allocate a slice for invalidated. - items = make([]*Entry, 0, len(keys)) - - c.locked(func() { - for x := range keys { - var item *Entry - - // Check for item in cache - item, ok = c.Cache.Get(keys[x]) - if !ok { - continue - } - - // Append this old value. - items = append(items, item) - - // Remove from cache map - _ = c.Cache.Delete(keys[x]) - } - - // Set hook func ptrs. - invalid = c.Invalid - }) - - if invalid != nil { - for x := range items { - // Pass to invalidate hook. - k := items[x].Key.(K) - v := items[x].Value.(V) - invalid(k, v) - - // Free this entry. - PutEntry(items[x]) - } - } - - return -} - -// Clear: implements cache.Cache's Clear(). -func (c *Cache[K, V]) Clear() { c.Trim(100) } - -// Trim will truncate the cache to ensure it stays within given percentage of total capacity. -func (c *Cache[K, V]) Trim(perc float64) { - var ( - // deleted items - items []*Entry - - // hook func ptrs. - invalid func(K, V) - ) - - c.locked(func() { - // Calculate number of cache items to truncate. - max := (perc / 100) * float64(c.Cache.Cap()) - diff := c.Cache.Len() - int(max) - if diff <= 0 { - return - } - - // Set hook func ptr. - invalid = c.Invalid - - // Truncate by calculated length. - items = c.truncate(diff, invalid) - }) - - if invalid != nil { - for x := range items { - // Pass to invalidate hook. - k := items[x].Key.(K) - v := items[x].Value.(V) - invalid(k, v) - - // Free this entry. - PutEntry(items[x]) - } - } -} - -// Len: implements cache.Cache's Len(). -func (c *Cache[K, V]) Len() (l int) { - c.locked(func() { l = c.Cache.Len() }) - return -} - -// Cap: implements cache.Cache's Cap(). -func (c *Cache[K, V]) Cap() (l int) { - c.locked(func() { l = c.Cache.Cap() }) - return -} - -// locked performs given function within mutex lock (NOTE: UNLOCK IS NOT DEFERRED). -func (c *Cache[K, V]) locked(fn func()) { - c.Lock() - fn() - c.Unlock() -} - -// truncate will truncate the cache by given size, returning deleted items. -func (c *Cache[K, V]) truncate(sz int, hook func(K, V)) []*Entry { - if hook == nil { - // No hook to execute, simply release all truncated entries. - c.Cache.Truncate(sz, func(_ K, item *Entry) { PutEntry(item) }) - return nil - } - - // Allocate a slice for deleted. - deleted := make([]*Entry, 0, sz) - - // Truncate and catch all deleted k-v pairs. - c.Cache.Truncate(sz, func(_ K, item *Entry) { - deleted = append(deleted, item) - }) - - return deleted -} |