地址:https://github.com/muesli/cache2go
主要特点:
1、并发安全,使用RWMutex锁来保证并发执行
2、可设置过期时间,过期自动删除
3、可设置操作的回调函数,如增加、删除时的回调函数
主要结构和关系为:
cache:map类型,缓存器,根据设置的缓存数据名称来存取相应的缓存表CacheTable
CacheTable:缓存表,存储一类数据的缓存结构,结构里的map维护了一个key到缓存项的映射,定义如下:
type CacheTable struct {
sync.RWMutex //锁,为了并发安全
name string //表名
items map[interface{}]*CacheItem //缓存项目
cleanupTimer *time.Timer //定时器,检查缓存项是否超时
cleanupInterval time.Duration //下次检查超时的时间间隔
logger *log.Logger //输出使用的logger
//访问一个不存在的项时,会调用此函数生成新数据项目, 调用SetDataLoader进行设置
loadData func(key interface{}, args ...interface{}) *CacheItem
addedItem func(item *CacheItem) //增加新缓存项时调用此函数,调用SetAddedItemCallback进行设置
aboutToDeleteItem func(item *CacheItem) //删除缓存项时调用此函数,调用SetAboutToDeleteItemCallback进行设置
}
CacheItem:缓存项,存储数据的结构,定义如下:
type CacheItem struct {
sync.RWMutex //读写锁
key interface{} //缓存项的key
data interface{} //缓存项的value
lifeSpan time.Duration //数据的过期时间,为0则不过期
createdOn time.Time //数据的加入时间
accessedOn time.Time //上次访问时间,根据此值和lifeSpan判断是否过期
accessCount int64 //访问次数统计
aboutToExpire func(key interface{}) //超时回调函数
}
以下是自己测试写的例子,测试了Foreach、SetDataLoader、SetLogger和超时处理:
package main
import (
"fmt"
"log"
"os"
"time"
"github.com/muesli/cache2go"
)
type student struct {
id int
name string
age int
score int
}
func main() {
cache := cache2go.Cache("studentInfo")
jack := &student{1, "jack", 12, 90}
tom := &student{2, "tom", 13, 65}
tony := &student{3, "tony", 12, 80}
saveTime := 5 * time.Second
cache.Add(1, saveTime, jack)
cache.Add(2, saveTime, tom)
cache.Add(3, saveTime, tony)
fmt.Println("students num:", cache.Count())
printFunc := func(key interface{}, stu *cache2go.CacheItem) {
fmt.Println(key, stu.Data())
}
cache.Foreach(printFunc)
loadFunc := func(key interface{}, args ...interface{}) *cache2go.CacheItem {
ftmp := &student{key.(int), "", 0, 0}
item := cache2go.NewCacheItem(key, 0, ftmp)
return item
}
cache.SetDataLoader(loadFunc)
tmp, ok := cache.Value(4)
if ok == nil {
fmt.Println(tmp.Data())
}
logFile, err := os.Create("./log.txt")
if err != nil {
fmt.Println(err)
}
defer logFile.Close()
logger := log.New(logFile, "mytest_", log.Ldate|log.Ltime|log.Lshortfile)
logger.Println("this is test line")
cache.SetLogger(logger)
time.Sleep(7 * time.Second)
}
输出结果:
students num: 3
1 &{1 jack 12 90}
2 &{2 tom 13 65}
3 &{3 tony 12 80}
&{4 0 0}
日志打印结果:
mytest_2018/12/31 09:52:51 mytest.go:51: this is test line
mytest_2018/12/31 09:52:56 cachetable.go:330: Expiration check triggered after 5s for table studentInfo
mytest_2018/12/31 09:52:56 cachetable.go:330: Deleting item with key 1 created on 2018-12-31 09:52:51.7731682 +0800 CST m=+0.014991301 and hit 0 times from table studentInfo
mytest_2018/12/31 09:52:56 cachetable.go:330: Deleting item with key 2 created on 2018-12-31 09:52:51.7731682 +0800 CST m=+0.014991301 and hit 0 times from table studentInfo
mytest_2018/12/31 09:52:56 cachetable.go:330: Deleting item with key 3 created on 2018-12-31 09:52:51.7731682 +0800 CST m=+0.014991301 and hit 0 times from table studentInfo