From 77d8a7d140cc1ef3d8d76e976f1e5a3b870b0fff Mon Sep 17 00:00:00 2001 From: zhangsixian Date: Fri, 2 Dec 2022 18:31:11 +0800 Subject: [PATCH] feat: GetOrSetFunc --- arc.go | 16 ++++++++++++++++ cache.go | 2 ++ lfu.go | 16 ++++++++++++++++ lru.go | 16 ++++++++++++++++ simple.go | 16 ++++++++++++++++ 5 files changed, 66 insertions(+) diff --git a/arc.go b/arc.go index 7d0a012..3a03d13 100644 --- a/arc.go +++ b/arc.go @@ -182,6 +182,22 @@ func (c *ARC) GetIFPresent(key interface{}) (interface{}, error) { return v, err } +// GetOrSetFunc return the value and set if the key not found. +func (c *ARC) GetOrSetFunc(key interface{}, f func() (interface{}, error), duration time.Duration) (interface{}, error) { + v, err := c.Get(key) + if err == KeyNotFoundError { + value, err := f() + if err != nil { + return nil, err + } + if value == nil { + return nil, nil + } + return v, c.SetWithExpire(key, value, duration) + } + return v, nil +} + func (c *ARC) get(key interface{}, onLoad bool) (interface{}, error) { v, err := c.getValue(key, onLoad) if err != nil { diff --git a/cache.go b/cache.go index 0ae51bf..90fd12a 100644 --- a/cache.go +++ b/cache.go @@ -30,6 +30,8 @@ type Cache interface { // GetIFPresent returns the value for the specified key if it is present in the cache. // Return KeyNotFoundError if the key is not present. GetIFPresent(key interface{}) (interface{}, error) + // GetOrSetFunc return the value and set if the key not found. + GetOrSetFunc(key interface{}, f func() (interface{}, error), duration time.Duration) (interface{}, error) // GetAll returns a map containing all key-value pairs in the cache. GetALL(checkExpired bool) map[interface{}]interface{} get(key interface{}, onLoad bool) (interface{}, error) diff --git a/lfu.go b/lfu.go index 610843e..695e8df 100644 --- a/lfu.go +++ b/lfu.go @@ -133,6 +133,22 @@ func (c *LFUCache) GetIFPresent(key interface{}) (interface{}, error) { return v, err } +// GetOrSetFunc return the value and set if the key not found. +func (c *LFUCache) GetOrSetFunc(key interface{}, f func() (interface{}, error), duration time.Duration) (interface{}, error) { + v, err := c.Get(key) + if err == KeyNotFoundError { + value, err := f() + if err != nil { + return nil, err + } + if value == nil { + return nil, nil + } + return v, c.SetWithExpire(key, value, duration) + } + return v, nil +} + func (c *LFUCache) get(key interface{}, onLoad bool) (interface{}, error) { v, err := c.getValue(key, onLoad) if err != nil { diff --git a/lru.go b/lru.go index 7d79a8f..8e81eb5 100644 --- a/lru.go +++ b/lru.go @@ -110,6 +110,22 @@ func (c *LRUCache) GetIFPresent(key interface{}) (interface{}, error) { return v, err } +// GetOrSetFunc return the value and set if the key not found. +func (c *LRUCache) GetOrSetFunc(key interface{}, f func() (interface{}, error), duration time.Duration) (interface{}, error) { + v, err := c.Get(key) + if err == KeyNotFoundError { + value, err := f() + if err != nil { + return nil, err + } + if value == nil { + return nil, nil + } + return v, c.SetWithExpire(key, value, duration) + } + return v, nil +} + func (c *LRUCache) get(key interface{}, onLoad bool) (interface{}, error) { v, err := c.getValue(key, onLoad) if err != nil { diff --git a/simple.go b/simple.go index 956d40a..01168f2 100644 --- a/simple.go +++ b/simple.go @@ -108,6 +108,22 @@ func (c *SimpleCache) GetIFPresent(key interface{}) (interface{}, error) { return v, nil } +// GetOrSetFunc return the value and set if the key not found. +func (c *SimpleCache) GetOrSetFunc(key interface{}, f func() (interface{}, error), duration time.Duration) (interface{}, error) { + v, err := c.Get(key) + if err == KeyNotFoundError { + value, err := f() + if err != nil { + return nil, err + } + if value == nil { + return nil, nil + } + return v, c.SetWithExpire(key, value, duration) + } + return v, nil +} + func (c *SimpleCache) get(key interface{}, onLoad bool) (interface{}, error) { v, err := c.getValue(key, onLoad) if err != nil {