package lru import ( "container/list" _ "gitee.com/timedb/wheatCache/conf" "gitee.com/timedb/wheatCache/pkg/errorx" "gitee.com/timedb/wheatCache/pkg/event" "gitee.com/timedb/wheatCache/pkg/structure" "gitee.com/timedb/wheatCache/pkg/util" "github.com/spf13/viper" "sync/atomic" ) type keyBaseValue struct { key string val structure.KeyBaseInterface } type singleCache struct { maxsize int64 //最大的长度 clearSize int64 // 清理长度 nowSize int64 // 现在的长度 li *list.List lruMap map[string]*list.Element lruDriver event.DriverInterface lruConsumer event.ConsumerInterface lruCleanProduce event.ProduceInterface // 发送清理事件 } // UpdateLruSize 更新现在的长度 func (lru *singleCache) UpdateLruSize(length int64) { atomic.AddInt64(&lru.nowSize, length) } func cacheInit() (int64, int64, event.DriverInterface) { maxSize := viper.GetString("lruCache.maxSize") retMaxSize, maxErr:= util.ParseSizeToBit(maxSize) if maxErr != nil{ return 0, 0, nil } if retMaxSize == 0{ retMaxSize = lruMaxSize } clearSize := viper.GetString("lruCache.clearSize") retClearSize, clearErr := util.ParseSizeToBit(clearSize) if clearErr != nil{ return 0, 0, nil } if retClearSize == 0{ retClearSize = lruClearSize } maxDriver := viper.GetInt("lruCache.eventDriverSize") if maxDriver == 0{ maxDriver = lruEventDriver } lruDriver := event.NewDriver(maxDriver) return retMaxSize, retClearSize, lruDriver } // NewLRUCache lru初始化 func NewLRUCache() *singleCache { maxSize, clearSize, lruDrivers := cacheInit() lruCacheOnce.Do(func() { _, _, lruDriver := cacheInit() lru := &singleCache{ maxsize: maxSize, clearSize: clearSize, nowSize: 0, li: list.New(), lruMap: make(map[string]*list.Element), lruDriver: lruDriver, lruConsumer: event.NewConsumer(lruDrivers), lruCleanProduce: event.NewProduce(lruDrivers), } lruCache = lru go lru.lruSingleWork() }) return lruCache } // GetDriver 获取驱动 func (lru *singleCache) GetDriver() event.DriverInterface { return lru.lruDriver } //Add 增加 func (lru *singleCache) Add(key string, val structure.KeyBaseInterface) { keyBaseVal := &keyBaseValue{ key: key, val: val, } if elVal, ok := lru.lruMap[key]; ok { lru.li.MoveToFront(elVal) elVal.Value = keyBaseVal return } valEl := lru.li.PushFront(keyBaseVal) lru.lruMap[key] = valEl //增加大小 lru.UpdateLruSize(valEl.Value.(*keyBaseValue).val.SizeByte()) } // Get 查找key对应的value func (lru *singleCache) Get(key string) (structure.KeyBaseInterface, bool) { if lru.lruMap == nil { return nil, false } if elVal, ok := lru.lruMap[key]; ok { lru.li.MoveToFront(elVal) return elVal.Value.(*keyBaseValue).val, true } return nil, false } //Del 删除机制 func (lru *singleCache) Del() error { if lru.lruMap == nil { return errorx.New("lru is nil") } data := lru.li.Back() delete(lru.lruMap, data.Value.(*keyBaseValue).key) //删除大小 lru.UpdateLruSize(-1 * data.Value.(*keyBaseValue).val.SizeByte()) lru.li.Remove(data) return nil }