wheat-cache/pkg/lru/lru.go

222 lines
5.3 KiB
Go
Raw Permalink Normal View History

2021-09-27 11:29:47 +08:00
package lru
import (
"container/list"
2021-10-12 15:11:30 +08:00
"sync/atomic"
2021-09-27 11:29:47 +08:00
_ "gitee.com/timedb/wheatCache/conf"
"gitee.com/timedb/wheatCache/pkg/errorx"
"gitee.com/timedb/wheatCache/pkg/event"
2021-10-12 15:11:30 +08:00
"gitee.com/timedb/wheatCache/pkg/middle"
"gitee.com/timedb/wheatCache/pkg/proto"
2021-09-27 11:29:47 +08:00
"gitee.com/timedb/wheatCache/pkg/structure"
"gitee.com/timedb/wheatCache/pkg/util"
"github.com/spf13/viper"
)
type keyBaseValue struct {
2021-10-12 15:11:30 +08:00
key string
val structure.KeyBaseInterface
expire int64 // 过期时间戳
2021-09-27 11:29:47 +08:00
}
2021-10-04 22:20:58 +08:00
type SingleCache struct {
maxsize int64 //最大的长度
clearSize int64 // 清理长度
nowSize int64 // 现在的长度
li *list.List
lruMap map[string]*list.Element
lruMaxDiverSize int
2021-10-12 15:11:30 +08:00
lruTtlManage *lruTTl // 定时清理器
2021-10-04 22:37:04 +08:00
lruDriver event.DriverInterface
lruConsumer event.ConsumerInterface
lruCleanProduce event.ProduceInterface // 发送清理事件
2021-10-12 15:11:30 +08:00
middleProduce event.ProduceInterface // 中间件驱动
2021-09-27 11:29:47 +08:00
}
2021-10-04 20:32:20 +08:00
// UpdateLruSize 更新现在的长度
2021-10-04 22:37:04 +08:00
func (lru *SingleCache) UpdateLruSize(length structure.UpdateLength) {
atomic.AddInt64(&lru.nowSize, int64(length))
2021-09-27 11:29:47 +08:00
}
2021-10-12 15:11:30 +08:00
func cacheInit() (int64, int64, int, int) {
2021-09-27 11:29:47 +08:00
maxSize := viper.GetString("lruCache.maxSize")
2021-10-04 22:37:04 +08:00
retMaxSize, maxErr := util.ParseSizeToBit(maxSize)
if maxErr != nil {
2021-10-12 15:11:30 +08:00
return 0, 0, 0, 0
2021-10-04 20:32:20 +08:00
}
2021-10-04 22:37:04 +08:00
if retMaxSize == 0 {
retMaxSize = defaultLruMaxSize
2021-10-04 20:32:20 +08:00
}
2021-09-27 11:29:47 +08:00
clearSize := viper.GetString("lruCache.clearSize")
2021-10-04 20:32:20 +08:00
retClearSize, clearErr := util.ParseSizeToBit(clearSize)
2021-10-04 22:37:04 +08:00
if clearErr != nil {
2021-10-12 15:11:30 +08:00
return 0, 0, 0, 0
2021-10-04 20:32:20 +08:00
}
2021-10-04 22:37:04 +08:00
if retClearSize == 0 {
retClearSize = defaultLruClearSize
2021-10-04 20:32:20 +08:00
}
2021-09-27 11:29:47 +08:00
maxDriver := viper.GetInt("lruCache.eventDriverSize")
2021-10-04 22:37:04 +08:00
if maxDriver == 0 {
maxDriver = defaultLruEventDriver
2021-10-04 20:32:20 +08:00
}
2021-10-12 15:11:30 +08:00
detachNum := viper.GetInt("lruCache.detachNum")
if detachNum == 0 {
detachNum = defaultDetachNum
}
return retMaxSize, retClearSize, maxDriver, detachNum
}
2021-09-27 11:29:47 +08:00
// NewLRUCache lru初始化
2021-10-04 22:20:58 +08:00
func NewLRUCache() *SingleCache {
2021-10-12 15:11:30 +08:00
maxSize, clearSize, maxDriverSize, detachNum := cacheInit()
2021-10-05 16:53:16 +08:00
lruDriver := event.NewDriver(maxDriverSize)
2021-10-04 16:23:37 +08:00
lruCacheOnce.Do(func() {
2021-10-04 22:20:58 +08:00
lru := &SingleCache{
2021-10-04 22:37:04 +08:00
maxsize: maxSize,
clearSize: clearSize,
nowSize: 0,
li: list.New(),
lruMap: make(map[string]*list.Element),
lruMaxDiverSize: maxDriverSize,
2021-10-04 22:37:04 +08:00
lruDriver: lruDriver,
2021-10-05 16:53:16 +08:00
lruConsumer: event.NewConsumer(lruDriver),
lruCleanProduce: event.NewProduce(lruDriver),
2021-10-12 15:11:30 +08:00
middleProduce: event.NewProduce(middle.NewMiddleWare().GetEventDriver()),
lruTtlManage: newLruTTl(detachNum),
2021-10-04 16:23:37 +08:00
}
lruCache = lru
2021-10-12 15:11:30 +08:00
// 启动 lru 事件驱动
2021-10-04 16:23:37 +08:00
go lru.lruSingleWork()
2021-10-12 15:11:30 +08:00
go lru.lruTtlWork()
go lru.cleanWork()
2021-10-04 16:23:37 +08:00
})
return lruCache
2021-09-27 11:29:47 +08:00
}
2021-10-04 16:23:37 +08:00
// GetDriver 获取驱动
2021-10-04 22:20:58 +08:00
func (lru *SingleCache) GetDriver() event.DriverInterface {
2021-09-27 11:29:47 +08:00
return lru.lruDriver
}
//Add 增加
2021-10-19 00:24:16 +08:00
func (lru *SingleCache) Add(key *proto.BaseKey, val structure.KeyBaseInterface) error {
if key == nil {
return errorx.KeyBaseIsNilErr()
}
2021-09-27 11:29:47 +08:00
2021-10-12 15:11:30 +08:00
exp := lru.lruTtlManage.setKeys(key)
2021-09-27 11:29:47 +08:00
keyBaseVal := &keyBaseValue{
2021-10-12 15:11:30 +08:00
key: key.Key,
val: val,
expire: exp,
2021-09-27 11:29:47 +08:00
}
if elVal, ok := lru.lruMap[key.Key]; ok {
2021-09-27 11:29:47 +08:00
lru.li.MoveToFront(elVal)
elVal.Value = keyBaseVal
2021-10-19 00:24:16 +08:00
return nil
2021-09-27 11:29:47 +08:00
}
valEl := lru.li.PushFront(keyBaseVal)
lru.lruMap[key.Key] = valEl
2021-10-04 20:32:20 +08:00
//增加大小
2021-10-04 22:37:04 +08:00
lru.UpdateLruSize(structure.UpdateLength(valEl.Value.(*keyBaseValue).val.SizeByte()))
2021-10-19 00:24:16 +08:00
return nil
2021-09-27 11:29:47 +08:00
}
// Get 查找key对应的value
func (lru *SingleCache) Get(key *proto.BaseKey) (structure.KeyBaseInterface, bool) {
2021-09-27 11:29:47 +08:00
2021-10-19 00:24:16 +08:00
if key == nil {
return nil, false
}
if elVal, ok := lru.lruMap[key.Key]; ok {
2021-09-27 11:29:47 +08:00
lru.li.MoveToFront(elVal)
return elVal.Value.(*keyBaseValue).val, true
}
return nil, false
}
//Del 删除机制
2021-10-04 22:20:58 +08:00
func (lru *SingleCache) Del() error {
2021-09-27 11:29:47 +08:00
if lru.lruMap == nil {
return errorx.New("lru is nil")
}
data := lru.li.Back()
delete(lru.lruMap, data.Value.(*keyBaseValue).key)
2021-10-04 20:32:20 +08:00
//删除大小
2021-10-04 22:37:04 +08:00
lru.UpdateLruSize(structure.UpdateLength(-1 * data.Value.(*keyBaseValue).val.SizeByte()))
2021-09-27 11:29:47 +08:00
lru.li.Remove(data)
return nil
}
2021-10-06 19:56:32 +08:00
//DelByKey 根据key删除
func (lru *SingleCache) DelByKey(key *proto.BaseKey) error {
2021-10-19 00:24:16 +08:00
if key == nil {
return errorx.KeyBaseIsNilErr()
}
2021-10-06 19:56:32 +08:00
if lru.lruMap == nil {
return errorx.New("lru is nil")
}
2021-10-12 15:11:30 +08:00
if el, ok := lru.lruMap[key.Key]; ok {
delete(lru.lruMap, key.Key)
2021-10-12 15:11:30 +08:00
lru.li.Remove(el)
lru.UpdateLruSize(structure.UpdateLength(-1 * el.Value.(*keyBaseValue).val.SizeByte()))
2021-10-06 19:56:32 +08:00
return nil
}
return errorx.New("lru no this key")
}
2021-10-12 15:11:30 +08:00
//DelByKeyAndExTtl 根据key(string)删除已经过期的 key
func (lru *SingleCache) delByKeyAndExTtl(key string, beforeTime int64) {
if elVal, ok := lru.lruMap[key]; ok {
exp := elVal.Value.(*keyBaseValue).expire
if exp <= beforeTime {
delete(lru.lruMap, key)
lru.li.Remove(elVal)
lru.UpdateLruSize(structure.UpdateLength(-1 * elVal.Value.(*keyBaseValue).val.SizeByte()))
}
}
}
func (lru *SingleCache) DelToClearSize() error {
if lru.lruMap == nil {
return errorx.New("lru is nil")
}
2021-10-12 15:11:30 +08:00
for lru.nowSize > lru.clearSize {
//del自动给nowSize进行大小的改变
err := lru.Del()
if err != nil {
return err
}
2021-10-12 15:11:30 +08:00
}
return nil
}
2021-10-12 15:11:30 +08:00
// 更新过期时间
func (lru *SingleCache) UpdateTTl(key *proto.BaseKey) error {
2021-10-19 00:24:16 +08:00
if key == nil {
return errorx.KeyBaseIsNilErr()
}
2021-10-12 15:11:30 +08:00
if elVal, ok := lru.lruMap[key.Key]; ok {
expire := lru.lruTtlManage.setKeys(key)
elVal.Value.(*keyBaseValue).expire = expire
}
return errorx.New("the key is not in lru cache, key:%s", key.Key)
}