diff --git a/cache.go b/cache.go index 2f0d140..d6c5497 100644 --- a/cache.go +++ b/cache.go @@ -395,6 +395,32 @@ func (c *Cache[K, V]) GetOrSet(key K, value V, opts ...Option[K, V]) (*Item[K, V return item, false } +// GetOrSetFunc retrieves an item from the cache by the provided key. +// If the element is not found, it is created by executing the fn function +// with the provided options and then returned. +// The bool return value is true if the item was found, false if created +// during the execution of the method. +// If the loader is non-nil (i.e., used as an option or specified when +// creating the cache instance), its execution is skipped. +func (c *Cache[K, V]) GetOrSetFunc(key K, fn func() V, opts ...Option[K, V]) (*Item[K, V], bool) { + c.items.mu.Lock() + defer c.items.mu.Unlock() + + elem := c.getWithOpts(key, false, opts...) + if elem != nil { + return elem, true + } + + setOpts := options[K, V]{ + ttl: c.options.ttl, + } + applyOptions(&setOpts, opts...) // used only to update the TTL + + item := c.set(key, fn(), setOpts.ttl) + + return item, false +} + // GetAndDelete retrieves an item from the cache by the provided key and // then deletes it. // The bool return value is true if the item was found before