学习开源缓存库,cache2g0是作为Go新手来说,比较容易上手的library。
Cache2go
Concurrency-safe golang caching library with expiration capabilities.
cache2g0是一个key-value格式的保证并发安全并带有过期控制的缓存库。
你如何来设计一个缓存库呢?
最方便的方式: key-value形式。类似redis那样,我先画一张表,然后在表中存放n个key-value。

Cache2go的实现就是这个实现原理,在上图基础上添加了安全性和过期控制等功能。
部分Cache2go源码解读
先让我们来看看Cache2go中有关的结构体:CacheTable,CacheItem
//CacheTable type CacheTable struct { sync.RWMutex // 互斥锁 name string // 表名 items map[interface{}]*CacheItem // item的集合 cleanupTimer *time.Timer // 设置清理时间(处于等待状态) cleanupInterval time.Duration // 设置清理时间段 logger *log.Logger // 设置日志 loadData func(key interface{}, args ...interface{}) *CacheItem addedItem func(item *CacheItem) aboutToDeleteItem func(item *CacheItem) } //CacheItem type CacheItem struct { sync.RWMutex // 互斥锁 key interface{} // data-key data interface{} // data-value lifeSpan time.Duration // 生命周期 createdOn time.Time // 创建时间 accessedOn time.Time // 最后访问时间 accessCount int64 // 访问次数 aboutToExpire func(key interface{}) // TODO }
为了保证其并发安全性,都带有sync.RWMutex
,维持操作的原子性。并带有时间戳来实现过期控制。至于那些回调函数,我也是第一次看见这种写法。
Cache2go的作者们,根据这两个struct分别开放了许多getter&setter
方法,使用者只需调用即可,代码实现过程中也有对用户是否设置过属性进行判断,来确保程序的健壮性。
举个例子:
CacheTable中包含logger字段,并且编写了SetLogger(logger)
来让用户实现logger打印,并实现了log(v...)方法,让用户可选实现SetLogger(logger),如果用户不想打印日志,那么不需要调用SetLogger(logger)
。
func (table *CacheTable) log(v ...interface{}) { if table.logger == nil { return } table.logger.Println(v) }
创建表并添加Item
通过创建一个缓存表并添加缓存Item来剖析源码,实现代码如下:
// new Cache cache := cache2go.Cache("myCache") // set logger logger := log.New(os.Stdout, "DEBUG", log.Ltime) cache.SetLogger(logger) // will storage data val := myStruct{"This is a test!", []byte{}} // Add Item : key, duration, stor_data cache.Add("someKey", 5*time.Second, &val)
创建一个表
Cache2go中调用Cache(tableName)
方法来实现创建,内部使用map来实现的,先通过tableName
关键字在map中查找,如果存在则直接返回,否则先出创建,之后返回。

向表中添加CacheItem
- 通过调用
NewCacheItem(key, lifeSpan, value)
来完成CacheItem的初始化 - 接下里需要添加将CacheItem添加到CacheTable中
- CacheTable的对象通过调用自身的
addInternal(cacheItem)
完成添加,并检查是否有过期的缓存 - 在
addInternal(cacheItem)
中调用自身的expiraionCheck()
来完成检查.

这里只是代码简单描述了下,主要掌握其设计思想就好啦。详情还请移步cache2g0
需要扩充的知识点(后续更新...)
- struct中的回调函数
- sync.RWMutex源码的解读
- time源码的解读
精彩文章,持续更新,请关注微信公众号:

有疑问加站长微信联系(非本文作者)
