go开源项目学习--cache2go

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/yefengzhichen/article/details/85448749

地址: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

猜你喜欢

转载自blog.csdn.net/yefengzhichen/article/details/85448749