From b4c88b6b02d81f4f3c8b8b99325082ddf53e57aa Mon Sep 17 00:00:00 2001 From: Kyle Sanderson Date: Sat, 23 Nov 2024 19:03:23 -0800 Subject: [PATCH] expose Item --- main.go | 6 ++++-- pkg/ttlcache/domain.go | 4 ++-- pkg/ttlcache/internal.go | 38 +++++++++++++++++++++++++++++++++---- pkg/ttlcache/ttlcache.go | 41 +++++++++++++++++++++++++++------------- 4 files changed, 68 insertions(+), 21 deletions(-) diff --git a/main.go b/main.go index 5056e8d..f118d51 100644 --- a/main.go +++ b/main.go @@ -81,7 +81,8 @@ type timeentry struct { var db *bolt.DB var clientmap = ttlcache.New[qbittorrent.Config, *qbittorrent.Client]( ttlcache.Options[qbittorrent.Config, *qbittorrent.Client]{}. - SetDefaultTTL(time.Minute * 5)) + SetDefaultTTL(time.Minute * 5). + SetTimerResolution(time.Minute * 1)) var torrentmap = ttlcache.New[qbittorrent.Config, *timeentry]( ttlcache.Options[qbittorrent.Config, *timeentry]{}. @@ -90,7 +91,8 @@ var torrentmap = ttlcache.New[qbittorrent.Config, *timeentry]( var titlemap = ttlcache.New[string, *rls.Release]( ttlcache.Options[string, *rls.Release]{}. - SetDefaultTTL(time.Minute * 15)) + SetDefaultTTL(time.Minute * 15). + SetTimerResolution(time.Minute * 5)) func main() { initDatabase() diff --git a/pkg/ttlcache/domain.go b/pkg/ttlcache/domain.go index 3a59168..513ad8e 100644 --- a/pkg/ttlcache/domain.go +++ b/pkg/ttlcache/domain.go @@ -15,10 +15,10 @@ type Cache[K comparable, V any] struct { l sync.RWMutex o Options[K, V] ch chan time.Time - m map[K]item[V] + m map[K]Item[V] } -type item[V any] struct { +type Item[V any] struct { t time.Time d time.Duration v V diff --git a/pkg/ttlcache/internal.go b/pkg/ttlcache/internal.go index 4907757..e7ce4e4 100644 --- a/pkg/ttlcache/internal.go +++ b/pkg/ttlcache/internal.go @@ -2,7 +2,7 @@ package ttlcache import "time" -func (c *Cache[K, V]) get(key K) (item[V], bool) { +func (c *Cache[K, V]) get(key K) (Item[V], bool) { c.l.RLock() defer c.l.RUnlock() v, ok := c.m[key] @@ -14,7 +14,7 @@ func (c *Cache[K, V]) get(key K) (item[V], bool) { return v, ok } -func (c *Cache[K, V]) set(key K, it item[V]) { +func (c *Cache[K, V]) set(key K, it Item[V]) { it.t = c.getDuration(it.d) c.l.Lock() @@ -24,7 +24,7 @@ func (c *Cache[K, V]) set(key K, it item[V]) { } func (c *Cache[K, V]) delete(key K, reason DeallocationReason) { - var v item[V] + var v Item[V] c.l.Lock() defer c.l.Unlock() @@ -39,7 +39,7 @@ func (c *Cache[K, V]) delete(key K, reason DeallocationReason) { c.deleteUnsafe(key, v, reason) } -func (c *Cache[K, V]) deleteUnsafe(key K, v item[V], reason DeallocationReason) { +func (c *Cache[K, V]) deleteUnsafe(key K, v Item[V], reason DeallocationReason) { delete(c.m, key) if c.o.deallocationFunc != nil { @@ -47,6 +47,24 @@ func (c *Cache[K, V]) deleteUnsafe(key K, v item[V], reason DeallocationReason) } } +func (c *Cache[K, V]) getkeys() []K { + c.l.RLock() + defer c.l.RUnlock() + + keys := make([]K, len(c.m)) + for k := range c.m { + keys = append(keys, k) + } + + return keys +} + +func (c *Cache[K, V]) close() { + c.l.Lock() + defer c.l.Unlock() + close(c.ch) +} + func (c *Cache[K, V]) getDuration(d time.Duration) time.Time { switch d { case NoTTL: @@ -58,3 +76,15 @@ func (c *Cache[K, V]) getDuration(d time.Duration) time.Time { return time.Time{} } + +func (i *Item[V]) getDuration() time.Duration { + return i.d +} + +func (i *Item[V]) getTime() time.Time { + return i.t +} + +func (i *Item[V]) getValue() V { + return i.v +} diff --git a/pkg/ttlcache/ttlcache.go b/pkg/ttlcache/ttlcache.go index 7592099..c1a680f 100644 --- a/pkg/ttlcache/ttlcache.go +++ b/pkg/ttlcache/ttlcache.go @@ -10,7 +10,7 @@ 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]), + m: make(map[K]Item[V]), } if options.defaultTTL != NoTTL && options.defaultResolution == 0 { @@ -36,12 +36,25 @@ func (c *Cache[K, V]) Get(key K) (V, bool) { return it.v, 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() && c.getDuration(it.d).After(it.t) { + c.set(key, it) + } + + return it, ok +} + func (c *Cache[K, V]) Set(key K, value V, duration time.Duration) bool { if c.o.defaultTTL == NoTTL && duration == DefaultTTL { duration = NoTTL } - c.set(key, item[V]{v: value, d: duration}) + c.set(key, Item[V]{v: value, d: duration}) return true } @@ -49,22 +62,24 @@ 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.l.Lock() - defer c.l.Unlock() - close(c.ch) + c.close() } -func (c *Cache[K, V]) GetKeys() []K { - c.l.RLock() - defer c.l.RUnlock() +func (i *Item[V]) GetDuration() time.Duration { + return i.getDuration() +} - ret := make([]K, 0, len(c.m)) - for k := range c.m { - ret = append(ret, k) - } +func (i *Item[V]) GetTime() time.Time { + return i.getTime() +} - return ret +func (i *Item[V]) GetValue() V { + return i.getValue() } func (o Options[K, V]) SetTimerResolution(d time.Duration) Options[K, V] {