mirror of
https://gitee.com/johng/gf
synced 2026-06-06 02:25:47 +08:00
add functions Update/UpdateExpire/GetExpire for package gcache
This commit is contained in:
@ -13,42 +13,42 @@ import (
|
||||
)
|
||||
|
||||
// Default cache object.
|
||||
var cache = New()
|
||||
var defaultCache = New()
|
||||
|
||||
// Set sets cache with <key>-<value> pair, which is expired after <duration>.
|
||||
// It does not expire if <duration> == 0.
|
||||
func Set(key interface{}, value interface{}, duration time.Duration) {
|
||||
cache.Set(key, value, duration)
|
||||
defaultCache.Set(key, value, duration)
|
||||
}
|
||||
|
||||
// SetVar edit cache with <key>-<value> , but will not change expire.
|
||||
// If key is not exist return false. Nothing will change.
|
||||
func SetVar(key interface{}, value interface{}) bool {
|
||||
return cache.SetVar(key, value)
|
||||
// Update updates the value of <key> without changing its expiration and returns the old value.
|
||||
// The returned <exist> value is false if the <key> does not exist in the cache.
|
||||
func Update(key interface{}, value interface{}) (oldValue interface{}, exist bool) {
|
||||
return defaultCache.Update(key, value)
|
||||
}
|
||||
|
||||
// SetIfNotExist sets cache with <key>-<value> pair if <key> does not exist in the cache,
|
||||
// which is expired after <duration>. It does not expire if <duration> == 0.
|
||||
func SetIfNotExist(key interface{}, value interface{}, duration time.Duration) bool {
|
||||
return cache.SetIfNotExist(key, value, duration)
|
||||
return defaultCache.SetIfNotExist(key, value, duration)
|
||||
}
|
||||
|
||||
// Sets batch sets cache with key-value pairs by <data>, which is expired after <duration>.
|
||||
//
|
||||
// It does not expire if <duration> == 0.
|
||||
func Sets(data map[interface{}]interface{}, duration time.Duration) {
|
||||
cache.Sets(data, duration)
|
||||
defaultCache.Sets(data, duration)
|
||||
}
|
||||
|
||||
// Get returns the value of <key>.
|
||||
// It returns nil if it does not exist or its value is nil.
|
||||
func Get(key interface{}) interface{} {
|
||||
return cache.Get(key)
|
||||
return defaultCache.Get(key)
|
||||
}
|
||||
|
||||
// GetVar retrieves and returns the value of <key> as gvar.Var.
|
||||
func GetVar(key interface{}) *gvar.Var {
|
||||
return cache.GetVar(key)
|
||||
return defaultCache.GetVar(key)
|
||||
}
|
||||
|
||||
// GetOrSet returns the value of <key>,
|
||||
@ -57,14 +57,14 @@ func GetVar(key interface{}) *gvar.Var {
|
||||
//
|
||||
// It does not expire if <duration> == 0.
|
||||
func GetOrSet(key interface{}, value interface{}, duration time.Duration) interface{} {
|
||||
return cache.GetOrSet(key, value, duration)
|
||||
return defaultCache.GetOrSet(key, value, duration)
|
||||
}
|
||||
|
||||
// GetOrSetFunc returns the value of <key>, or sets <key> with result of function <f>
|
||||
// and returns its result if <key> does not exist in the cache. The key-value pair expires
|
||||
// after <duration>. It does not expire if <duration> == 0.
|
||||
func GetOrSetFunc(key interface{}, f func() interface{}, duration time.Duration) interface{} {
|
||||
return cache.GetOrSetFunc(key, f, duration)
|
||||
return defaultCache.GetOrSetFunc(key, f, duration)
|
||||
}
|
||||
|
||||
// GetOrSetFuncLock returns the value of <key>, or sets <key> with result of function <f>
|
||||
@ -73,57 +73,59 @@ func GetOrSetFunc(key interface{}, f func() interface{}, duration time.Duration)
|
||||
//
|
||||
// Note that the function <f> is executed within writing mutex lock.
|
||||
func GetOrSetFuncLock(key interface{}, f func() interface{}, duration time.Duration) interface{} {
|
||||
return cache.GetOrSetFuncLock(key, f, duration)
|
||||
return defaultCache.GetOrSetFuncLock(key, f, duration)
|
||||
}
|
||||
|
||||
// Contains returns true if <key> exists in the cache, or else returns false.
|
||||
func Contains(key interface{}) bool {
|
||||
return cache.Contains(key)
|
||||
return defaultCache.Contains(key)
|
||||
}
|
||||
|
||||
// Remove deletes the one or more keys from cache, and returns its value.
|
||||
// If multiple keys are given, it returns the value of the deleted last item.
|
||||
func Remove(keys ...interface{}) (value interface{}) {
|
||||
return cache.Remove(keys...)
|
||||
return defaultCache.Remove(keys...)
|
||||
}
|
||||
|
||||
// Removes deletes <keys> in the cache.
|
||||
// Deprecated, use Remove instead.
|
||||
func Removes(keys []interface{}) {
|
||||
cache.Removes(keys)
|
||||
defaultCache.Removes(keys)
|
||||
}
|
||||
|
||||
// Data returns a copy of all key-value pairs in the cache as map type.
|
||||
func Data() map[interface{}]interface{} {
|
||||
return cache.Data()
|
||||
return defaultCache.Data()
|
||||
}
|
||||
|
||||
// Keys returns all keys in the cache as slice.
|
||||
func Keys() []interface{} {
|
||||
return cache.Keys()
|
||||
return defaultCache.Keys()
|
||||
}
|
||||
|
||||
// KeyStrings returns all keys in the cache as string slice.
|
||||
func KeyStrings() []string {
|
||||
return cache.KeyStrings()
|
||||
return defaultCache.KeyStrings()
|
||||
}
|
||||
|
||||
// Values returns all values in the cache as slice.
|
||||
func Values() []interface{} {
|
||||
return cache.Values()
|
||||
return defaultCache.Values()
|
||||
}
|
||||
|
||||
// Size returns the size of the cache.
|
||||
func Size() int {
|
||||
return cache.Size()
|
||||
return defaultCache.Size()
|
||||
}
|
||||
|
||||
// GetExpire returns the expire time with given expired duration in milliseconds.
|
||||
func GetExpire(key interface{}) (int64, bool) {
|
||||
return cache.GetExpire(key)
|
||||
// GetExpire retrieves and returns the expiration of <key>.
|
||||
// It returns -1 if the <key> does not exist in the cache.
|
||||
func GetExpire(key interface{}) time.Duration {
|
||||
return defaultCache.GetExpire(key)
|
||||
}
|
||||
|
||||
// SetExpire set cache expired after <duration>.
|
||||
func SetExpire(key interface{}, duration time.Duration) bool {
|
||||
return cache.SetExpire(key, duration)
|
||||
// UpdateExpire updates the expiration of <key> and returns the old expiration duration value.
|
||||
// It returns -1 if the <key> does not exist in the cache.
|
||||
func UpdateExpire(key interface{}, duration time.Duration) (oldDuration time.Duration) {
|
||||
return defaultCache.UpdateExpire(key, duration)
|
||||
}
|
||||
|
||||
@ -64,7 +64,7 @@ type memCache struct {
|
||||
// Internal cache item.
|
||||
type memCacheItem struct {
|
||||
v interface{} // Value.
|
||||
e int64 // Expire time in milliseconds.
|
||||
e int64 // Expire timestamp in milliseconds.
|
||||
}
|
||||
|
||||
// Internal event item.
|
||||
@ -97,7 +97,6 @@ func newMemCache(lruCap ...int) *memCache {
|
||||
}
|
||||
|
||||
// Set sets cache with <key>-<value> pair, which is expired after <duration>.
|
||||
//
|
||||
// It does not expire if <duration> == 0.
|
||||
func (c *memCache) Set(key interface{}, value interface{}, duration time.Duration) {
|
||||
expireTime := c.getInternalExpire(duration)
|
||||
@ -113,8 +112,9 @@ func (c *memCache) Set(key interface{}, value interface{}, duration time.Duratio
|
||||
})
|
||||
}
|
||||
|
||||
// SetVar retrieves and set the value of <key>.
|
||||
func (c *memCache) SetVar(key interface{}, value interface{}) bool {
|
||||
// Update updates the value of <key> without changing its expiration and returns the old value.
|
||||
// The returned <exist> value is false if the <key> does not exist in the cache.
|
||||
func (c *memCache) Update(key interface{}, value interface{}) (oldValue interface{}, exist bool) {
|
||||
c.dataMu.Lock()
|
||||
defer c.dataMu.Unlock()
|
||||
if item, ok := c.data[key]; ok {
|
||||
@ -122,21 +122,18 @@ func (c *memCache) SetVar(key interface{}, value interface{}) bool {
|
||||
v: value,
|
||||
e: item.e,
|
||||
}
|
||||
return true
|
||||
return item.v, true
|
||||
}
|
||||
return false
|
||||
return nil, false
|
||||
}
|
||||
|
||||
// SetExpire retrieves and set the value of <key>.
|
||||
func (c *memCache) SetExpire(key interface{}, duration time.Duration) bool {
|
||||
// UpdateExpire updates the expiration of <key> and returns the old expiration duration value.
|
||||
// It returns -1 if the <key> does not exist in the cache.
|
||||
func (c *memCache) UpdateExpire(key interface{}, duration time.Duration) (oldDuration time.Duration) {
|
||||
newExpireTime := c.getInternalExpire(duration)
|
||||
c.dataMu.Lock()
|
||||
defer c.dataMu.Unlock()
|
||||
if item, ok := c.data[key]; ok {
|
||||
c.eventList.PushBack(&memCacheEvent{
|
||||
k: key,
|
||||
e: gtime.TimestampMilli() - 1000,
|
||||
})
|
||||
newExpireTime := c.getInternalExpire(duration)
|
||||
c.data[key] = memCacheItem{
|
||||
v: item.v,
|
||||
e: newExpireTime,
|
||||
@ -145,18 +142,20 @@ func (c *memCache) SetExpire(key interface{}, duration time.Duration) bool {
|
||||
k: key,
|
||||
e: newExpireTime,
|
||||
})
|
||||
return true
|
||||
return time.Duration(item.e-gtime.TimestampMilli()) * time.Millisecond
|
||||
}
|
||||
return false
|
||||
return -1
|
||||
}
|
||||
|
||||
func (c *memCache) GetExpire(key interface{}) (int64, bool) {
|
||||
// GetExpire retrieves and returns the expiration of <key>.
|
||||
// It returns -1 if the <key> does not exist in the cache.
|
||||
func (c *memCache) GetExpire(key interface{}) time.Duration {
|
||||
c.dataMu.RLock()
|
||||
defer c.dataMu.RUnlock()
|
||||
if item, ok := c.data[key]; ok {
|
||||
return item.e, true
|
||||
return time.Duration(item.e-gtime.TimestampMilli()) * time.Millisecond
|
||||
}
|
||||
return 0, false
|
||||
return -1
|
||||
}
|
||||
|
||||
// doSetWithLockCheck sets cache with <key>-<value> pair if <key> does not exist in the
|
||||
|
||||
@ -15,15 +15,15 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
cache = gcache.New()
|
||||
cacheLru = gcache.New(10000)
|
||||
localCache = gcache.New()
|
||||
localCacheLru = gcache.New(10000)
|
||||
)
|
||||
|
||||
func Benchmark_CacheSet(b *testing.B) {
|
||||
b.RunParallel(func(pb *testing.PB) {
|
||||
i := 0
|
||||
for pb.Next() {
|
||||
cache.Set(i, i, 0)
|
||||
localCache.Set(i, i, 0)
|
||||
i++
|
||||
}
|
||||
})
|
||||
@ -33,7 +33,7 @@ func Benchmark_CacheGet(b *testing.B) {
|
||||
b.RunParallel(func(pb *testing.PB) {
|
||||
i := 0
|
||||
for pb.Next() {
|
||||
cache.Get(i)
|
||||
localCache.Get(i)
|
||||
i++
|
||||
}
|
||||
})
|
||||
@ -43,7 +43,7 @@ func Benchmark_CacheRemove(b *testing.B) {
|
||||
b.RunParallel(func(pb *testing.PB) {
|
||||
i := 0
|
||||
for pb.Next() {
|
||||
cache.Remove(i)
|
||||
localCache.Remove(i)
|
||||
i++
|
||||
}
|
||||
})
|
||||
@ -53,7 +53,7 @@ func Benchmark_CacheLruSet(b *testing.B) {
|
||||
b.RunParallel(func(pb *testing.PB) {
|
||||
i := 0
|
||||
for pb.Next() {
|
||||
cacheLru.Set(i, i, 0)
|
||||
localCacheLru.Set(i, i, 0)
|
||||
i++
|
||||
}
|
||||
})
|
||||
@ -63,7 +63,7 @@ func Benchmark_CacheLruGet(b *testing.B) {
|
||||
b.RunParallel(func(pb *testing.PB) {
|
||||
i := 0
|
||||
for pb.Next() {
|
||||
cacheLru.Get(i)
|
||||
localCacheLru.Get(i)
|
||||
i++
|
||||
}
|
||||
})
|
||||
@ -73,7 +73,7 @@ func Benchmark_CacheLruRemove(b *testing.B) {
|
||||
b.RunParallel(func(pb *testing.PB) {
|
||||
i := 0
|
||||
for pb.Next() {
|
||||
cacheLru.Remove(i)
|
||||
localCacheLru.Remove(i)
|
||||
i++
|
||||
}
|
||||
})
|
||||
|
||||
@ -9,9 +9,7 @@
|
||||
package gcache_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/gogf/gf/os/glog"
|
||||
"github.com/gogf/gf/util/grand"
|
||||
"github.com/gogf/gf/util/guid"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
@ -76,32 +74,51 @@ func TestCache_Set_Expire(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func TestCache_SetVar(t *testing.T) {
|
||||
func TestCache_Update_GetExpire(t *testing.T) {
|
||||
// gcache
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
key := guid.S()
|
||||
gcache.Set(key, 11, 3*time.Second)
|
||||
oldExpire1 := gcache.GetExpire(key)
|
||||
gcache.Update(key, 12)
|
||||
oldExpire2 := gcache.GetExpire(key)
|
||||
t.Assert(gcache.GetVar(key), 12)
|
||||
t.Assert(oldExpire1, oldExpire2)
|
||||
})
|
||||
// gcache.Cache
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
cache := gcache.New()
|
||||
cache.Set(1, 11, 3*time.Second)
|
||||
expireBefore, _ := cache.GetExpire(1)
|
||||
cache.SetVar(1, 12)
|
||||
expireAfter, _ := cache.GetExpire(1)
|
||||
oldExpire1 := cache.GetExpire(1)
|
||||
cache.Update(1, 12)
|
||||
oldExpire2 := cache.GetExpire(1)
|
||||
t.Assert(cache.GetVar(1), 12)
|
||||
t.Assert(expireBefore, expireAfter)
|
||||
t.Assert(oldExpire1, oldExpire2)
|
||||
})
|
||||
}
|
||||
|
||||
func BenchmarkMemCache_GetSetExpire(b *testing.B) {
|
||||
cache := gcache.New()
|
||||
cache.Set(1, 11, 3*time.Second)
|
||||
if expire, ok := cache.GetExpire(1); ok {
|
||||
glog.Println(expire)
|
||||
}
|
||||
for i := 0; i < b.N; i++ {
|
||||
r := time.Duration(grand.N(5, 10))
|
||||
cache.SetExpire(1, r*time.Second)
|
||||
//cache.SetExpire(1, 7*time.Second)
|
||||
if _, ok := cache.GetExpire(1); !ok {
|
||||
panic(fmt.Sprintf("[ERROR] %s", "GetExpire error"))
|
||||
}
|
||||
}
|
||||
func TestCache_UpdateExpire(t *testing.T) {
|
||||
// gcache
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
key := guid.S()
|
||||
gcache.Set(key, 11, 3*time.Second)
|
||||
defer gcache.Remove(key)
|
||||
oldExpire := gcache.GetExpire(key)
|
||||
newExpire := 10 * time.Second
|
||||
gcache.UpdateExpire(key, newExpire)
|
||||
t.AssertNE(gcache.GetExpire(key), oldExpire)
|
||||
t.Assert(gcache.GetExpire(key), newExpire)
|
||||
})
|
||||
// gcache.Cache
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
cache := gcache.New()
|
||||
cache.Set(1, 11, 3*time.Second)
|
||||
oldExpire := cache.GetExpire(1)
|
||||
newExpire := 10 * time.Second
|
||||
cache.UpdateExpire(1, newExpire)
|
||||
t.AssertNE(cache.GetExpire(1), oldExpire)
|
||||
t.Assert(cache.GetExpire(1), newExpire)
|
||||
})
|
||||
}
|
||||
|
||||
func TestCache_Keys_Values(t *testing.T) {
|
||||
|
||||
Reference in New Issue
Block a user