From 0b390912921919df1b75894a9ff06b6b2665cc75 Mon Sep 17 00:00:00 2001 From: JessonChan Date: Wed, 6 Jan 2016 15:05:29 +0800 Subject: [PATCH 1/8] mem cache put function fixed when a expire duration==0,it means forever https://github.com/astaxie/beego/issues/1260 --- cache/memory.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/cache/memory.go b/cache/memory.go index 5cc0ab52..2aea913f 100644 --- a/cache/memory.go +++ b/cache/memory.go @@ -79,6 +79,10 @@ func (bc *MemoryCache) GetMulti(names []string) []interface{} { func (bc *MemoryCache) Put(name string, value interface{}, expired int64) error { bc.lock.Lock() defer bc.lock.Unlock() + if expired == 0 { + //ten years,behave as the file cache + expired = 86400 * 365 * 10 + } bc.items[name] = &MemoryItem{ val: value, Lastaccess: time.Now(), From 8832334d6af275ff936494e7bdfc04d32390e07b Mon Sep 17 00:00:00 2001 From: JessonChan Date: Wed, 6 Jan 2016 15:12:25 +0800 Subject: [PATCH 2/8] tiny fix for error description and comment --- cache/memory.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/cache/memory.go b/cache/memory.go index 2aea913f..1fe82fd6 100644 --- a/cache/memory.go +++ b/cache/memory.go @@ -106,7 +106,7 @@ func (bc *MemoryCache) Delete(name string) error { } // Incr increase cache counter in memory. -// it supports int,int64,int32,uint,uint64,uint32. +// it supports int,int32,int64,uint,uint32,uint64. func (bc *MemoryCache) Incr(key string) error { bc.lock.RLock() defer bc.lock.RUnlock() @@ -117,10 +117,10 @@ func (bc *MemoryCache) Incr(key string) error { switch itm.val.(type) { case int: itm.val = itm.val.(int) + 1 - case int64: - itm.val = itm.val.(int64) + 1 case int32: itm.val = itm.val.(int32) + 1 + case int64: + itm.val = itm.val.(int64) + 1 case uint: itm.val = itm.val.(uint) + 1 case uint32: @@ -128,7 +128,7 @@ func (bc *MemoryCache) Incr(key string) error { case uint64: itm.val = itm.val.(uint64) + 1 default: - return errors.New("item val is not int int64 int32") + return errors.New("item val is not (u)int (u)int32 (u)int64") } return nil } From eff200e014eb0072c9acad8ec06f13b6aa7bd4a9 Mon Sep 17 00:00:00 2001 From: JessonChan Date: Thu, 7 Jan 2016 09:08:00 +0800 Subject: [PATCH 3/8] modify as xuxiaohei suggest https://github.com/astaxie/beego/issues/1259 --- cache/memory.go | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/cache/memory.go b/cache/memory.go index 1fe82fd6..67a38892 100644 --- a/cache/memory.go +++ b/cache/memory.go @@ -37,7 +37,7 @@ type MemoryItem struct { // MemoryCache is Memory cache adapter. // it contains a RW locker for safe map storage. type MemoryCache struct { - lock sync.RWMutex + sync.RWMutex dur time.Duration items map[string]*MemoryItem Every int // run an expiration check Every clock time @@ -52,8 +52,8 @@ func NewMemoryCache() Cache { // Get cache from memory. // if non-existed or expired, return nil. func (bc *MemoryCache) Get(name string) interface{} { - bc.lock.RLock() - defer bc.lock.RUnlock() + bc.RLock() + defer bc.RUnlock() if itm, ok := bc.items[name]; ok { if (time.Now().Unix() - itm.Lastaccess.Unix()) > itm.expired { go bc.Delete(name) @@ -77,12 +77,8 @@ func (bc *MemoryCache) GetMulti(names []string) []interface{} { // Put cache to memory. // if expired is 0, it will be cleaned by next gc operation ( default gc clock is 1 minute). func (bc *MemoryCache) Put(name string, value interface{}, expired int64) error { - bc.lock.Lock() - defer bc.lock.Unlock() - if expired == 0 { - //ten years,behave as the file cache - expired = 86400 * 365 * 10 - } + bc.Lock() + defer bc.Unlock() bc.items[name] = &MemoryItem{ val: value, Lastaccess: time.Now(), @@ -93,8 +89,8 @@ func (bc *MemoryCache) Put(name string, value interface{}, expired int64) error // Delete cache in memory. func (bc *MemoryCache) Delete(name string) error { - bc.lock.Lock() - defer bc.lock.Unlock() + bc.Lock() + defer bc.Unlock() if _, ok := bc.items[name]; !ok { return errors.New("key not exist") } @@ -108,8 +104,8 @@ func (bc *MemoryCache) Delete(name string) error { // Incr increase cache counter in memory. // it supports int,int32,int64,uint,uint32,uint64. func (bc *MemoryCache) Incr(key string) error { - bc.lock.RLock() - defer bc.lock.RUnlock() + bc.RLock() + defer bc.RUnlock() itm, ok := bc.items[key] if !ok { return errors.New("key not exist") @@ -135,8 +131,8 @@ func (bc *MemoryCache) Incr(key string) error { // Decr decrease counter in memory. func (bc *MemoryCache) Decr(key string) error { - bc.lock.RLock() - defer bc.lock.RUnlock() + bc.RLock() + defer bc.RUnlock() itm, ok := bc.items[key] if !ok { return errors.New("key not exist") @@ -174,16 +170,16 @@ func (bc *MemoryCache) Decr(key string) error { // IsExist check cache exist in memory. func (bc *MemoryCache) IsExist(name string) bool { - bc.lock.RLock() - defer bc.lock.RUnlock() + bc.RLock() + defer bc.RUnlock() _, ok := bc.items[name] return ok } // ClearAll will delete all cache in memory. func (bc *MemoryCache) ClearAll() error { - bc.lock.Lock() - defer bc.lock.Unlock() + bc.Lock() + defer bc.Unlock() bc.items = make(map[string]*MemoryItem) return nil } @@ -224,12 +220,16 @@ func (bc *MemoryCache) vaccuum() { // itemExpired returns true if an item is expired. func (bc *MemoryCache) itemExpired(name string) bool { - bc.lock.Lock() - defer bc.lock.Unlock() + bc.Lock() + defer bc.Unlock() itm, ok := bc.items[name] if !ok { return true } + // expired==0 means never + if itm.expired==0{ + return false + } if time.Now().Unix()-itm.Lastaccess.Unix() >= itm.expired { delete(bc.items, name) return true From b0b9812de6c4af7de825ae2770a007a67452c765 Mon Sep 17 00:00:00 2001 From: JessonChan Date: Thu, 7 Jan 2016 09:13:47 +0800 Subject: [PATCH 4/8] extract a expire fun --- cache/memory.go | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/cache/memory.go b/cache/memory.go index 67a38892..2ad1da06 100644 --- a/cache/memory.go +++ b/cache/memory.go @@ -34,6 +34,14 @@ type MemoryItem struct { expired int64 } +func (mi *MemoryItem) isExpire() bool { + // expired==0 means never + if mi.expired == 0 { + return false + } + return time.Now().Unix()-mi.Lastaccess.Unix() > mi.expired +} + // MemoryCache is Memory cache adapter. // it contains a RW locker for safe map storage. type MemoryCache struct { @@ -55,7 +63,7 @@ func (bc *MemoryCache) Get(name string) interface{} { bc.RLock() defer bc.RUnlock() if itm, ok := bc.items[name]; ok { - if (time.Now().Unix() - itm.Lastaccess.Unix()) > itm.expired { + if itm.isExpire() { go bc.Delete(name) return nil } @@ -222,15 +230,12 @@ func (bc *MemoryCache) vaccuum() { func (bc *MemoryCache) itemExpired(name string) bool { bc.Lock() defer bc.Unlock() + itm, ok := bc.items[name] if !ok { return true } - // expired==0 means never - if itm.expired==0{ - return false - } - if time.Now().Unix()-itm.Lastaccess.Unix() >= itm.expired { + if itm.isExpire() { delete(bc.items, name) return true } From 98e0626f0cee373a7924edd698c84d4cb2d8e5f3 Mon Sep 17 00:00:00 2001 From: JessonChan Date: Thu, 7 Jan 2016 09:25:06 +0800 Subject: [PATCH 5/8] rename vals --- cache/memory.go | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/cache/memory.go b/cache/memory.go index 2ad1da06..4980b9aa 100644 --- a/cache/memory.go +++ b/cache/memory.go @@ -30,16 +30,16 @@ var ( // MemoryItem store enery cache item. type MemoryItem struct { val interface{} - Lastaccess time.Time - expired int64 + cratedTime time.Time + lifespan int64 } func (mi *MemoryItem) isExpire() bool { - // expired==0 means never - if mi.expired == 0 { + // 0 means forever + if mi.lifespan == 0 { return false } - return time.Now().Unix()-mi.Lastaccess.Unix() > mi.expired + return time.Now().Unix()-mi.cratedTime.Unix() > mi.lifespan } // MemoryCache is Memory cache adapter. @@ -89,8 +89,8 @@ func (bc *MemoryCache) Put(name string, value interface{}, expired int64) error defer bc.Unlock() bc.items[name] = &MemoryItem{ val: value, - Lastaccess: time.Now(), - expired: expired, + cratedTime: time.Now(), + lifespan: expired, } return nil } From 6465dbd703deb2924216fa68cdca3d90eed6ea34 Mon Sep 17 00:00:00 2001 From: JessonChan Date: Thu, 7 Jan 2016 09:28:40 +0800 Subject: [PATCH 6/8] no more goroutine ,i will be GCed at a gc goroutine --- cache/memory.go | 1 - 1 file changed, 1 deletion(-) diff --git a/cache/memory.go b/cache/memory.go index 4980b9aa..44aaf89a 100644 --- a/cache/memory.go +++ b/cache/memory.go @@ -64,7 +64,6 @@ func (bc *MemoryCache) Get(name string) interface{} { defer bc.RUnlock() if itm, ok := bc.items[name]; ok { if itm.isExpire() { - go bc.Delete(name) return nil } return itm.val From 8aed4c13d7c0e6e49598689c2cf1ab7583c67922 Mon Sep 17 00:00:00 2001 From: JessonChan Date: Thu, 7 Jan 2016 09:36:23 +0800 Subject: [PATCH 7/8] isExist func will check if the value is expired --- cache/memory.go | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/cache/memory.go b/cache/memory.go index 44aaf89a..b31eb84d 100644 --- a/cache/memory.go +++ b/cache/memory.go @@ -82,14 +82,14 @@ func (bc *MemoryCache) GetMulti(names []string) []interface{} { } // Put cache to memory. -// if expired is 0, it will be cleaned by next gc operation ( default gc clock is 1 minute). -func (bc *MemoryCache) Put(name string, value interface{}, expired int64) error { +// if lifespan is 0, it will be forever till restart. +func (bc *MemoryCache) Put(name string, value interface{}, lifespan int64) error { bc.Lock() defer bc.Unlock() bc.items[name] = &MemoryItem{ val: value, cratedTime: time.Now(), - lifespan: expired, + lifespan: lifespan, } return nil } @@ -179,8 +179,10 @@ func (bc *MemoryCache) Decr(key string) error { func (bc *MemoryCache) IsExist(name string) bool { bc.RLock() defer bc.RUnlock() - _, ok := bc.items[name] - return ok + if v, ok := bc.items[name]; ok { + return !v.isExpire() + } + return false } // ClearAll will delete all cache in memory. From 3821b2cb269085f7ac4489c8594b0636fd12d4db Mon Sep 17 00:00:00 2001 From: JessonChan Date: Thu, 7 Jan 2016 09:37:50 +0800 Subject: [PATCH 8/8] createdTime typo fixed --- cache/memory.go | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/cache/memory.go b/cache/memory.go index b31eb84d..f8cccb14 100644 --- a/cache/memory.go +++ b/cache/memory.go @@ -27,11 +27,11 @@ var ( DefaultEvery = 60 // 1 minute ) -// MemoryItem store enery cache item. +// MemoryItem store memory cache item. type MemoryItem struct { - val interface{} - cratedTime time.Time - lifespan int64 + val interface{} + createdTime time.Time + lifespan int64 } func (mi *MemoryItem) isExpire() bool { @@ -39,7 +39,7 @@ func (mi *MemoryItem) isExpire() bool { if mi.lifespan == 0 { return false } - return time.Now().Unix()-mi.cratedTime.Unix() > mi.lifespan + return time.Now().Unix()-mi.createdTime.Unix() > mi.lifespan } // MemoryCache is Memory cache adapter. @@ -88,7 +88,7 @@ func (bc *MemoryCache) Put(name string, value interface{}, lifespan int64) error defer bc.Unlock() bc.items[name] = &MemoryItem{ val: value, - cratedTime: time.Now(), + createdTime: time.Now(), lifespan: lifespan, } return nil