diff --git a/os/gcache/gcache.go b/os/gcache/gcache.go index cdcf00515..4a8a91d7d 100644 --- a/os/gcache/gcache.go +++ b/os/gcache/gcache.go @@ -13,42 +13,42 @@ import ( ) // Default cache object. -var cache = New() +var defaultCache = New() // Set sets cache with - pair, which is expired after . // It does not expire if == 0. func Set(key interface{}, value interface{}, duration time.Duration) { - cache.Set(key, value, duration) + defaultCache.Set(key, value, duration) } -// SetVar edit cache with - , 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 without changing its expiration and returns the old value. +// The returned value is false if the 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 - pair if does not exist in the cache, // which is expired after . It does not expire if == 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 , which is expired after . // // It does not expire if == 0. func Sets(data map[interface{}]interface{}, duration time.Duration) { - cache.Sets(data, duration) + defaultCache.Sets(data, duration) } // Get returns the value of . // 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 as gvar.Var. func GetVar(key interface{}) *gvar.Var { - return cache.GetVar(key) + return defaultCache.GetVar(key) } // GetOrSet returns the value of , @@ -57,14 +57,14 @@ func GetVar(key interface{}) *gvar.Var { // // It does not expire if == 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 , or sets with result of function // and returns its result if does not exist in the cache. The key-value pair expires // after . It does not expire if == 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 , or sets with result of function @@ -73,57 +73,59 @@ func GetOrSetFunc(key interface{}, f func() interface{}, duration time.Duration) // // Note that the function 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 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 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 . +// It returns -1 if the does not exist in the cache. +func GetExpire(key interface{}) time.Duration { + return defaultCache.GetExpire(key) } -// SetExpire set cache expired after . -func SetExpire(key interface{}, duration time.Duration) bool { - return cache.SetExpire(key, duration) +// UpdateExpire updates the expiration of and returns the old expiration duration value. +// It returns -1 if the does not exist in the cache. +func UpdateExpire(key interface{}, duration time.Duration) (oldDuration time.Duration) { + return defaultCache.UpdateExpire(key, duration) } diff --git a/os/gcache/gcache_mem_cache.go b/os/gcache/gcache_mem_cache.go index 745393b3d..b8eccaa77 100644 --- a/os/gcache/gcache_mem_cache.go +++ b/os/gcache/gcache_mem_cache.go @@ -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 - pair, which is expired after . -// // It does not expire if == 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 . -func (c *memCache) SetVar(key interface{}, value interface{}) bool { +// Update updates the value of without changing its expiration and returns the old value. +// The returned value is false if the 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 . -func (c *memCache) SetExpire(key interface{}, duration time.Duration) bool { +// UpdateExpire updates the expiration of and returns the old expiration duration value. +// It returns -1 if the 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 . +// It returns -1 if the 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 - pair if does not exist in the diff --git a/os/gcache/gcache_z_bench_test.go b/os/gcache/gcache_z_bench_test.go index 0279cf6c3..a3df89941 100644 --- a/os/gcache/gcache_z_bench_test.go +++ b/os/gcache/gcache_z_bench_test.go @@ -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++ } }) diff --git a/os/gcache/gcache_z_unit_1_test.go b/os/gcache/gcache_z_unit_1_test.go index 5a451c227..f3ba0c7c9 100644 --- a/os/gcache/gcache_z_unit_1_test.go +++ b/os/gcache/gcache_z_unit_1_test.go @@ -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) {