mirror of
https://github.com/idanoo/autobrr
synced 2025-07-23 00:39:13 +00:00
feat(cache): implement TTLCache and TimeCache (#1822)
* feat(pkg): implement ttlcache and timecache
This commit is contained in:
parent
acef4ac624
commit
c1d8a4a850
8 changed files with 742 additions and 21 deletions
127
pkg/ttlcache/ttlcache.go
Normal file
127
pkg/ttlcache/ttlcache.go
Normal file
|
@ -0,0 +1,127 @@
|
|||
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
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue