diff --git a/main.go b/main.go index 8a7717e..da4e8cc 100644 --- a/main.go +++ b/main.go @@ -159,17 +159,19 @@ func (c *upgradereq) getAllTorrents() (*timeentry, error) { } getOrInitialize := func() ttlcache.Item[*timeentry] { - if it, ok := torrentmap.GetItem(set); ok { - if c.CacheBypass == 0 { + it, ok := torrentmap.GetOrSetItem(set, &timeentry{}, ttlcache.DefaultTTL) + if !ok { + return torrentmap.SetItem(set, &timeentry{}, ttlcache.DefaultTTL) + } + + if c.CacheBypass == 0 { + return it + } else if c.CacheBypass == 1 { + val := it.GetValue() + val.m.RLock() + defer val.m.RUnlock() + if val.e == nil { return it - } else if c.CacheBypass == 1 { - val := it.GetValue() - val.m.RLock() - defer val.m.RUnlock() - - if val.e == nil { - return it - } } } diff --git a/pkg/ttlcache/internal.go b/pkg/ttlcache/internal.go index c87b88e..202bea2 100644 --- a/pkg/ttlcache/internal.go +++ b/pkg/ttlcache/internal.go @@ -24,6 +24,14 @@ func (c *Cache[K, V]) set(key K, it Item[V]) Item[V] { return it } +func (c *Cache[K, V]) getOrSet(key K, it Item[V]) (Item[V], bool) { + if v, ok := c.get(key); ok { + return v, ok + } + + return c.set(key, it), true +} + func (c *Cache[K, V]) delete(key K, reason DeallocationReason) { var v Item[V] c.l.Lock() diff --git a/pkg/ttlcache/ttlcache.go b/pkg/ttlcache/ttlcache.go index 02e400a..5f65bab 100644 --- a/pkg/ttlcache/ttlcache.go +++ b/pkg/ttlcache/ttlcache.go @@ -47,6 +47,28 @@ func (c *Cache[K, V]) GetItem(key K) (Item[V], bool) { 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]) GetOrSetItem(key K, value V, duration time.Duration) (Item[V], bool) { + if c.o.defaultTTL == NoTTL && duration == DefaultTTL { + duration = NoTTL + } + + it, ok := c.getOrSet(key, Item[V]{v: value, d: 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