From 4b10cda1d69c250026a62d4fed1fb8d0de241bbc Mon Sep 17 00:00:00 2001 From: AllenX2018 Date: Sat, 12 Dec 2020 17:50:36 +0800 Subject: [PATCH] add utils of incr&decr for cache --- client/cache/calc_utils.go | 83 ++++++++++++++++++++++++++++++++++++++ client/cache/file.go | 54 ++++--------------------- client/cache/memory.go | 52 +++++------------------- 3 files changed, 101 insertions(+), 88 deletions(-) create mode 100644 client/cache/calc_utils.go diff --git a/client/cache/calc_utils.go b/client/cache/calc_utils.go new file mode 100644 index 00000000..b0e68dfe --- /dev/null +++ b/client/cache/calc_utils.go @@ -0,0 +1,83 @@ +package cache + +import ( + "fmt" + "math" +) + +func incr(originVal interface{}) (interface{}, error) { + switch val := originVal.(type) { + case int: + tmp := val + 1 + if val > 0 && tmp < 0 { + return nil, fmt.Errorf("increment would overflow") + } + return tmp, nil + case int32: + if val == math.MaxInt32 { + return nil, fmt.Errorf("increment would overflow") + } + return val + 1, nil + case int64: + // if val == math.MaxInt64 { + // return nil, fmt.Errorf("increment would overflow") + // } + return val + 1, nil + case uint: + tmp := val + 1 + if tmp < val { + return nil, fmt.Errorf("increment would overflow") + } + return tmp, nil + case uint32: + if val == math.MaxUint32 { + return nil, fmt.Errorf("increment would overflow") + } + return val + 1, nil + case uint64: + if val == math.MaxUint64 { + return nil, fmt.Errorf("increment would overflow") + } + return val + 1, nil + default: + return nil, fmt.Errorf("item val is not (u)int (u)int32 (u)int64") + } +} + +func decr(originVal interface{}) (interface{}, error) { + switch val := originVal.(type) { + case int: + tmp := val - 1 + if val < 0 && tmp > 0 { + return nil, fmt.Errorf("decrement would overflow") + } + return tmp, nil + case int32: + if val == math.MinInt32 { + return nil, fmt.Errorf("decrement would overflow") + } + return val - 1, nil + case int64: + if val == math.MinInt64 { + return nil, fmt.Errorf("decrement would overflow") + } + return val - 1, nil + case uint: + if val == 0 { + return nil, fmt.Errorf("decrement would overflow") + } + return val - 1, nil + case uint32: + if val == 0 { + return nil, fmt.Errorf("increment would overflow") + } + return val - 1, nil + case uint64: + if val == 0 { + return nil, fmt.Errorf("increment would overflow") + } + return val - 1, nil + default: + return nil, fmt.Errorf("item val is not (u)int (u)int32 (u)int64") + } +} \ No newline at end of file diff --git a/client/cache/file.go b/client/cache/file.go index 043c4650..87e14b6c 100644 --- a/client/cache/file.go +++ b/client/cache/file.go @@ -199,25 +199,12 @@ func (fc *FileCache) Incr(ctx context.Context, key string) error { return err } - var res interface{} - switch val := data.(type) { - case int: - res = val + 1 - case int32: - res = val + 1 - case int64: - res = val + 1 - case uint: - res = val + 1 - case uint32: - res = val + 1 - case uint64: - res = val + 1 - default: - return errors.Errorf("data is not (u)int (u)int32 (u)int64") + val, err := incr(data) + if err != nil { + return err } - return fc.Put(context.Background(), key, res, time.Duration(fc.EmbedExpiry)) + return fc.Put(context.Background(), key, val, time.Duration(fc.EmbedExpiry)) } // Decr decreases cached int value. @@ -227,37 +214,12 @@ func (fc *FileCache) Decr(ctx context.Context, key string) error { return err } - var res interface{} - switch val := data.(type) { - case int: - res = val - 1 - case int32: - res = val - 1 - case int64: - res = val - 1 - case uint: - if val > 0 { - res = val - 1 - } else { - return errors.New("data val is less than 0") - } - case uint32: - if val > 0 { - res = val - 1 - } else { - return errors.New("data val is less than 0") - } - case uint64: - if val > 0 { - res = val - 1 - } else { - return errors.New("data val is less than 0") - } - default: - return errors.Errorf("data is not (u)int (u)int32 (u)int64") + val, err := decr(data) + if err != nil { + return err } - return fc.Put(context.Background(), key, res, time.Duration(fc.EmbedExpiry)) + return fc.Put(context.Background(), key, val, time.Duration(fc.EmbedExpiry)) } // IsExist checks if value exists. diff --git a/client/cache/memory.go b/client/cache/memory.go index 28c7d980..850326ad 100644 --- a/client/cache/memory.go +++ b/client/cache/memory.go @@ -130,22 +130,12 @@ func (bc *MemoryCache) Incr(ctx context.Context, key string) error { if !ok { return errors.New("key not exist") } - switch val := itm.val.(type) { - case int: - itm.val = val + 1 - case int32: - itm.val = val + 1 - case int64: - itm.val = val + 1 - case uint: - itm.val = val + 1 - case uint32: - itm.val = val + 1 - case uint64: - itm.val = val + 1 - default: - return errors.New("item val is not (u)int (u)int32 (u)int64") + + val, err := incr(itm.val) + if err != nil { + return err } + itm.val = val return nil } @@ -157,34 +147,12 @@ func (bc *MemoryCache) Decr(ctx context.Context, key string) error { if !ok { return errors.New("key not exist") } - switch val := itm.val.(type) { - case int: - itm.val = val - 1 - case int64: - itm.val = val - 1 - case int32: - itm.val = val - 1 - case uint: - if val > 0 { - itm.val = val - 1 - } else { - return errors.New("item val is less than 0") - } - case uint32: - if val > 0 { - itm.val = val - 1 - } else { - return errors.New("item val is less than 0") - } - case uint64: - if val > 0 { - itm.val = val - 1 - } else { - return errors.New("item val is less than 0") - } - default: - return errors.New("item val is not int int64 int32") + + val, err := decr(itm.val) + if err != nil { + return err } + itm.val = val return nil }