323 lines
8.8 KiB
Go
323 lines
8.8 KiB
Go
package cache
|
|
|
|
import (
|
|
"errors"
|
|
"reflect"
|
|
"strconv"
|
|
"time"
|
|
)
|
|
|
|
/*
|
|
输出时间为-1或者time类型为IsZero()表示永不过期
|
|
*/
|
|
|
|
// Get 获取数据
|
|
// key: 键 返回值: 数据 剩余时间 是否存在
|
|
func (c *Cache[K, V]) Get(key K) (V, int64, bool) {
|
|
if dataAny, ok := c.data.Load(key); ok {
|
|
data, ok := dataAny.(*Data[V])
|
|
if ok {
|
|
if data.End.IsZero() {
|
|
return data.Val, -1, true
|
|
} else if data.End.After(time.Now()) {
|
|
return data.Val, int64(data.End.Sub(time.Now()).Seconds()), true
|
|
}
|
|
}
|
|
}
|
|
return c.zero(), 0, false
|
|
}
|
|
|
|
// GetData 获取数据
|
|
// key: 键 返回值: 数据 剩余时间 是否存在
|
|
func (c *Cache[K, V]) GetData(key K) (V, bool) {
|
|
val, _, ok := c.Get(key)
|
|
return val, ok
|
|
}
|
|
|
|
// GetTime 获取数据到期时间
|
|
// key: 键 返回值: 到期时间 是否存在
|
|
func (c *Cache[K, V]) GetTime(key K) (time.Time, bool) {
|
|
if dataAny, ok := c.data.Load(key); ok {
|
|
data, ok := dataAny.(*Data[V])
|
|
if ok {
|
|
if c.cGetTTL != nil {
|
|
c.cGetTTL(key, *data)
|
|
}
|
|
return data.End, true
|
|
}
|
|
}
|
|
return time.Time{}, false
|
|
}
|
|
|
|
// GetTTL 获取数据剩余时间
|
|
// key: 键 返回值: 剩余时间 是否存在
|
|
// 时间为-1表示永不过期
|
|
func (c *Cache[K, V]) GetTTL(key K) (int64, bool) {
|
|
_, ttl, ok := c.Get(key)
|
|
return ttl, ok
|
|
}
|
|
|
|
// GetAll 获取所有数据
|
|
// 返回值: 数据
|
|
// 该功能为一些状态API提供支持
|
|
func (c *Cache[K, V]) GetAll() map[K]Data[V] {
|
|
data := make(map[K]Data[V])
|
|
c.data.Range(func(key, val any) bool {
|
|
data[key.(K)] = *val.(*Data[V])
|
|
return true
|
|
})
|
|
return data
|
|
}
|
|
|
|
/*
|
|
下方仅为获取数据并且输出指定类型的方法
|
|
推荐在定义类型为any的情况下使用
|
|
*/
|
|
|
|
// TypeErrMsg 不支持的的类型转换
|
|
var TypeErrMsg = errors.New("type error")
|
|
|
|
// NegativeNumberErrMsg 负数错误
|
|
var NegativeNumberErrMsg = errors.New("negative number")
|
|
|
|
// NumberBigErrMsg 数字过大
|
|
var NumberBigErrMsg = errors.New("number too big")
|
|
|
|
// KeyNotExists 不存在
|
|
var KeyNotExists = errors.New("key not exists")
|
|
|
|
// GetString 获取数据并转为string
|
|
// key: 键 返回值: 数据 是否存在 error
|
|
// 支持类型: string,int*,uint*,float*,bool
|
|
func (c *Cache[K, V]) GetString(key K) (string, bool, error) {
|
|
val, ok := c.GetData(key)
|
|
if !ok {
|
|
return "", false, nil
|
|
}
|
|
switch v := reflect.ValueOf(val); v.Kind() {
|
|
case reflect.String:
|
|
return v.String(), true, nil
|
|
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
|
return strconv.FormatInt(v.Int(), 10), true, nil
|
|
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
|
return strconv.FormatUint(v.Uint(), 10), true, nil
|
|
case reflect.Float32, reflect.Float64:
|
|
return strconv.FormatFloat(v.Float(), 'f', -1, 64), true, nil
|
|
case reflect.Bool:
|
|
return strconv.FormatBool(v.Bool()), true, nil
|
|
default:
|
|
return "", true, TypeErrMsg
|
|
}
|
|
}
|
|
|
|
// GetInt 获取数据并转为int
|
|
// key: 键 返回值: 数据 是否存在 error
|
|
// [int64,uint64,float64在32位系统上会出现type error]
|
|
// 支持类型: int*,uint*,float*(丢失精度)
|
|
func (c *Cache[K, V]) GetInt(key K) (int, bool, error) {
|
|
val, ok := c.GetData(key)
|
|
if !ok {
|
|
return 0, false, nil
|
|
}
|
|
switch v := reflect.ValueOf(val); v.Kind() {
|
|
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32:
|
|
return int(v.Int()), true, nil
|
|
case reflect.Int64:
|
|
if c.is64Bit {
|
|
return int(v.Int()), true, nil
|
|
} else {
|
|
return 0, true, TypeErrMsg
|
|
}
|
|
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32:
|
|
return int(v.Uint()), true, nil
|
|
case reflect.Uint64:
|
|
if c.is64Bit {
|
|
return int(v.Uint()), true, nil
|
|
} else {
|
|
return 0, true, TypeErrMsg
|
|
}
|
|
case reflect.Float32:
|
|
return int(v.Float()), true, nil
|
|
case reflect.Float64:
|
|
if c.is64Bit {
|
|
return int(v.Float()), true, nil
|
|
} else {
|
|
return 0, true, TypeErrMsg
|
|
}
|
|
default:
|
|
return 0, true, TypeErrMsg
|
|
}
|
|
}
|
|
|
|
// GetInt64 获取数据并转为int64
|
|
// key: 键 返回值: 数据 是否存在 error
|
|
// 支持类型: int*,uint*,float*(丢失精度)
|
|
func (c *Cache[K, V]) GetInt64(key K) (int64, bool, error) {
|
|
val, ok := c.GetData(key)
|
|
if !ok {
|
|
return 0, false, nil
|
|
}
|
|
switch v := reflect.ValueOf(val); v.Kind() {
|
|
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
|
return v.Int(), true, nil
|
|
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
|
return int64(v.Uint()), true, nil
|
|
case reflect.Float32, reflect.Float64:
|
|
return int64(v.Float()), true, nil
|
|
default:
|
|
return 0, true, TypeErrMsg
|
|
}
|
|
}
|
|
|
|
// GetUint 获取数据并转为uint
|
|
// key: 键 返回值: 数据 是否存在 error
|
|
// [负数会导致negative number] [int64,uint64,float64在32位系统上会出现type error]
|
|
// 支持类型: int*,uint*,float*
|
|
func (c *Cache[K, V]) GetUint(key K) (uint, bool, error) {
|
|
val, ok := c.GetData(key)
|
|
if !ok {
|
|
return 0, false, nil
|
|
}
|
|
switch v := reflect.ValueOf(val); v.Kind() {
|
|
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32:
|
|
if v.Int() < 0 {
|
|
return 0, true, NegativeNumberErrMsg
|
|
}
|
|
return uint(v.Int()), true, nil
|
|
case reflect.Int64:
|
|
if v.Int() < 0 {
|
|
return 0, true, NegativeNumberErrMsg
|
|
}
|
|
if c.is64Bit {
|
|
return uint(v.Int()), true, nil
|
|
} else {
|
|
return 0, true, TypeErrMsg
|
|
}
|
|
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32:
|
|
return uint(v.Uint()), true, nil
|
|
case reflect.Uint64:
|
|
if c.is64Bit {
|
|
return uint(v.Uint()), true, nil
|
|
} else {
|
|
return 0, true, TypeErrMsg
|
|
}
|
|
case reflect.Float32:
|
|
if v.Float() < 0 {
|
|
return 0, true, NegativeNumberErrMsg
|
|
}
|
|
return uint(v.Float()), true, nil
|
|
case reflect.Float64:
|
|
if v.Float() < 0 {
|
|
return 0, true, NegativeNumberErrMsg
|
|
}
|
|
if c.is64Bit {
|
|
return uint(v.Float()), true, nil
|
|
} else {
|
|
return 0, true, TypeErrMsg
|
|
}
|
|
default:
|
|
return 0, true, TypeErrMsg
|
|
}
|
|
}
|
|
|
|
// GetUint64 获取数据并转为uint64
|
|
// key: 键 返回值: 数据 是否存在 error
|
|
// [负数会导致negative number]
|
|
// 支持类型: int*,uint*,float*
|
|
func (c *Cache[K, V]) GetUint64(key K) (uint64, bool, error) {
|
|
val, ok := c.GetData(key)
|
|
if !ok {
|
|
return 0, false, nil
|
|
}
|
|
switch v := reflect.ValueOf(val); v.Kind() {
|
|
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
|
if v.Int() < 0 {
|
|
return 0, true, NegativeNumberErrMsg
|
|
}
|
|
return uint64(v.Int()), true, nil
|
|
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
|
return v.Uint(), true, nil
|
|
case reflect.Float32, reflect.Float64:
|
|
if v.Float() < 0 {
|
|
return 0, true, NegativeNumberErrMsg
|
|
}
|
|
return uint64(v.Float()), true, nil
|
|
default:
|
|
return 0, true, TypeErrMsg
|
|
}
|
|
}
|
|
|
|
// GetFloat32 获取数据并转为float32
|
|
// key: 键 返回值: 数据 是否存在 error
|
|
// [储蓄超过32位精度数字会出现number too big]
|
|
// 支持类型: int*,uint*,float*
|
|
func (c *Cache[K, V]) GetFloat32(key K) (float32, bool, error) {
|
|
val, ok := c.GetData(key)
|
|
if !ok {
|
|
return 0, false, nil
|
|
}
|
|
switch v := reflect.ValueOf(val); v.Kind() {
|
|
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
|
if v.Int() > 1<<24 {
|
|
return 0, true, NumberBigErrMsg
|
|
}
|
|
return float32(v.Int()), true, nil
|
|
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
|
if v.Uint() > 1<<24 {
|
|
return 0, true, NumberBigErrMsg
|
|
}
|
|
return float32(v.Uint()), true, nil
|
|
case reflect.Float32:
|
|
return float32(v.Float()), true, nil
|
|
case reflect.Float64:
|
|
if v.Float() > 1<<24 {
|
|
return 0, true, NumberBigErrMsg
|
|
}
|
|
return float32(v.Float()), true, nil
|
|
default:
|
|
return 0, true, TypeErrMsg
|
|
}
|
|
}
|
|
|
|
// GetFloat64 获取数据并转为float64
|
|
// key: 键 返回值: 数据 是否存在 error
|
|
// 支持类型: int*,uint*,float*
|
|
func (c *Cache[K, V]) GetFloat64(key K) (float64, bool, error) {
|
|
val, ok := c.GetData(key)
|
|
if !ok {
|
|
return 0, false, nil
|
|
}
|
|
switch v := reflect.ValueOf(val); v.Kind() {
|
|
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
|
return float64(v.Int()), true, nil
|
|
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
|
return float64(v.Uint()), true, nil
|
|
case reflect.Float32, reflect.Float64:
|
|
return v.Float(), true, nil
|
|
default:
|
|
return 0, true, TypeErrMsg
|
|
}
|
|
}
|
|
|
|
// GetBool 获取数据并转为bool
|
|
// key: 键 返回值: 数据 是否存在 error
|
|
// 支持类型: bool,[int*,uint*,float*]非0为true
|
|
func (c *Cache[K, V]) GetBool(key K) (bool, bool, error) {
|
|
val, ok := c.GetData(key)
|
|
if !ok {
|
|
return false, false, nil
|
|
}
|
|
switch v := reflect.ValueOf(val); v.Kind() {
|
|
case reflect.Bool:
|
|
return v.Bool(), true, nil
|
|
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
|
|
return v.Int() != 0, true, nil
|
|
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
|
|
return v.Uint() != 0, true, nil
|
|
case reflect.Float32, reflect.Float64:
|
|
return v.Float() != 0, true, nil
|
|
default:
|
|
return false, true, TypeErrMsg
|
|
}
|
|
}
|