mirror of
https://github.com/idanoo/autobrr
synced 2025-07-22 16:29:12 +00:00
130 lines
2.8 KiB
Go
130 lines
2.8 KiB
Go
// Copyright (c) 2021-2025, Ludvig Lundgren and the autobrr contributors.
|
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
|
|
package ttlcache
|
|
|
|
import (
|
|
"time"
|
|
|
|
"github.com/autobrr/autobrr/pkg/timecache"
|
|
)
|
|
|
|
func New[K comparable, V any](options Options[K, V]) *Cache[K, V] {
|
|
c := Cache[K, V]{
|
|
o: options,
|
|
ch: make(chan time.Time, 1000),
|
|
m: make(map[K]Item[V]),
|
|
}
|
|
|
|
if options.defaultTTL != NoTTL && options.defaultResolution == 0 {
|
|
c.tc = *timecache.New(timecache.Options{}.Round(options.defaultTTL / 2))
|
|
} else if options.defaultResolution != 0 {
|
|
c.tc = *timecache.New(timecache.Options{}.Round(options.defaultResolution))
|
|
}
|
|
|
|
go c.startExpirations()
|
|
return &c
|
|
}
|
|
|
|
func (c *Cache[K, V]) Get(key K) (V, bool) {
|
|
it, ok := c.GetItem(key)
|
|
if !ok {
|
|
return *new(V), ok
|
|
}
|
|
|
|
return it.GetValue(), ok
|
|
}
|
|
|
|
func (c *Cache[K, V]) GetItem(key K) (Item[V], bool) {
|
|
it, ok := c.get(key)
|
|
if !ok {
|
|
return it, ok
|
|
}
|
|
|
|
if !c.o.noUpdateTime && !it.t.IsZero() {
|
|
if _, t := c.getDuration(it.d); t.After(it.t) {
|
|
c.set(key, it)
|
|
}
|
|
}
|
|
|
|
return it, ok
|
|
}
|
|
|
|
func (c *Cache[K, V]) GetOrSet(key K, value V, duration time.Duration) (V, bool) {
|
|
it, ok := c.GetOrSetItem(key, value, duration)
|
|
if !ok {
|
|
return *new(V), ok
|
|
}
|
|
|
|
return it.GetValue(), ok
|
|
}
|
|
|
|
func (c *Cache[K, V]) fixupDuration(duration time.Duration) time.Duration {
|
|
if c.o.defaultTTL == NoTTL && duration == DefaultTTL {
|
|
return NoTTL
|
|
}
|
|
|
|
return duration
|
|
}
|
|
|
|
func (c *Cache[K, V]) GetOrSetItem(key K, value V, duration time.Duration) (Item[V], bool) {
|
|
it, ok := c.getOrSet(key, Item[V]{v: value, d: c.fixupDuration(duration)})
|
|
if !ok {
|
|
return Item[V]{}, ok
|
|
}
|
|
|
|
return it, ok
|
|
}
|
|
|
|
func (c *Cache[K, V]) Set(key K, value V, duration time.Duration) bool {
|
|
c.SetItem(key, value, duration)
|
|
return true
|
|
}
|
|
|
|
func (c *Cache[K, V]) SetItem(key K, value V, duration time.Duration) Item[V] {
|
|
return c.set(key, Item[V]{v: value, d: c.fixupDuration(duration)})
|
|
}
|
|
|
|
func (c *Cache[K, V]) Delete(key K) {
|
|
c.delete(key, ReasonDeleted)
|
|
}
|
|
|
|
func (c *Cache[K, V]) GetKeys() []K {
|
|
return c.getkeys()
|
|
}
|
|
|
|
func (c *Cache[K, V]) Close() {
|
|
c.close()
|
|
}
|
|
|
|
func (i *Item[V]) GetDuration() time.Duration {
|
|
return i.getDuration()
|
|
}
|
|
|
|
func (i *Item[V]) GetTime() time.Time {
|
|
return i.getTime()
|
|
}
|
|
|
|
func (i *Item[V]) GetValue() V {
|
|
return i.getValue()
|
|
}
|
|
|
|
func (o Options[K, V]) SetTimerResolution(d time.Duration) Options[K, V] {
|
|
o.defaultResolution = d
|
|
return o
|
|
}
|
|
|
|
func (o Options[K, V]) SetDefaultTTL(d time.Duration) Options[K, V] {
|
|
o.defaultTTL = d
|
|
return o
|
|
}
|
|
|
|
func (o Options[K, V]) SetDeallocationFunc(f DeallocationFunc[K, V]) Options[K, V] {
|
|
o.deallocationFunc = f
|
|
return o
|
|
}
|
|
|
|
func (o Options[K, V]) DisableUpdateTime(val bool) Options[K, V] {
|
|
o.noUpdateTime = val
|
|
return o
|
|
}
|