diff --git a/cache/cache.go b/cache/cache.go index 1e91248a..4771750d 100644 --- a/cache/cache.go +++ b/cache/cache.go @@ -8,6 +8,8 @@ type Cache interface { Get(key string) interface{} Put(key string, val interface{}, timeout int64) error Delete(key string) error + Incr(key string) error + Decr(key string) error IsExist(key string) bool ClearAll() error StartAndGC(config string) error diff --git a/cache/cache_test.go b/cache/cache_test.go index 4183fbc0..cb0fc76c 100644 --- a/cache/cache_test.go +++ b/cache/cache_test.go @@ -31,6 +31,21 @@ func Test_cache(t *testing.T) { t.Error("set Error", err) } + if err = bm.Incr("astaxie"); err != nil { + t.Error("Incr Error", err) + } + + if v := bm.Get("astaxie"); v.(int) != 2 { + t.Error("get err") + } + + if err = bm.Decr("astaxie"); err != nil { + t.Error("Incr Error", err) + } + + if v := bm.Get("astaxie"); v.(int) != 1 { + t.Error("get err") + } bm.Delete("astaxie") if bm.IsExist("astaxie") { t.Error("delete err") diff --git a/cache/memcache.go b/cache/memcache.go index 331f1e0c..5a0bc4ed 100644 --- a/cache/memcache.go +++ b/cache/memcache.go @@ -51,6 +51,14 @@ func (rc *MemcacheCache) Delete(key string) error { return err } +func (rc *MemcacheCache) Incr(key string) error { + return errors.New("not support in memcache") +} + +func (rc *MemcacheCache) Decr(key string) error { + return errors.New("not support in memcache") +} + func (rc *MemcacheCache) IsExist(key string) bool { if rc.c == nil { rc.c = rc.connectInit() diff --git a/cache/memory.go b/cache/memory.go index fd1536cb..7889d099 100644 --- a/cache/memory.go +++ b/cache/memory.go @@ -75,6 +75,70 @@ func (bc *MemoryCache) Delete(name string) error { return nil } +func (bc *MemoryCache) Incr(key string) error { + bc.lock.RLock() + defer bc.lock.RUnlock() + itm, ok := bc.items[key] + if !ok { + return errors.New("key not exist") + } + 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 uint: + itm.val = itm.val.(uint) + 1 + case uint32: + itm.val = itm.val.(uint32) + 1 + case uint64: + itm.val = itm.val.(uint64) + 1 + default: + return errors.New("item val is not int int64 int32") + } + return nil +} + +func (bc *MemoryCache) Decr(key string) error { + bc.lock.RLock() + defer bc.lock.RUnlock() + itm, ok := bc.items[key] + if !ok { + return errors.New("key not exist") + } + 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 uint: + if itm.val.(uint) > 0 { + itm.val = itm.val.(uint) - 1 + } else { + return errors.New("item val is less than 0") + } + case uint32: + if itm.val.(uint32) > 0 { + itm.val = itm.val.(uint32) - 1 + } else { + return errors.New("item val is less than 0") + } + case uint64: + if itm.val.(uint64) > 0 { + itm.val = itm.val.(uint64) - 1 + } else { + return errors.New("item val is less than 0") + } + default: + return errors.New("item val is not int int64 int32") + } + return nil +} + func (bc *MemoryCache) IsExist(name string) bool { bc.lock.RLock() defer bc.lock.RUnlock() diff --git a/cache/redis.go b/cache/redis.go index 2b01c82a..db6ed923 100644 --- a/cache/redis.go +++ b/cache/redis.go @@ -58,6 +58,28 @@ func (rc *RedisCache) IsExist(key string) bool { return v } +func (rc *RedisCache) Incr(key string) error { + if rc.c == nil { + rc.c = rc.connectInit() + } + _, err := redis.Bool(rc.c.Do("HINCRBY", rc.key, key, 1)) + if err != nil { + return err + } + return nil +} + +func (rc *RedisCache) Decr(key string) error { + if rc.c == nil { + rc.c = rc.connectInit() + } + _, err := redis.Bool(rc.c.Do("HINCRBY", rc.key, key, -1)) + if err != nil { + return err + } + return nil +} + func (rc *RedisCache) ClearAll() error { if rc.c == nil { rc.c = rc.connectInit()