最近开始准备持续的读一些go项目的代码,先从一些简单的入手,最后目标是读TiDB源码。
打卡一选择了单机kv内存缓存的实现其中star比较多的go-cache和gcache(都是实现了并发安全的)。记录了其代码结构以及我从每个项目学习到的东西
前言
本文的代码结构说明图并非完全是原本的代码实现的结构,去除了一些非核心的功能点(只列出了关键/我关心的部分)
go-cache - 🌟🌟🌟
项目简介:
最简单的一个项目,通过map实现的kv缓存,无任何淘汰策略(直接淘汰)
代码结构梳理:
学到的东西:
- 其代码层级很好,将实现管理过期key逻辑的部分抽象到数据结构janitor来实现!使得cache结构能够专注的实现自己的逻辑
- 通过runtime.SetFinalizer实现绑定关闭janitor定期维护过期key的goroutine的逻辑到Cache的生命周期,避免了需要用户手动调用来关闭(万一用户忘记调用了呢!)
gcache - 🌟🌟🌟🌟🌟
项目简介:
非常好的一个项目,实现了simple、LRU、LFU、ARC四种缓存淘汰策略
代码结构梳理:
学到的东西:
- 用户初始化的代码入口很优雅,使用了建造者模式、且融合了简单工厂模式。
- 代码层级和变化隔离实现的非常好!顶层的Cache interface定义,公有属性部分的baseCache(且通过CacheBuilder持有全部baseCache的属性,每个具体策略在new时调用相同的buildCache函数实现了共同的baseCache部分属性的初始化!),然后是嵌套的statsAccessor interface通过stats实现嵌入到了baseCache,使得全部具体实现类都完全不需要管stats那部分的逻辑实现!这部分非常值得学习
- stats中的数值并发读写使用了atomic包提供的硬件原子同步、性能更高
- LRU/LFU/ARC算法的实现
- list.List的相关接口的熟悉