一瞥之见

0%

读go项目源码打卡一 - gcache & go-cache

最近开始准备持续的读一些go项目的代码,先从一些简单的入手,最后目标是读TiDB源码。
打卡一选择了单机kv内存缓存的实现其中star比较多的go-cache和gcache(都是实现了并发安全的)。记录了其代码结构以及我从每个项目学习到的东西

前言
本文的代码结构说明图并非完全是原本的代码实现的结构,去除了一些非核心的功能点(只列出了关键/我关心的部分)

go-cache - 🌟🌟🌟

项目简介:

最简单的一个项目,通过map实现的kv缓存,无任何淘汰策略(直接淘汰)

代码结构梳理:

go-cache代码梳理

学到的东西:

  1. 其代码层级很好,将实现管理过期key逻辑的部分抽象到数据结构janitor来实现!使得cache结构能够专注的实现自己的逻辑
  2. 通过runtime.SetFinalizer实现绑定关闭janitor定期维护过期key的goroutine的逻辑到Cache的生命周期,避免了需要用户手动调用来关闭(万一用户忘记调用了呢!)

gcache - 🌟🌟🌟🌟🌟

项目简介:

非常好的一个项目,实现了simple、LRU、LFU、ARC四种缓存淘汰策略

代码结构梳理:

gcache代码梳理

学到的东西:

  1. 用户初始化的代码入口很优雅,使用了建造者模式、且融合了简单工厂模式。
  2. 代码层级和变化隔离实现的非常好!顶层的Cache interface定义,公有属性部分的baseCache(且通过CacheBuilder持有全部baseCache的属性,每个具体策略在new时调用相同的buildCache函数实现了共同的baseCache部分属性的初始化!),然后是嵌套的statsAccessor interface通过stats实现嵌入到了baseCache,使得全部具体实现类都完全不需要管stats那部分的逻辑实现!这部分非常值得学习
  3. stats中的数值并发读写使用了atomic包提供的硬件原子同步、性能更高
  4. LRU/LFU/ARC算法的实现
  5. list.List的相关接口的熟悉