lru driver-test
This commit is contained in:
parent
a556840f9b
commit
768f3df70e
|
@ -7,30 +7,18 @@ import (
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestLoadConf(t *testing.T) {
|
|
||||||
type args struct {
|
|
||||||
path string
|
|
||||||
}
|
|
||||||
tests := []struct {
|
|
||||||
name string
|
|
||||||
args args
|
|
||||||
wantErr bool
|
|
||||||
}{
|
|
||||||
// TODO: Add test cases.
|
|
||||||
}
|
|
||||||
for _, tt := range tests {
|
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
|
||||||
if err := LoadConf(tt.args.path); (err != nil) != tt.wantErr {
|
|
||||||
t.Errorf("LoadConf() error = %v, wantErr %v", err, tt.wantErr)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestConf(t *testing.T) {
|
func TestConf(t *testing.T) {
|
||||||
|
// 外部导入 conf.yaml 需要导入 conf 包
|
||||||
|
|
||||||
|
// get 使用, 读取 public_conf 配置文件
|
||||||
|
h := viper.Get("storage.host")
|
||||||
|
require.Equal(t, h, "127.0.0.1")
|
||||||
|
|
||||||
|
h = viper.Get("env")
|
||||||
|
require.Equal(t, h, "dev")
|
||||||
|
|
||||||
|
// set 使用
|
||||||
viper.Set("host", "1222")
|
viper.Set("host", "1222")
|
||||||
host := viper.GetString("host")
|
host := viper.GetString("host")
|
||||||
|
|
||||||
require.Equal(t, host, "1222")
|
require.Equal(t, host, "1222")
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,3 +6,10 @@ storage:
|
||||||
host: '127.0.0.1'
|
host: '127.0.0.1'
|
||||||
port: 5890
|
port: 5890
|
||||||
timeOut: 2 # second
|
timeOut: 2 # second
|
||||||
|
|
||||||
|
# clearSize and maxSize must be Int
|
||||||
|
lruCache:
|
||||||
|
clearSize: "512MB"
|
||||||
|
maxSize: "1GB"
|
||||||
|
eventDriverSize: 2000
|
||||||
|
workTime: 1
|
||||||
|
|
|
@ -2,6 +2,6 @@
|
||||||
|
|
||||||
EventP : 生产事件
|
EventP : 生产事件
|
||||||
|
|
||||||
EventQ : 队列事件
|
EventQ : 事件队列
|
||||||
|
|
||||||
Event CP : 清理事件
|
Event CP : 清理事件
|
|
@ -27,3 +27,4 @@ type ProduceInterface interface {
|
||||||
type ConsumerInterface interface {
|
type ConsumerInterface interface {
|
||||||
Receive(ctx context.Context) *Event
|
Receive(ctx context.Context) *Event
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1 +1,10 @@
|
||||||
package lru
|
package lru
|
||||||
|
|
||||||
|
type SingleWorkFunc func() interface{}
|
||||||
|
|
||||||
|
const (
|
||||||
|
OpEventName = "operateEvent"
|
||||||
|
CleEventName = "clearEvent"
|
||||||
|
|
||||||
|
WorkFuncEventCtxKey = "workFunc"
|
||||||
|
)
|
||||||
|
|
|
@ -0,0 +1,104 @@
|
||||||
|
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"
|
||||||
|
)
|
||||||
|
|
||||||
|
// feat
|
||||||
|
/*
|
||||||
|
1. cleanProduce
|
||||||
|
2. 定义 LRUSingle Work 函数
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
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
|
||||||
|
lruProduce event.ProduceInterface // 发送清理事件
|
||||||
|
}
|
||||||
|
|
||||||
|
func (lru *singleCache) UpdateLruLength(length int64) {
|
||||||
|
atomic.AddInt64(&lru.nowSize, length)
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewLRUCache lru初始化
|
||||||
|
func NewLRUCache() *singleCache {
|
||||||
|
maxSize := viper.GetString("lruCache.maxSize")
|
||||||
|
clearSize := viper.GetString("lruCache.clearSize")
|
||||||
|
maxDriver := viper.GetInt("lruCache.eventDriverSize")
|
||||||
|
lruDriver := event.NewDriver(maxDriver)
|
||||||
|
|
||||||
|
return &singleCache{
|
||||||
|
maxsize: util.ParseSizeToBit(maxSize),
|
||||||
|
clearSize: util.ParseSizeToBit(clearSize),
|
||||||
|
nowSize: 0,
|
||||||
|
li: list.New(),
|
||||||
|
lruMap: make(map[string]*list.Element),
|
||||||
|
lruDriver: lruDriver,
|
||||||
|
lruConsumer: event.NewConsumer(lruDriver),
|
||||||
|
lruProduce: event.NewProduce(lruDriver),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// RetDriver 获取驱动
|
||||||
|
func (lru *singleCache) RetDriver() 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
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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.li.Remove(data)
|
||||||
|
return nil
|
||||||
|
}
|
|
@ -0,0 +1,20 @@
|
||||||
|
package lru
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"gitee.com/timedb/wheatCache/pkg/structure/stringx"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestNewLRUCache(t *testing.T) {
|
||||||
|
cache := NewLRUCache()
|
||||||
|
v1 := stringx.NewStringSingle()
|
||||||
|
v2 := stringx.NewStringSingle()
|
||||||
|
v3 := stringx.NewStringSingle()
|
||||||
|
cache.Add("1", v1)
|
||||||
|
cache.Add("2", v2)
|
||||||
|
cache.Add("3", v3)
|
||||||
|
cache.Add("1", v1)
|
||||||
|
cache.Del()
|
||||||
|
fmt.Println(cache.Get("1"))
|
||||||
|
}
|
|
@ -0,0 +1,47 @@
|
||||||
|
package lru
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"gitee.com/timedb/wheatCache/pkg/errorx"
|
||||||
|
"gitee.com/timedb/wheatCache/pkg/event"
|
||||||
|
"log"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
func lruCleanWork() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func funcWork(work SingleWorkFunc, ttl time.Duration) interface{} {
|
||||||
|
t := time.NewTimer(ttl)
|
||||||
|
|
||||||
|
resultCh := make(chan interface{})
|
||||||
|
go func() {
|
||||||
|
resultCh <- work()
|
||||||
|
}()
|
||||||
|
|
||||||
|
select {
|
||||||
|
case <-t.C:
|
||||||
|
return errorx.TimeOutErr()
|
||||||
|
case res := <-resultCh:
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (lru *singleCache) lruSingleWork() interface{} {
|
||||||
|
ctx := context.Background()
|
||||||
|
for {
|
||||||
|
event := lru.lruConsumer.Receive(ctx)
|
||||||
|
|
||||||
|
worFunc, ok := event.GetValue(WorkFuncEventCtxKey)
|
||||||
|
if !ok {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
switch worFunc.(type) {
|
||||||
|
case SingleWorkFunc:
|
||||||
|
_, err := event.ExecWorkAndSendResult(worFunc.(*event))
|
||||||
|
log.Println(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
package util
|
||||||
|
|
||||||
|
import (
|
||||||
|
"regexp"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ParseSizeToBit
|
||||||
|
// 支持MB, GB, KB, 格式 "5KB" 或者 "5kb"
|
||||||
|
func ParseSizeToBit(size string) int64 {
|
||||||
|
|
||||||
|
sizes := regexp.MustCompile("^\\d+")
|
||||||
|
sizeRes := sizes.FindAllString(size, 1)
|
||||||
|
unit := strings.Split(size, sizeRes[0])
|
||||||
|
if unit[1] == "KB"|| unit[1] == "kb"{
|
||||||
|
Res, _ := strconv.ParseInt(sizeRes[0], 10, 64)
|
||||||
|
return Res * 1024
|
||||||
|
} else if unit[1] == "MB"|| unit[1] == "mb"{
|
||||||
|
Res, _ := strconv.ParseInt(sizeRes[0], 10, 64)
|
||||||
|
return Res * 1024 * 1024
|
||||||
|
} else if unit[1] == "GB"|| unit[1] == "fb"{
|
||||||
|
Res, _ := strconv.ParseInt(sizeRes[0], 10, 64)
|
||||||
|
return Res * 1024 *1024 * 1024
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
package util
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestParseSizeToBit(t *testing.T) {
|
||||||
|
fmt.Print(ParseSizeToBit("18KB"))
|
||||||
|
}
|
Loading…
Reference in New Issue