1
0
mirror of https://github.com/astaxie/beego.git synced 2024-11-25 18:20:55 +00:00
cache add function
// IncrBy increase counter by num.
IncrBy(key string, num int)
// DecrBy decrease counter by num.
DecrBy(key string, num int)
This commit is contained in:
hible 2018-07-31 17:19:09 +08:00
parent a09bafbf2a
commit c7c0b01ec5
10 changed files with 284 additions and 1 deletions

4
cache/cache.go vendored
View File

@ -59,6 +59,10 @@ type Cache interface {
Incr(key string) error Incr(key string) error
// decrease cached int value by key, as a counter. // decrease cached int value by key, as a counter.
Decr(key string) error Decr(key string) error
// increase cached with int value by key, as a counter.
IncrBy(key string, num int) error
// decrease cached with int value by key, as a counter.
DecrBy(key string, num int) error
// check if cached value exists or not. // check if cached value exists or not.
IsExist(key string) bool IsExist(key string) bool
// clear all cache. // clear all cache.

36
cache/cache_test.go vendored
View File

@ -37,7 +37,7 @@ func TestCache(t *testing.T) {
t.Error("get err") t.Error("get err")
} }
time.Sleep(30 * time.Second) time.Sleep(10 * time.Second)
if bm.IsExist("astaxie") { if bm.IsExist("astaxie") {
t.Error("check err") t.Error("check err")
@ -55,6 +55,22 @@ func TestCache(t *testing.T) {
t.Error("get err") t.Error("get err")
} }
if err = bm.IncrBy("astaxie", 2); err != nil {
t.Error("Incr Error", err)
}
if v := bm.Get("astaxie"); v.(int) != 4 {
t.Error("get err")
}
if err = bm.DecrBy("astaxie", 2); err != nil {
t.Error("Decr Error", err)
}
if v := bm.Get("astaxie"); v.(int) != 2 {
t.Error("get err")
}
if err = bm.Decr("astaxie"); err != nil { if err = bm.Decr("astaxie"); err != nil {
t.Error("Decr Error", err) t.Error("Decr Error", err)
} }
@ -62,6 +78,7 @@ func TestCache(t *testing.T) {
if v := bm.Get("astaxie"); v.(int) != 1 { if v := bm.Get("astaxie"); v.(int) != 1 {
t.Error("get err") t.Error("get err")
} }
bm.Delete("astaxie") bm.Delete("astaxie")
if bm.IsExist("astaxie") { if bm.IsExist("astaxie") {
t.Error("delete err") t.Error("delete err")
@ -122,6 +139,22 @@ func TestFileCache(t *testing.T) {
t.Error("get err") t.Error("get err")
} }
if err = bm.IncrBy("astaxie", 2); err != nil {
t.Error("Incr Error", err)
}
if v := bm.Get("astaxie"); v.(int) != 4 {
t.Error("get err")
}
if err = bm.DecrBy("astaxie", 2); err != nil {
t.Error("Decr Error", err)
}
if v := bm.Get("astaxie"); v.(int) != 2 {
t.Error("get err")
}
if err = bm.Decr("astaxie"); err != nil { if err = bm.Decr("astaxie"); err != nil {
t.Error("Decr Error", err) t.Error("Decr Error", err)
} }
@ -129,6 +162,7 @@ func TestFileCache(t *testing.T) {
if v := bm.Get("astaxie"); v.(int) != 1 { if v := bm.Get("astaxie"); v.(int) != 1 {
t.Error("get err") t.Error("get err")
} }
bm.Delete("astaxie") bm.Delete("astaxie")
if bm.IsExist("astaxie") { if bm.IsExist("astaxie") {
t.Error("delete err") t.Error("delete err")

36
cache/file.go vendored
View File

@ -20,6 +20,7 @@ import (
"encoding/gob" "encoding/gob"
"encoding/hex" "encoding/hex"
"encoding/json" "encoding/json"
"errors"
"fmt" "fmt"
"io" "io"
"io/ioutil" "io/ioutil"
@ -183,6 +184,24 @@ func (fc *FileCache) Incr(key string) error {
return nil return nil
} }
// IncrBy will increase cached int value by num.
// fc value is saving forever unless Delete.
func (fc *FileCache) IncrBy(key string, num int) error {
if num < 1 {
return errors.New("increase num should be a positive number")
}
data := fc.Get(key)
var incr int
if reflect.TypeOf(data).Name() != "int" {
incr = 0
} else {
incr = data.(int) + int(num)
}
fc.Put(key, incr, FileCacheEmbedExpiry)
return nil
}
// Decr will decrease cached int value. // Decr will decrease cached int value.
func (fc *FileCache) Decr(key string) error { func (fc *FileCache) Decr(key string) error {
data := fc.Get(key) data := fc.Get(key)
@ -196,6 +215,23 @@ func (fc *FileCache) Decr(key string) error {
return nil return nil
} }
// DecrBy will decrease cached int value.
func (fc *FileCache) DecrBy(key string, num int) error {
if num < 1 {
return errors.New("decrease num should be a positive number")
}
data := fc.Get(key)
var decr int
if reflect.TypeOf(data).Name() != "int" || data.(int)-1 <= 0 {
decr = 0
} else {
decr = data.(int) - int(num)
}
fc.Put(key, decr, FileCacheEmbedExpiry)
return nil
}
// IsExist check value is exist. // IsExist check value is exist.
func (fc *FileCache) IsExist(key string) bool { func (fc *FileCache) IsExist(key string) bool {
ret, _ := exists(fc.getCacheFileName(key)) ret, _ := exists(fc.getCacheFileName(key))

View File

@ -127,6 +127,21 @@ func (rc *Cache) Incr(key string) error {
return err return err
} }
// IncrBy increase counter by num.
func (rc *Cache) IncrBy(key string, num int) error {
if num < 1 {
return errors.New("increase num should be a positive number")
}
if rc.conn == nil {
if err := rc.connectInit(); err != nil {
return err
}
}
_, err := rc.conn.Increment(key, uint64(num))
return err
}
// Decr decrease counter. // Decr decrease counter.
func (rc *Cache) Decr(key string) error { func (rc *Cache) Decr(key string) error {
if rc.conn == nil { if rc.conn == nil {
@ -138,6 +153,21 @@ func (rc *Cache) Decr(key string) error {
return err return err
} }
// DecrBy decrease counter by num.
func (rc *Cache) DecrBy(key string, num int) error {
if num < 1 {
return errors.New("decrease num should be a positive number")
}
if rc.conn == nil {
if err := rc.connectInit(); err != nil {
return err
}
}
_, err := rc.conn.Decrement(key, uint64(num))
return err
}
// IsExist check value exists in memcache. // IsExist check value exists in memcache.
func (rc *Cache) IsExist(key string) bool { func (rc *Cache) IsExist(key string) bool {
if rc.conn == nil { if rc.conn == nil {

View File

@ -58,6 +58,22 @@ func TestMemcacheCache(t *testing.T) {
t.Error("get err") t.Error("get err")
} }
if err = bm.IncrBy("astaxie", 2); err != nil {
t.Error("Incr Error", err)
}
if v, err := strconv.Atoi(string(bm.Get("astaxie").([]byte))); err != nil || v != 4 {
t.Error("get err")
}
if err = bm.DecrBy("astaxie", 2); err != nil {
t.Error("Decr Error", err)
}
if v, err := strconv.Atoi(string(bm.Get("astaxie").([]byte))); err != nil || v != 2 {
t.Error("get err")
}
if err = bm.Decr("astaxie"); err != nil { if err = bm.Decr("astaxie"); err != nil {
t.Error("Decr Error", err) t.Error("Decr Error", err)
} }
@ -65,6 +81,7 @@ func TestMemcacheCache(t *testing.T) {
if v, err := strconv.Atoi(string(bm.Get("astaxie").([]byte))); err != nil || v != 1 { if v, err := strconv.Atoi(string(bm.Get("astaxie").([]byte))); err != nil || v != 1 {
t.Error("get err") t.Error("get err")
} }
bm.Delete("astaxie") bm.Delete("astaxie")
if bm.IsExist("astaxie") { if bm.IsExist("astaxie") {
t.Error("delete err") t.Error("delete err")

77
cache/memory.go vendored
View File

@ -135,6 +135,39 @@ func (bc *MemoryCache) Incr(key string) error {
return nil return nil
} }
// IncrBy increase cache counter in memory by num.
// it supports int,int32,int64,uint,uint32,uint64.
func (bc *MemoryCache) IncrBy(key string, num int) error {
bc.RLock()
defer bc.RUnlock()
itm, ok := bc.items[key]
if !ok {
return errors.New("key not exist")
}
if num < 1 {
return errors.New("increase num should be a positive number")
}
switch itm.val.(type) {
case int:
itm.val = itm.val.(int) + num
case int32:
itm.val = itm.val.(int32) + int32(num)
case int64:
itm.val = itm.val.(int64) + int64(num)
case uint:
itm.val = itm.val.(uint) + uint(num)
case uint32:
itm.val = itm.val.(uint32) + uint32(num)
case uint64:
itm.val = itm.val.(uint64) + uint64(num)
default:
return errors.New("item val is not (u)int (u)int32 (u)int64")
}
return nil
}
// Decr decrease counter in memory. // Decr decrease counter in memory.
func (bc *MemoryCache) Decr(key string) error { func (bc *MemoryCache) Decr(key string) error {
bc.RLock() bc.RLock()
@ -174,6 +207,50 @@ func (bc *MemoryCache) Decr(key string) error {
return nil return nil
} }
// DecrBy decrease counter in memory by num.
func (bc *MemoryCache) DecrBy(key string, num int) error {
bc.RLock()
defer bc.RUnlock()
itm, ok := bc.items[key]
if !ok {
return errors.New("key not exist")
}
if num < 1 {
return errors.New("decrease num should be a positive number")
}
switch itm.val.(type) {
case int:
itm.val = itm.val.(int) - int(num)
case int64:
itm.val = itm.val.(int64) - int64(num)
case int32:
itm.val = itm.val.(int32) - int32(num)
case uint:
if itm.val.(uint) > 0 {
itm.val = itm.val.(uint) - uint(num)
} else {
return errors.New("item val is less than 0")
}
case uint32:
if itm.val.(uint32) > 0 {
itm.val = itm.val.(uint32) - uint32(num)
} else {
return errors.New("item val is less than 0")
}
case uint64:
if itm.val.(uint64) > 0 {
itm.val = itm.val.(uint64) - uint64(num)
} else {
return errors.New("item val is less than 0")
}
default:
return errors.New("item val is not int int64 int32")
}
return nil
}
// IsExist check cache exist in memory. // IsExist check cache exist in memory.
func (bc *MemoryCache) IsExist(name string) bool { func (bc *MemoryCache) IsExist(name string) bool {
bc.RLock() bc.RLock()

18
cache/redis/redis.go vendored
View File

@ -128,12 +128,30 @@ func (rc *Cache) Incr(key string) error {
return err return err
} }
// IncrBy increase counter in redis by num.
func (rc *Cache) IncrBy(key string, num int) error {
if num < 1 {
return errors.New("increase num should be a positive number")
}
_, err := redis.Bool(rc.do("INCRBY", key, num))
return err
}
// Decr decrease counter in redis. // Decr decrease counter in redis.
func (rc *Cache) Decr(key string) error { func (rc *Cache) Decr(key string) error {
_, err := redis.Bool(rc.do("INCRBY", key, -1)) _, err := redis.Bool(rc.do("INCRBY", key, -1))
return err return err
} }
// DecrBy decrease counter in redis by num.
func (rc *Cache) DecrBy(key string, num int) error {
if num < 1 {
return errors.New("decrease num should be a positive number")
}
_, err := redis.Bool(rc.do("DECRBY", key, num))
return err
}
// ClearAll clean all cache in redis. delete this redis collection. // ClearAll clean all cache in redis. delete this redis collection.
func (rc *Cache) ClearAll() error { func (rc *Cache) ClearAll() error {
c := rc.p.Get() c := rc.p.Get()

View File

@ -56,6 +56,22 @@ func TestRedisCache(t *testing.T) {
t.Error("get err") t.Error("get err")
} }
if err = bm.IncrBy("astaxie", 2); err != nil {
t.Error("Incr Error", err)
}
if v, _ := redis.Int(bm.Get("astaxie"), err); v != 4 {
t.Error("get err")
}
if err = bm.DecrBy("astaxie", 2); err != nil {
t.Error("Decr Error", err)
}
if v, _ := redis.Int(bm.Get("astaxie"), err); v != 2 {
t.Error("get err")
}
if err = bm.Decr("astaxie"); err != nil { if err = bm.Decr("astaxie"); err != nil {
t.Error("Decr Error", err) t.Error("Decr Error", err)
} }
@ -63,6 +79,7 @@ func TestRedisCache(t *testing.T) {
if v, _ := redis.Int(bm.Get("astaxie"), err); v != 1 { if v, _ := redis.Int(bm.Get("astaxie"), err); v != 1 {
t.Error("get err") t.Error("get err")
} }
bm.Delete("astaxie") bm.Delete("astaxie")
if bm.IsExist("astaxie") { if bm.IsExist("astaxie") {
t.Error("delete err") t.Error("delete err")

29
cache/ssdb/ssdb.go vendored
View File

@ -124,6 +124,20 @@ func (rc *Cache) Incr(key string) error {
return err return err
} }
// IncrBy increase counter by num.
func (rc *Cache) IncrBy(key string, num int) error {
if num < 1 {
return errors.New("increase num should be a positive number")
}
if rc.conn == nil {
if err := rc.connectInit(); err != nil {
return err
}
}
_, err := rc.conn.Do("incr", key, num)
return err
}
// Decr decrease counter. // Decr decrease counter.
func (rc *Cache) Decr(key string) error { func (rc *Cache) Decr(key string) error {
if rc.conn == nil { if rc.conn == nil {
@ -135,6 +149,21 @@ func (rc *Cache) Decr(key string) error {
return err return err
} }
// DecrBy decrease counter by num.
func (rc *Cache) DecrBy(key string, num int) error {
if num < 1 {
return errors.New("decrease num should be a positive number")
}
if rc.conn == nil {
if err := rc.connectInit(); err != nil {
return err
}
}
_, err := rc.conn.Do("incr", key, -num)
return err
}
// IsExist check value exists in memcache. // IsExist check value exists in memcache.
func (rc *Cache) IsExist(key string) bool { func (rc *Cache) IsExist(key string) bool {
if rc.conn == nil { if rc.conn == nil {

View File

@ -40,6 +40,7 @@ func TestSsdbcacheCache(t *testing.T) {
if err = ssdb.Put("ssdb", "2", timeoutDuration); err != nil { if err = ssdb.Put("ssdb", "2", timeoutDuration); err != nil {
t.Error("set Error", err) t.Error("set Error", err)
} }
if err = ssdb.Incr("ssdb"); err != nil { if err = ssdb.Incr("ssdb"); err != nil {
t.Error("incr Error", err) t.Error("incr Error", err)
} }
@ -48,10 +49,30 @@ func TestSsdbcacheCache(t *testing.T) {
t.Error("get err") t.Error("get err")
} }
if err = ssdb.IncrBy("ssdb", 2); err != nil {
t.Error("incr Error", err)
}
if v, err := strconv.Atoi(ssdb.Get("ssdb").(string)); err != nil || v != 5 {
t.Error("get err")
}
if err = ssdb.DecrBy("ssdb", 2); err != nil {
t.Error("decr error")
}
if v, err := strconv.Atoi(ssdb.Get("ssdb").(string)); err != nil || v != 3 {
t.Error("get err")
}
if err = ssdb.Decr("ssdb"); err != nil { if err = ssdb.Decr("ssdb"); err != nil {
t.Error("decr error") t.Error("decr error")
} }
if v, err := strconv.Atoi(ssdb.Get("ssdb").(string)); err != nil || v != 2 {
t.Error("get err")
}
// test del // test del
if err = ssdb.Put("ssdb", "3", timeoutDuration); err != nil { if err = ssdb.Put("ssdb", "3", timeoutDuration); err != nil {
t.Error("set Error", err) t.Error("set Error", err)