diff options
Diffstat (limited to 'vendor/codeberg.org/gruf/go-cache/v2/ttl.go')
-rw-r--r-- | vendor/codeberg.org/gruf/go-cache/v2/ttl.go | 310 |
1 files changed, 0 insertions, 310 deletions
diff --git a/vendor/codeberg.org/gruf/go-cache/v2/ttl.go b/vendor/codeberg.org/gruf/go-cache/v2/ttl.go deleted file mode 100644 index a5b6637b2..000000000 --- a/vendor/codeberg.org/gruf/go-cache/v2/ttl.go +++ /dev/null @@ -1,310 +0,0 @@ -package cache - -import ( - "sync" - "time" -) - -// TTLCache is the underlying Cache implementation, providing both the base -// Cache interface and access to "unsafe" methods so that you may build your -// customized caches ontop of this structure. -type TTLCache[Key comparable, Value any] struct { - cache map[Key](*entry[Value]) - evict Hook[Key, Value] // the evict hook is called when an item is evicted from the cache, includes manual delete - invalid Hook[Key, Value] // the invalidate hook is called when an item's data in the cache is invalidated - ttl time.Duration // ttl is the item TTL - stop func() // stop is the cancel function for the scheduled eviction routine - mu sync.Mutex // mu protects TTLCache for concurrent access -} - -// Init performs Cache initialization. MUST be called. -func (c *TTLCache[K, V]) Init() { - c.cache = make(map[K](*entry[V]), 100) - c.evict = emptyHook[K, V] - c.invalid = emptyHook[K, V] - c.ttl = time.Minute * 5 -} - -func (c *TTLCache[K, V]) Start(freq time.Duration) (ok bool) { - // Nothing to start - if freq <= 0 { - return false - } - - // Safely start - c.mu.Lock() - - if ok = c.stop == nil; ok { - // Not yet running, schedule us - c.stop = schedule(c.sweep, freq) - } - - // Done with lock - c.mu.Unlock() - - return -} - -func (c *TTLCache[K, V]) Stop() (ok bool) { - // Safely stop - c.mu.Lock() - - if ok = c.stop != nil; ok { - // We're running, cancel evicts - c.stop() - c.stop = nil - } - - // Done with lock - c.mu.Unlock() - - return -} - -// sweep attempts to evict expired items (with callback!) from cache. -func (c *TTLCache[K, V]) sweep(now time.Time) { - // Lock and defer unlock (in case of hook panic) - c.mu.Lock() - defer c.mu.Unlock() - - // Sweep the cache for old items! - for key, item := range c.cache { - if now.After(item.expiry) { - c.evict(key, item.value) - delete(c.cache, key) - } - } -} - -// Lock locks the cache mutex. -func (c *TTLCache[K, V]) Lock() { - c.mu.Lock() -} - -// Unlock unlocks the cache mutex. -func (c *TTLCache[K, V]) Unlock() { - c.mu.Unlock() -} - -func (c *TTLCache[K, V]) SetEvictionCallback(hook Hook[K, V]) { - // Ensure non-nil hook - if hook == nil { - hook = emptyHook[K, V] - } - - // Safely set evict hook - c.mu.Lock() - c.evict = hook - c.mu.Unlock() -} - -func (c *TTLCache[K, V]) SetInvalidateCallback(hook Hook[K, V]) { - // Ensure non-nil hook - if hook == nil { - hook = emptyHook[K, V] - } - - // Safely set invalidate hook - c.mu.Lock() - c.invalid = hook - c.mu.Unlock() -} - -func (c *TTLCache[K, V]) SetTTL(ttl time.Duration, update bool) { - // Safely update TTL - c.mu.Lock() - diff := ttl - c.ttl - c.ttl = ttl - - if update { - // Update existing cache entries - for _, entry := range c.cache { - entry.expiry.Add(diff) - } - } - - // We're done - c.mu.Unlock() -} - -func (c *TTLCache[K, V]) Get(key K) (V, bool) { - c.mu.Lock() - value, ok := c.GetUnsafe(key) - c.mu.Unlock() - return value, ok -} - -// GetUnsafe is the mutex-unprotected logic for Cache.Get(). -func (c *TTLCache[K, V]) GetUnsafe(key K) (V, bool) { - item, ok := c.cache[key] - if !ok { - var value V - return value, false - } - item.expiry = time.Now().Add(c.ttl) - return item.value, true -} - -func (c *TTLCache[K, V]) Put(key K, value V) bool { - c.mu.Lock() - success := c.PutUnsafe(key, value) - c.mu.Unlock() - return success -} - -// PutUnsafe is the mutex-unprotected logic for Cache.Put(). -func (c *TTLCache[K, V]) PutUnsafe(key K, value V) bool { - // If already cached, return - if _, ok := c.cache[key]; ok { - return false - } - - // Create new cached item - c.cache[key] = &entry[V]{ - value: value, - expiry: time.Now().Add(c.ttl), - } - - return true -} - -func (c *TTLCache[K, V]) Set(key K, value V) { - c.mu.Lock() - defer c.mu.Unlock() // defer in case of hook panic - c.SetUnsafe(key, value) -} - -// SetUnsafe is the mutex-unprotected logic for Cache.Set(), it calls externally-set functions. -func (c *TTLCache[K, V]) SetUnsafe(key K, value V) { - item, ok := c.cache[key] - if ok { - // call invalidate hook - c.invalid(key, item.value) - } else { - // alloc new item - item = &entry[V]{} - c.cache[key] = item - } - - // Update the item + expiry - item.value = value - item.expiry = time.Now().Add(c.ttl) -} - -func (c *TTLCache[K, V]) CAS(key K, cmp V, swp V) bool { - c.mu.Lock() - ok := c.CASUnsafe(key, cmp, swp) - c.mu.Unlock() - return ok -} - -// CASUnsafe is the mutex-unprotected logic for Cache.CAS(). -func (c *TTLCache[K, V]) CASUnsafe(key K, cmp V, swp V) bool { - // Check for item - item, ok := c.cache[key] - if !ok || !Compare(item.value, cmp) { - return false - } - - // Invalidate item - c.invalid(key, item.value) - - // Update item + expiry - item.value = swp - item.expiry = time.Now().Add(c.ttl) - - return ok -} - -func (c *TTLCache[K, V]) Swap(key K, swp V) V { - c.mu.Lock() - old := c.SwapUnsafe(key, swp) - c.mu.Unlock() - return old -} - -// SwapUnsafe is the mutex-unprotected logic for Cache.Swap(). -func (c *TTLCache[K, V]) SwapUnsafe(key K, swp V) V { - // Check for item - item, ok := c.cache[key] - if !ok { - var value V - return value - } - - // invalidate old item - c.invalid(key, item.value) - old := item.value - - // update item + expiry - item.value = swp - item.expiry = time.Now().Add(c.ttl) - - return old -} - -func (c *TTLCache[K, V]) Has(key K) bool { - c.mu.Lock() - ok := c.HasUnsafe(key) - c.mu.Unlock() - return ok -} - -// HasUnsafe is the mutex-unprotected logic for Cache.Has(). -func (c *TTLCache[K, V]) HasUnsafe(key K) bool { - _, ok := c.cache[key] - return ok -} - -func (c *TTLCache[K, V]) Invalidate(key K) bool { - c.mu.Lock() - defer c.mu.Unlock() - return c.InvalidateUnsafe(key) -} - -// InvalidateUnsafe is mutex-unprotected logic for Cache.Invalidate(). -func (c *TTLCache[K, V]) InvalidateUnsafe(key K) bool { - // Check if we have item with key - item, ok := c.cache[key] - if !ok { - return false - } - - // Call hook, remove from cache - c.invalid(key, item.value) - delete(c.cache, key) - return true -} - -func (c *TTLCache[K, V]) Clear() { - c.mu.Lock() - defer c.mu.Unlock() - c.ClearUnsafe() -} - -// ClearUnsafe is mutex-unprotected logic for Cache.Clean(). -func (c *TTLCache[K, V]) ClearUnsafe() { - for key, item := range c.cache { - c.invalid(key, item.value) - delete(c.cache, key) - } -} - -func (c *TTLCache[K, V]) Size() int { - c.mu.Lock() - sz := c.SizeUnsafe() - c.mu.Unlock() - return sz -} - -// SizeUnsafe is mutex unprotected logic for Cache.Size(). -func (c *TTLCache[K, V]) SizeUnsafe() int { - return len(c.cache) -} - -// entry represents an item in the cache, with -// it's currently calculated expiry time. -type entry[Value any] struct { - value Value - expiry time.Time -} |