代码改变世界

vitess源码阅读笔记笔记之LRUCache

2012-04-05 18:58  ngaut  阅读(1157)  评论(0编辑  收藏  举报
LRUCache的作用以及在vitess中扮演的角色,文档上是这样描述的:
 vtocc builds a plan for every query that requires bind variables. It stores these plans in an LRU cache

 

今天先来分析LRUCache本身的具体实现

提到cache就不能少了key-value(以下简称kv),提到kv就不能不提到两个必须实现的接口。get和set,LRUCache也不例外。

kv最便捷的实现方法就是map,至于map底层实现是hash表还是红黑树,暂时无需关心,LRUCache大概也是这样想的,使用

了map作为kv的主要数据结构,同时使用一个list(双链表)来存放所有的元素,总是将最近访问的放到list的头部。

另外为了线程安全还用到了lock 

 

先上数据结构,这个是算法实现的灵魂
type LRUCache struct {
mu sync.Mutex
// list & table of *entry objects
list  *list.List //LQ: 所有的kv被组织成entry都放到list中,方便实现lru算法
table map[string]*list.Element     //LQ:  用map保持对其的引用来实现快速查找
// Our current size, in bytes. Obviously a gross simplification and low-grade
// approximation.
size uint64
// How many bytes we are limiting the cache to.
capacity uint64

 

既然是kv,那么key是什么类型呢,从table的定义可以看到key的类型是string,那么value又是什么类型呢?*list.Element

这里能看到的是个指针。这个指针指向什么呢? entry上场

type entry struct {
key           string
value         Value
size          int
time_accessed time.Time

为了统计LRUCache中元素占用内存大小,所有放到LRUCache中的元素都必须实现接口Value,即要实现函数Size() int

type Value interface {
Size() int

所有放入LRUCache的元素都会被包装成entry,见函数addNew

func (self *LRUCache) addNew(key string, value Value) {
newEntry := &entry{key, value, value.Size(), time.Now()} //构造一个新的entry,对结构体的成员依次赋值
element := self.list.PushFront(newEntry) //最近的总是放到list的头部
self.table[key] = element //kv
self.size += uint64(newEntry.size) //当前LRUCache的实际大小
self.checkCapacity() //检查是否超过了LRUCache的容量

 其它的函数想必大体也可以猜到如何实现,这里就不一而足了。我们在vitess源码阅读笔记笔记之起因和编码风格中提到

vitess的多个模块都通过http的方式导出内部状态(json格式)来辅助调试和监控系统的运行状况  

 LRUCache虽然本身没有提供http服务,但提供了StatsJSON函数来导出自身的运行状态。

func (self *LRUCache) StatsJSON() string {
l, s, c, o := self.Stats()
return fmt.Sprintf("{\"Length\": %v, \"Size\": %v, \"Capacity\": %v, \"OldestAccess\": \"%v\"}", l, s, c, o)

导出的分别是:LRUCache中元素的个数, 当前占用的内存大小, 总容量, 最老的元素的上次访问时间

 

前面提到分析代码时一定要知道代码在架构中扮演的角色 就像谍战剧中的情节一样,

找不到组织的后果是危险的,LRUCache 的组织在哪里呢?

其在架构图中扮演的角色是作为consolidator和schema中的基本组件,具体职责嘛,叫啥名,就做啥事。