1 Star 0 Fork 0

liujinsuo/tool

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
_example
coroutine_pool
fsdef
graceful
msg_group
nocopy
primitive
s2m
singleflight
toolcache
toolgin
toolhttp
tooljson
toolmap
toolmapsync
toolnet
toolpb
toolreflect
toolrunner
toolsync
toolzone
.gitignore
LICENSE
README.en.md
README.md
cron.go
crypto_cbc_aes.go
debug_x.go
feishu.go
func.go
func_test.go
go.mod
go.sum
http_client.go
logrus_hook.go
mgoid.go
mgoid_test.go
mysql_save_config.go
redis_zset_lru.go
redis_zset_lru_test.go
string.go
time.go
time_test.go
with_json2.go
zerolog_func.go
克隆/下载
redis_zset_lru.go 3.05 KB
一键复制 编辑 原始数据 按行查看 历史
liujinsuo 提交于 3年前 . zset lru
package tool
import (
"context"
"encoding/json"
"github.com/go-redis/redis/v8"
"github.com/pkg/errors"
"time"
)
// RedisZSetLRU 基于redis Zset实现 lru缓存
// RedisFreshDataCache 最新数据缓存,自动淘汰就数据
// 使用场景 如:缓存用户最后发送的5条消息,超过5条则自动删除,用户30分钟未发消息则会删除所有消息
type RedisZSetLRU struct {
rdb *redis.Client //
redisKey string //key
}
func NewRedisZSetLRU(rdb *redis.Client, RedisKey string) *RedisZSetLRU {
return &RedisZSetLRU{
rdb: rdb,
redisKey: RedisKey,
}
}
// Add 添加 //过期时间 //最大缓存个数
func (s *RedisZSetLRU) Add(Score float64, data interface{}, Expire time.Duration, MaxCacheNumber int64) error {
b, err := json.Marshal(data)
if err != nil {
return errors.Wrapf(err, "%+v %+v %+v %+v %+v", s.redisKey, Score, data, Expire, MaxCacheNumber)
}
if err := s.rdb.ZAdd(context.Background(), s.redisKey, &redis.Z{
Score: Score,
Member: b, //这里虽然是借口但是 只能存 string|[]byte|, 否则会报错 redis: can't marshal map[string]int (implement encoding.BinaryMarshaler)
}).Err(); err != nil {
return errors.Wrapf(err, "%+v %+v %+v %+v %+v", s.redisKey, Score, data, Expire, MaxCacheNumber)
}
//设置过期时间
if err := s.rdb.Expire(context.Background(), s.redisKey, Expire).Err(); err != nil {
return errors.Wrapf(err, "%+v %+v %+v %+v %+v", s.redisKey, Score, data, Expire, MaxCacheNumber)
}
//获取成员总个数
count := s.rdb.ZCard(context.Background(), s.redisKey).Val()
if count <= MaxCacheNumber {
return nil
}
//根据下标删除成员,前后都包含,分值越大,下标越大,这里删除小的
stop := count - MaxCacheNumber - 1
if stop < 0 {
return nil
}
if err := s.rdb.ZRemRangeByRank(context.Background(), s.redisKey, 0, stop).Err(); err != nil {
return errors.Wrapf(err, "%+v %+v %+v %+v %+v", s.redisKey, Score, data, Expire, MaxCacheNumber)
}
return nil
}
// GetScoreMax 获取分值最大的数据
func (s *RedisZSetLRU) GetScoreMax(out interface{}) (Score float64, err error) {
return s.GetOneByIndex(out, -1)
}
// GetScoreMin 获取分值最小的数据
func (s *RedisZSetLRU) GetScoreMin(out interface{}) (Score float64, err error) {
return s.GetOneByIndex(out, 0)
}
// GetOneByIndex 根据下标获取一条数据
func (s *RedisZSetLRU) GetOneByIndex(out interface{}, index int64) (Score float64, err error) {
//根据下标获取分值和成员,分值越大,下标越大
result, err := s.rdb.ZRangeWithScores(context.Background(), s.redisKey, index, index).Result()
if err != nil {
return 0, errors.Wrapf(err, "%+v", s.redisKey)
}
if len(result) <= 0 {
return 0, redis.Nil
}
//类型判断
var b []byte
if r, ok := result[0].Member.(string); ok == true {
b = []byte(r)
} else if r, ok := result[0].Member.([]byte); ok == true {
b = r
} else {
return 0, errors.New("unmarshal fail")
}
//解码数据
if err := json.Unmarshal(b, out); err != nil {
return 0, errors.Wrapf(err, "%+v", s.redisKey)
} else {
return result[0].Score, nil
}
}
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
Go
1
https://gitee.com/liujinsuo/tool.git
git@gitee.com:liujinsuo/tool.git
liujinsuo
tool
tool
537076f1d965

搜索帮助