summaryrefslogtreecommitdiff
path: root/vendor/codeberg.org/gruf/go-cache
diff options
context:
space:
mode:
authorLibravatar kim <89579420+NyaaaWhatsUpDoc@users.noreply.github.com>2022-11-15 18:45:15 +0000
committerLibravatar GitHub <noreply@github.com>2022-11-15 18:45:15 +0000
commit8598dea98b872647393117704659878d9b38d4fc (patch)
tree1940168912dc7f54af723439dbc9f6e0a42f30ae /vendor/codeberg.org/gruf/go-cache
parent[docs] Both HTTP proxies and NAT can cause rate limiting issues (#1053) (diff)
downloadgotosocial-8598dea98b872647393117704659878d9b38d4fc.tar.xz
[chore] update database caching library (#1040)
* convert most of the caches to use result.Cache{} * add caching of emojis * fix issues causing failing tests * update go-cache/v2 instances with v3 * fix getnotification * add a note about the left-in StatusCreate comment * update EmojiCategory db access to use new result.Cache{} * fix possible panic in getstatusparents * further proof that kim is not stinky
Diffstat (limited to 'vendor/codeberg.org/gruf/go-cache')
-rw-r--r--vendor/codeberg.org/gruf/go-cache/v2/LICENSE9
-rw-r--r--vendor/codeberg.org/gruf/go-cache/v2/README.md3
-rw-r--r--vendor/codeberg.org/gruf/go-cache/v2/cache.go67
-rw-r--r--vendor/codeberg.org/gruf/go-cache/v2/compare.go23
-rw-r--r--vendor/codeberg.org/gruf/go-cache/v2/hook.go6
-rw-r--r--vendor/codeberg.org/gruf/go-cache/v2/lookup.go210
-rw-r--r--vendor/codeberg.org/gruf/go-cache/v2/scheduler.go20
-rw-r--r--vendor/codeberg.org/gruf/go-cache/v2/ttl.go310
-rw-r--r--vendor/codeberg.org/gruf/go-cache/v3/README.md17
-rw-r--r--vendor/codeberg.org/gruf/go-cache/v3/cache.go60
10 files changed, 77 insertions, 648 deletions
diff --git a/vendor/codeberg.org/gruf/go-cache/v2/LICENSE b/vendor/codeberg.org/gruf/go-cache/v2/LICENSE
deleted file mode 100644
index b7c4417ac..000000000
--- a/vendor/codeberg.org/gruf/go-cache/v2/LICENSE
+++ /dev/null
@@ -1,9 +0,0 @@
-MIT License
-
-Copyright (c) 2021 gruf
-
-Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/vendor/codeberg.org/gruf/go-cache/v2/README.md b/vendor/codeberg.org/gruf/go-cache/v2/README.md
deleted file mode 100644
index 69eee7039..000000000
--- a/vendor/codeberg.org/gruf/go-cache/v2/README.md
+++ /dev/null
@@ -1,3 +0,0 @@
-# go-cache
-
-A TTL cache designed to be used as a base for your own customizations, or used straight out of the box \ No newline at end of file
diff --git a/vendor/codeberg.org/gruf/go-cache/v2/cache.go b/vendor/codeberg.org/gruf/go-cache/v2/cache.go
deleted file mode 100644
index b0d697687..000000000
--- a/vendor/codeberg.org/gruf/go-cache/v2/cache.go
+++ /dev/null
@@ -1,67 +0,0 @@
-package cache
-
-import "time"
-
-// Cache represents a TTL cache with customizable callbacks, it
-// exists here to abstract away the "unsafe" methods in the case that
-// you do not want your own implementation atop TTLCache{}.
-type Cache[Key comparable, Value any] interface {
- // Start will start the cache background eviction routine with given sweep frequency.
- // If already running or a freq <= 0 provided, this is a no-op. This will block until
- // the eviction routine has started
- Start(freq time.Duration) bool
-
- // Stop will stop cache background eviction routine. If not running this is a no-op. This
- // will block until the eviction routine has stopped
- Stop() bool
-
- // SetEvictionCallback sets the eviction callback to the provided hook
- SetEvictionCallback(hook Hook[Key, Value])
-
- // SetInvalidateCallback sets the invalidate callback to the provided hook
- SetInvalidateCallback(hook Hook[Key, Value])
-
- // SetTTL sets the cache item TTL. Update can be specified to force updates of existing items in
- // the cache, this will simply add the change in TTL to their current expiry time
- SetTTL(ttl time.Duration, update bool)
-
- // Get fetches the value with key from the cache, extending its TTL
- Get(key Key) (value Value, ok bool)
-
- // Put attempts to place the value at key in the cache, doing nothing if
- // a value with this key already exists. Returned bool is success state
- Put(key Key, value Value) bool
-
- // Set places the value at key in the cache. This will overwrite any
- // existing value, and call the update callback so. Existing values
- // will have their TTL extended upon update
- Set(key Key, value Value)
-
- // CAS will attempt to perform a CAS operation on 'key', using provided
- // comparison and swap values. Returned bool is success.
- CAS(key Key, cmp, swp Value) bool
-
- // Swap will attempt to perform a swap on 'key', replacing the value there
- // and returning the existing value. If no value exists for key, this will
- // set the value and return the zero value for V.
- Swap(key Key, swp Value) Value
-
- // Has checks the cache for a value with key, this will not update TTL
- Has(key Key) bool
-
- // Invalidate deletes a value from the cache, calling the invalidate callback
- Invalidate(key Key) bool
-
- // Clear empties the cache, calling the invalidate callback
- Clear()
-
- // Size returns the current size of the cache
- Size() int
-}
-
-// New returns a new initialized Cache.
-func New[K comparable, V any]() Cache[K, V] {
- c := &TTLCache[K, V]{}
- c.Init()
- return c
-}
diff --git a/vendor/codeberg.org/gruf/go-cache/v2/compare.go b/vendor/codeberg.org/gruf/go-cache/v2/compare.go
deleted file mode 100644
index 749d6c05f..000000000
--- a/vendor/codeberg.org/gruf/go-cache/v2/compare.go
+++ /dev/null
@@ -1,23 +0,0 @@
-package cache
-
-import (
- "reflect"
-)
-
-type Comparable interface {
- Equal(any) bool
-}
-
-// Compare returns whether 2 values are equal using the Comparable
-// interface, or failing that falls back to use reflect.DeepEqual().
-func Compare(i1, i2 any) bool {
- c1, ok1 := i1.(Comparable)
- if ok1 {
- return c1.Equal(i2)
- }
- c2, ok2 := i2.(Comparable)
- if ok2 {
- return c2.Equal(i1)
- }
- return reflect.DeepEqual(i1, i2)
-}
diff --git a/vendor/codeberg.org/gruf/go-cache/v2/hook.go b/vendor/codeberg.org/gruf/go-cache/v2/hook.go
deleted file mode 100644
index 45ef8c92e..000000000
--- a/vendor/codeberg.org/gruf/go-cache/v2/hook.go
+++ /dev/null
@@ -1,6 +0,0 @@
-package cache
-
-// Hook defines a function hook that can be supplied as a callback.
-type Hook[Key comparable, Value any] func(key Key, value Value)
-
-func emptyHook[K comparable, V any](K, V) {}
diff --git a/vendor/codeberg.org/gruf/go-cache/v2/lookup.go b/vendor/codeberg.org/gruf/go-cache/v2/lookup.go
deleted file mode 100644
index d353b2959..000000000
--- a/vendor/codeberg.org/gruf/go-cache/v2/lookup.go
+++ /dev/null
@@ -1,210 +0,0 @@
-package cache
-
-// LookupCfg is the LookupCache configuration.
-type LookupCfg[OGKey, AltKey comparable, Value any] struct {
- // RegisterLookups is called on init to register lookups
- // within LookupCache's internal LookupMap
- RegisterLookups func(*LookupMap[OGKey, AltKey])
-
- // AddLookups is called on each addition to the cache, to
- // set any required additional key lookups for supplied item
- AddLookups func(*LookupMap[OGKey, AltKey], Value)
-
- // DeleteLookups is called on each eviction/invalidation of
- // an item in the cache, to remove any unused key lookups
- DeleteLookups func(*LookupMap[OGKey, AltKey], Value)
-}
-
-// LookupCache is a cache built on-top of TTLCache, providing multi-key
-// lookups for items in the cache by means of additional lookup maps. These
-// maps simply store additional keys => original key, with hook-ins to automatically
-// call user supplied functions on adding an item, or on updating/deleting an
-// item to keep the LookupMap up-to-date.
-type LookupCache[OGKey, AltKey comparable, Value any] interface {
- Cache[OGKey, Value]
-
- // GetBy fetches a cached value by supplied lookup identifier and key
- GetBy(lookup string, key AltKey) (value Value, ok bool)
-
- // CASBy will attempt to perform a CAS operation on supplied lookup identifier and key
- CASBy(lookup string, key AltKey, cmp, swp Value) bool
-
- // SwapBy will attempt to perform a swap operation on supplied lookup identifier and key
- SwapBy(lookup string, key AltKey, swp Value) Value
-
- // HasBy checks if a value is cached under supplied lookup identifier and key
- HasBy(lookup string, key AltKey) bool
-
- // InvalidateBy invalidates a value by supplied lookup identifier and key
- InvalidateBy(lookup string, key AltKey) bool
-}
-
-type lookupTTLCache[OK, AK comparable, V any] struct {
- TTLCache[OK, V]
- config LookupCfg[OK, AK, V]
- lookup LookupMap[OK, AK]
-}
-
-// NewLookup returns a new initialized LookupCache.
-func NewLookup[OK, AK comparable, V any](cfg LookupCfg[OK, AK, V]) LookupCache[OK, AK, V] {
- switch {
- case cfg.RegisterLookups == nil:
- panic("cache: nil lookups register function")
- case cfg.AddLookups == nil:
- panic("cache: nil lookups add function")
- case cfg.DeleteLookups == nil:
- panic("cache: nil delete lookups function")
- }
- c := &lookupTTLCache[OK, AK, V]{config: cfg}
- c.TTLCache.Init()
- c.lookup.lookup = make(map[string]map[AK]OK)
- c.config.RegisterLookups(&c.lookup)
- c.SetEvictionCallback(nil)
- c.SetInvalidateCallback(nil)
- return c
-}
-
-func (c *lookupTTLCache[OK, AK, V]) SetEvictionCallback(hook Hook[OK, V]) {
- if hook == nil {
- hook = emptyHook[OK, V]
- }
- c.TTLCache.SetEvictionCallback(func(key OK, value V) {
- hook(key, value)
- c.config.DeleteLookups(&c.lookup, value)
- })
-}
-
-func (c *lookupTTLCache[OK, AK, V]) SetInvalidateCallback(hook Hook[OK, V]) {
- if hook == nil {
- hook = emptyHook[OK, V]
- }
- c.TTLCache.SetInvalidateCallback(func(key OK, value V) {
- hook(key, value)
- c.config.DeleteLookups(&c.lookup, value)
- })
-}
-
-func (c *lookupTTLCache[OK, AK, V]) GetBy(lookup string, key AK) (V, bool) {
- c.Lock()
- origKey, ok := c.lookup.Get(lookup, key)
- if !ok {
- c.Unlock()
- var value V
- return value, false
- }
- v, ok := c.GetUnsafe(origKey)
- c.Unlock()
- return v, ok
-}
-
-func (c *lookupTTLCache[OK, AK, V]) Put(key OK, value V) bool {
- c.Lock()
- put := c.PutUnsafe(key, value)
- if put {
- c.config.AddLookups(&c.lookup, value)
- }
- c.Unlock()
- return put
-}
-
-func (c *lookupTTLCache[OK, AK, V]) Set(key OK, value V) {
- c.Lock()
- defer c.Unlock()
- c.SetUnsafe(key, value)
- c.config.AddLookups(&c.lookup, value)
-}
-
-func (c *lookupTTLCache[OK, AK, V]) CASBy(lookup string, key AK, cmp, swp V) bool {
- c.Lock()
- defer c.Unlock()
- origKey, ok := c.lookup.Get(lookup, key)
- if !ok {
- return false
- }
- return c.CASUnsafe(origKey, cmp, swp)
-}
-
-func (c *lookupTTLCache[OK, AK, V]) SwapBy(lookup string, key AK, swp V) V {
- c.Lock()
- defer c.Unlock()
- origKey, ok := c.lookup.Get(lookup, key)
- if !ok {
- var value V
- return value
- }
- return c.SwapUnsafe(origKey, swp)
-}
-
-func (c *lookupTTLCache[OK, AK, V]) HasBy(lookup string, key AK) bool {
- c.Lock()
- has := c.lookup.Has(lookup, key)
- c.Unlock()
- return has
-}
-
-func (c *lookupTTLCache[OK, AK, V]) InvalidateBy(lookup string, key AK) bool {
- c.Lock()
- defer c.Unlock()
- origKey, ok := c.lookup.Get(lookup, key)
- if !ok {
- return false
- }
- c.InvalidateUnsafe(origKey)
- return true
-}
-
-// LookupMap is a structure that provides lookups for
-// keys to primary keys under supplied lookup identifiers.
-// This is essentially a wrapper around map[string](map[K1]K2).
-type LookupMap[OK comparable, AK comparable] struct {
- lookup map[string](map[AK]OK)
-}
-
-// RegisterLookup registers a lookup identifier in the LookupMap,
-// note this can only be doing during the cfg.RegisterLookups() hook.
-func (l *LookupMap[OK, AK]) RegisterLookup(id string) {
- if _, ok := l.lookup[id]; ok {
- panic("cache: lookup mapping already exists for identifier")
- }
- l.lookup[id] = make(map[AK]OK, 100)
-}
-
-// Get fetches an entry's primary key for lookup identifier and key.
-func (l *LookupMap[OK, AK]) Get(id string, key AK) (OK, bool) {
- keys, ok := l.lookup[id]
- if !ok {
- var key OK
- return key, false
- }
- origKey, ok := keys[key]
- return origKey, ok
-}
-
-// Set adds a lookup to the LookupMap under supplied lookup identifier,
-// linking supplied key to the supplied primary (original) key.
-func (l *LookupMap[OK, AK]) Set(id string, key AK, origKey OK) {
- keys, ok := l.lookup[id]
- if !ok {
- panic("cache: invalid lookup identifier")
- }
- keys[key] = origKey
-}
-
-// Has checks if there exists a lookup for supplied identifier and key.
-func (l *LookupMap[OK, AK]) Has(id string, key AK) bool {
- keys, ok := l.lookup[id]
- if !ok {
- return false
- }
- _, ok = keys[key]
- return ok
-}
-
-// Delete removes a lookup from LookupMap with supplied identifier and key.
-func (l *LookupMap[OK, AK]) Delete(id string, key AK) {
- keys, ok := l.lookup[id]
- if !ok {
- return
- }
- delete(keys, key)
-}
diff --git a/vendor/codeberg.org/gruf/go-cache/v2/scheduler.go b/vendor/codeberg.org/gruf/go-cache/v2/scheduler.go
deleted file mode 100644
index ca93a0fcd..000000000
--- a/vendor/codeberg.org/gruf/go-cache/v2/scheduler.go
+++ /dev/null
@@ -1,20 +0,0 @@
-package cache
-
-import (
- "time"
-
- "codeberg.org/gruf/go-sched"
-)
-
-// scheduler is the global cache runtime scheduler
-// for handling regular cache evictions.
-var scheduler sched.Scheduler
-
-// schedule will given sweep routine to the global scheduler, and start global scheduler.
-func schedule(sweep func(time.Time), freq time.Duration) func() {
- if !scheduler.Running() {
- // ensure running
- _ = scheduler.Start()
- }
- return scheduler.Schedule(sched.NewJob(sweep).Every(freq))
-}
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
-}
diff --git a/vendor/codeberg.org/gruf/go-cache/v3/README.md b/vendor/codeberg.org/gruf/go-cache/v3/README.md
new file mode 100644
index 000000000..43004f3d8
--- /dev/null
+++ b/vendor/codeberg.org/gruf/go-cache/v3/README.md
@@ -0,0 +1,17 @@
+# go-cache
+
+Provides access to a simple yet flexible, performant TTL cache via the `Cache{}` interface and `cache.New()`. Under the hood this is returning a `ttl.Cache{}`.
+
+## ttl
+
+A TTL cache implementation with much of the inner workings exposed, designed to be used as a base for your own customizations, or used as-is. Access via the base package `cache.New()` is recommended in the latter case, to prevent accidental use of unsafe methods.
+
+## lookup
+
+`lookup.Cache` is an example of a more complex cache implementation using `ttl.Cache{}` as its underpinning. It provides caching of items under multiple keys.
+
+## result
+
+`result.Cache` is an example of a more complex cache implementation using `ttl.Cache{}` as its underpinning.
+
+It provides caching specifically of loadable struct types, with automatic keying by multiple different field members and caching of negative (error) values. All useful when wrapping, for example, a database. \ No newline at end of file
diff --git a/vendor/codeberg.org/gruf/go-cache/v3/cache.go b/vendor/codeberg.org/gruf/go-cache/v3/cache.go
new file mode 100644
index 000000000..dc1df46b1
--- /dev/null
+++ b/vendor/codeberg.org/gruf/go-cache/v3/cache.go
@@ -0,0 +1,60 @@
+package cache
+
+import (
+ "time"
+
+ ttlcache "codeberg.org/gruf/go-cache/v3/ttl"
+)
+
+// Cache represents a TTL cache with customizable callbacks, it exists here to abstract away the "unsafe" methods in the case that you do not want your own implementation atop ttl.Cache{}.
+type Cache[Key comparable, Value any] interface {
+ // Start will start the cache background eviction routine with given sweep frequency. If already running or a freq <= 0 provided, this is a no-op. This will block until the eviction routine has started.
+ Start(freq time.Duration) bool
+
+ // Stop will stop cache background eviction routine. If not running this is a no-op. This will block until the eviction routine has stopped.
+ Stop() bool
+
+ // SetEvictionCallback sets the eviction callback to the provided hook.
+ SetEvictionCallback(hook func(*ttlcache.Entry[Key, Value]))
+
+ // SetInvalidateCallback sets the invalidate callback to the provided hook.
+ SetInvalidateCallback(hook func(*ttlcache.Entry[Key, Value]))
+
+ // SetTTL sets the cache item TTL. Update can be specified to force updates of existing items in the cache, this will simply add the change in TTL to their current expiry time.
+ SetTTL(ttl time.Duration, update bool)
+
+ // Get fetches the value with key from the cache, extending its TTL.
+ Get(key Key) (value Value, ok bool)
+
+ // Add attempts to place the value at key in the cache, doing nothing if a value with this key already exists. Returned bool is success state.
+ Add(key Key, value Value) bool
+
+ // Set places the value at key in the cache. This will overwrite any existing value, and call the update callback so. Existing values will have their TTL extended upon update.
+ Set(key Key, value Value)
+
+ // CAS will attempt to perform a CAS operation on 'key', using provided old and new values, and comparator function. Returned bool is success.
+ CAS(key Key, old, new Value, cmp func(Value, Value) bool) bool
+
+ // Swap will attempt to perform a swap on 'key', replacing the value there and returning the existing value. If no value exists for key, this will set the value and return the zero value for V.
+ Swap(key Key, swp Value) Value
+
+ // Has checks the cache for a value with key, this will not update TTL.
+ Has(key Key) bool
+
+ // Invalidate deletes a value from the cache, calling the invalidate callback.
+ Invalidate(key Key) bool
+
+ // Clear empties the cache, calling the invalidate callback.
+ Clear()
+
+ // Len returns the current length of the cache.
+ Len() int
+
+ // Cap returns the maximum capacity of the cache.
+ Cap() int
+}
+
+// New returns a new initialized Cache with given initial length, maximum capacity and item TTL.
+func New[K comparable, V any](len, cap int, ttl time.Duration) Cache[K, V] {
+ return ttlcache.New[K, V](len, cap, ttl)
+}