From 3e27ea025953a650405aca0c78238547946d24be Mon Sep 17 00:00:00 2001 From: John Date: Wed, 4 Dec 2019 14:42:09 +0800 Subject: [PATCH] change duration parameter type from interface{} to time.Duration for gcache/gfcache --- database/gdb/gdb_model.go | 8 ++----- os/gcache/gcache.go | 14 +++++++----- os/gcache/gcache_mem_cache.go | 37 +++++++++---------------------- os/gcache/gcache_z_unit_1_test.go | 2 +- os/gfcache/gfcache.go | 33 +++++++++------------------ 5 files changed, 33 insertions(+), 61 deletions(-) diff --git a/database/gdb/gdb_model.go b/database/gdb/gdb_model.go index a2ec6a8f3..d9fa5ff8a 100644 --- a/database/gdb/gdb_model.go +++ b/database/gdb/gdb_model.go @@ -335,13 +335,9 @@ func (md *Model) Batch(batch int) *Model { // 2. expire参数类型为interface{},这是一个兼容旧版本的方式,该参数支持 int/time.Duration 类型,当传递类型为int时,表示缓存多少秒。 // 3. name表示自定义的缓存名称(注意不要出现重复),便于业务层精准定位缓存项(如果业务层需要手动清理时,必须指定缓存名称), // 例如:查询缓存时设置名称,在特定的业务逻辑中清理缓存时可以给定缓存名称进行精准清理。 -func (md *Model) Cache(expire interface{}, name ...string) *Model { +func (md *Model) Cache(expire time.Duration, name ...string) *Model { model := md.getModel() - if d, ok := expire.(time.Duration); ok { - model.cacheExpire = d - } else { - model.cacheExpire = gconv.Duration(expire) * time.Second - } + model.cacheExpire = expire if len(name) > 0 { model.cacheName = name[0] } diff --git a/os/gcache/gcache.go b/os/gcache/gcache.go index 3123c73d2..6c8554bc7 100644 --- a/os/gcache/gcache.go +++ b/os/gcache/gcache.go @@ -7,6 +7,8 @@ // Package gcache provides high performance and concurrent-safe in-memory cache for process. package gcache +import "time" + // Default cache object. var cache = New() @@ -15,7 +17,7 @@ var cache = New() // The parameter can be either type of int or time.Duration. // If is type of int, it means milliseconds. // If <=0 means it does not expire. -func Set(key interface{}, value interface{}, duration interface{}) { +func Set(key interface{}, value interface{}, duration time.Duration) { cache.Set(key, value, duration) } @@ -25,7 +27,7 @@ func Set(key interface{}, value interface{}, duration interface{}) { // The parameter can be either type of int or time.Duration. // If is type of int, it means milliseconds. // If <=0 means it does not expire. -func SetIfNotExist(key interface{}, value interface{}, duration interface{}) bool { +func SetIfNotExist(key interface{}, value interface{}, duration time.Duration) bool { return cache.SetIfNotExist(key, value, duration) } @@ -34,7 +36,7 @@ func SetIfNotExist(key interface{}, value interface{}, duration interface{}) boo // The parameter can be either type of int or time.Duration. // If is type of int, it means milliseconds. // If <=0 means it does not expire. -func Sets(data map[interface{}]interface{}, duration interface{}) { +func Sets(data map[interface{}]interface{}, duration time.Duration) { cache.Sets(data, duration) } @@ -51,7 +53,7 @@ func Get(key interface{}) interface{} { // The parameter can be either type of int or time.Duration. // If is type of int, it means milliseconds. // If <=0 means it does not expire. -func GetOrSet(key interface{}, value interface{}, duration interface{}) interface{} { +func GetOrSet(key interface{}, value interface{}, duration time.Duration) interface{} { return cache.GetOrSet(key, value, duration) } @@ -63,7 +65,7 @@ func GetOrSet(key interface{}, value interface{}, duration interface{}) interfac // The parameter can be either type of int or time.Duration. // If is type of int, it means milliseconds. // If <=0 means it does not expire. -func GetOrSetFunc(key interface{}, f func() interface{}, duration interface{}) interface{} { +func GetOrSetFunc(key interface{}, f func() interface{}, duration time.Duration) interface{} { return cache.GetOrSetFunc(key, f, duration) } @@ -77,7 +79,7 @@ func GetOrSetFunc(key interface{}, f func() interface{}, duration interface{}) i // If <=0 means it does not expire. // // Note that the function is executed within writing mutex lock. -func GetOrSetFuncLock(key interface{}, f func() interface{}, duration interface{}) interface{} { +func GetOrSetFuncLock(key interface{}, f func() interface{}, duration time.Duration) interface{} { return cache.GetOrSetFuncLock(key, f, duration) } diff --git a/os/gcache/gcache_mem_cache.go b/os/gcache/gcache_mem_cache.go index b17a7ff0c..69929d85e 100644 --- a/os/gcache/gcache_mem_cache.go +++ b/os/gcache/gcache_mem_cache.go @@ -104,25 +104,13 @@ func (c *memCache) getOrNewExpireSet(expire int64) (expireSet *gset.Set) { return } -// getMilliExpire converts parameter to int type in milliseconds. -// -// Note that there's some performance cost in type assertion here, but it's valuable. -func (c *memCache) getMilliExpire(duration interface{}) int64 { - if d, ok := duration.(time.Duration); ok { - return d.Nanoseconds() / 1000000 - } else { - return gconv.Int64(duration) - } -} - // Set sets cache with - pair, which is expired after . // // The parameter can be either type of int or time.Duration. // If is type of int, it means milliseconds. // If <=0 means it does not expire. -func (c *memCache) Set(key interface{}, value interface{}, duration interface{}) { - expire := c.getMilliExpire(duration) - expireTime := c.getInternalExpire(expire) +func (c *memCache) Set(key interface{}, value interface{}, duration time.Duration) { + expireTime := c.getInternalExpire(duration.Nanoseconds() / 1000000) c.dataMu.Lock() c.data[key] = memCacheItem{v: value, e: expireTime} c.dataMu.Unlock() @@ -138,9 +126,8 @@ func (c *memCache) Set(key interface{}, value interface{}, duration interface{}) // // It doubly checks the whether exists in the cache using mutex writing lock // before setting it to the cache. -func (c *memCache) doSetWithLockCheck(key interface{}, value interface{}, duration interface{}) interface{} { - expire := c.getMilliExpire(duration) - expireTimestamp := c.getInternalExpire(expire) +func (c *memCache) doSetWithLockCheck(key interface{}, value interface{}, duration time.Duration) interface{} { + expireTimestamp := c.getInternalExpire(duration.Nanoseconds() / 1000000) c.dataMu.Lock() defer c.dataMu.Unlock() if v, ok := c.data[key]; ok && !v.IsExpired() { @@ -172,10 +159,9 @@ func (c *memCache) getInternalExpire(expire int64) int64 { // The parameter can be either type of int or time.Duration. // If is type of int, it means milliseconds. // If <=0 means it does not expire. -func (c *memCache) SetIfNotExist(key interface{}, value interface{}, duration interface{}) bool { - expire := c.getMilliExpire(duration) +func (c *memCache) SetIfNotExist(key interface{}, value interface{}, duration time.Duration) bool { if !c.Contains(key) { - c.doSetWithLockCheck(key, value, expire) + c.doSetWithLockCheck(key, value, duration) return true } return false @@ -186,9 +172,8 @@ func (c *memCache) SetIfNotExist(key interface{}, value interface{}, duration in // The parameter can be either type of int or time.Duration. // If is type of int, it means milliseconds. // If <=0 means it does not expire. -func (c *memCache) Sets(data map[interface{}]interface{}, duration interface{}) { - expire := c.getMilliExpire(duration) - expireTime := c.getInternalExpire(expire) +func (c *memCache) Sets(data map[interface{}]interface{}, duration time.Duration) { + expireTime := c.getInternalExpire(duration.Nanoseconds() / 1000000) for k, v := range data { c.dataMu.Lock() c.data[k] = memCacheItem{v: v, e: expireTime} @@ -220,7 +205,7 @@ func (c *memCache) Get(key interface{}) interface{} { // The parameter can be either type of int or time.Duration. // If is type of int, it means milliseconds. // If <=0 means it does not expire. -func (c *memCache) GetOrSet(key interface{}, value interface{}, duration interface{}) interface{} { +func (c *memCache) GetOrSet(key interface{}, value interface{}, duration time.Duration) interface{} { if v := c.Get(key); v == nil { return c.doSetWithLockCheck(key, value, duration) } else { @@ -236,7 +221,7 @@ func (c *memCache) GetOrSet(key interface{}, value interface{}, duration interfa // The parameter can be either type of int or time.Duration. // If is type of int, it means milliseconds. // If <=0 means it does not expire. -func (c *memCache) GetOrSetFunc(key interface{}, f func() interface{}, duration interface{}) interface{} { +func (c *memCache) GetOrSetFunc(key interface{}, f func() interface{}, duration time.Duration) interface{} { if v := c.Get(key); v == nil { return c.doSetWithLockCheck(key, f(), duration) } else { @@ -254,7 +239,7 @@ func (c *memCache) GetOrSetFunc(key interface{}, f func() interface{}, duration // If <=0 means it does not expire. // // Note that the function is executed within writing mutex lock. -func (c *memCache) GetOrSetFuncLock(key interface{}, f func() interface{}, duration interface{}) interface{} { +func (c *memCache) GetOrSetFuncLock(key interface{}, f func() interface{}, duration time.Duration) interface{} { if v := c.Get(key); v == nil { return c.doSetWithLockCheck(key, f, duration) } else { diff --git a/os/gcache/gcache_z_unit_1_test.go b/os/gcache/gcache_z_unit_1_test.go index 4005101cd..c2f446b35 100644 --- a/os/gcache/gcache_z_unit_1_test.go +++ b/os/gcache/gcache_z_unit_1_test.go @@ -42,7 +42,7 @@ func TestCache_Set(t *testing.T) { func TestCache_Set_Expire(t *testing.T) { gtest.Case(t, func() { cache := gcache.New() - cache.Set(2, 22, 100) + cache.Set(2, 22, 100*time.Millisecond) gtest.Assert(cache.Get(2), 22) time.Sleep(200 * time.Millisecond) gtest.Assert(cache.Get(2), nil) diff --git a/os/gfcache/gfcache.go b/os/gfcache/gfcache.go index 5f606a005..962f15adb 100644 --- a/os/gfcache/gfcache.go +++ b/os/gfcache/gfcache.go @@ -18,59 +18,48 @@ import ( const ( // Default expire time for file content caching in seconds. - gDEFAULT_CACHE_EXPIRE = 60 + gDEFAULT_CACHE_EXPIRE = time.Minute ) var ( - // Default expire time for file content caching in seconds. - cacheExpire = cmdenv.Get("gf.gfcache.expire", gDEFAULT_CACHE_EXPIRE).Int() * 1000 + // Default expire time for file content caching. + cacheExpire = cmdenv.Get("gf.gfcache.expire", gDEFAULT_CACHE_EXPIRE).Duration() ) // GetContents returns string content of given file by from cache. // If there's no content in the cache, it will read it from disk file specified by . // The parameter specifies the caching time for this file content in seconds. -func GetContents(path string, duration ...interface{}) string { +func GetContents(path string, duration ...time.Duration) string { return string(GetBinContents(path, duration...)) } // GetBinContents returns []byte content of given file by from cache. // If there's no content in the cache, it will read it from disk file specified by . // The parameter specifies the caching time for this file content in seconds. -func GetBinContents(path string, duration ...interface{}) []byte { - k := cacheKey(path) - e := cacheExpire +func GetBinContents(path string, duration ...time.Duration) []byte { + key := cacheKey(path) + expire := cacheExpire if len(duration) > 0 { - e = getSecondExpire(duration[0]) + expire = duration[0] } - r := gcache.GetOrSetFuncLock(k, func() interface{} { + r := gcache.GetOrSetFuncLock(key, func() interface{} { b := gfile.GetBytes(path) if b != nil { // Adding this to gfsnotify, // it will clear its cache if there's any changes of the file. _, _ = gfsnotify.Add(path, func(event *gfsnotify.Event) { - gcache.Remove(k) + gcache.Remove(key) gfsnotify.Exit() }) } return b - }, e*1000) + }, expire) if r != nil { return r.([]byte) } return nil } -// getSecondExpire converts parameter to int type in seconds. -// -// Note that there's some performance cost in type assertion here, but it's valuable. -func getSecondExpire(duration interface{}) int { - if d, ok := duration.(time.Duration); ok { - return int(d.Nanoseconds() / 1000000000) - } else { - return duration.(int) - } -} - // cacheKey produces the cache key for gcache. func cacheKey(path string) string { return "gf.gfcache:" + path