leveldb cache 分析

leveldb cache 分析

先从cache.h开始看,提供了创建cache实例的方法NewLRUCache(size_t capacity)。创建出的cache本身支持插入、查找、释放等操作,进入NewLRUCache的实现可以发现内部是一个LRUCache,接下来进行详细分析

1.类结构图

在这里插入图片描述

(一个小知识,在读代码过程会发现很多GUARDED_BY,其定义是根据是否有__clang__来进行空定义或其他定义。这个那是Clang Thread Safety Analysis中定义的,是数据成员的属性,该属性声明数据成员受给定功能保护。读共享,写互斥。可以进行静态分析)

2.LRUCache

从底层往上看,先是LRUCache,其内部包含有容量capaicty,锁mutex,已使用的容量usage_,LRUHandle的_lru(prev指向第一个节点,next,指向最后一个节点)和in_use_(存储正在使用的节点),在然后有个HandleTable(自己实现的hashtable来加速查找)。LRUCache其实就是lru的实现。先看内部的数据结。

2.1 数据结构
2.1.1 LRUHandle

代码:

struct LRUHandle {
  void* value;
  void (*deleter)(const Slice&, void* value);
  LRUHandle* next_hash;
  LRUHandle* next;
  LRUHandle* prev;
  size_t charge;      // TODO(opt): Only allow uint32_t?
  size_t key_length;
  bool in_cache;      // Whether entry is in the cache.
  uint32_t refs;      // References, including cache reference, if present.
  uint32_t hash;      // Hash of key(); used for fast sharding and comparisons
  char key_data[1];   // Beginning of key

  Slice key() const {
    // next_ is only equal to this if the LRU handle is the list head of an
    // empty list. List heads never have meaningful keys.
    assert(next != this);

    return Slice(key_data, key_length);
  }
};

内部数据如上,使用key的开始地址和长度来记录key,因为使用自定义的Slice,所以不能直接使用指针不记录长度,方便后续处理。
下面简单看一下插入时申请空间操作

//减去1即为char[1],加上key的size
  LRUHandle* e = reinterpret_cast<LRUHandle*>(
       malloc(sizeof(LRUHandle)-1 + key.size()));

释放时URef函数

  if (e->refs == 0) {  // Deallocate.
    assert(!e->in_cache);
    (*e->deleter)(e->key(), e->value);
    free(e);
2.1.2 HandleTable

还是从数据来看

  // The table consists of an array of buckets where each bucket is
  // a linked list of cache entries that hash into the bucket.
  uint32_t length_;
  uint32_t elems_;
  LRUHandle** list_;

二级指针,第一个是个桶,每个项都指向一串对应的LRUHandle,第一级相同的放一起(相当于开链表方式解决冲突)

2.2 流程图

下面简单看一下流程

2.2.1 插入流程

加粗样式

2.2.2 移除流程

在这里插入图片描述

2.2.3 查找流程

相对简单直接在hashtable中查找

3.ShardedLRUCache

其实主要都是使用了LRUCache的函数,主要改进在于使用LRUCache[],使用多个来达到分段的效果,减少竞争(因为涉及互斥)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序员学习随笔

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值