leveldb之cache

leveldb在内存中使用Cache加速数据查找,包括Table Cache和Block Cache,两者都利用LRU思想。LRUCache维护一个双向链表和哈希表,新插入的元素位于链表尾部,当超过容量时,从头部移除最近最少使用的元素。ShardedLRUCache通过将元素分散到16个分片中,减少多线程访问的锁竞争。插入元素时,首先将元素加入链表,然后根据哈希值插入哈希表,如果哈希冲突,则替换旧元素。
摘要由CSDN通过智能技术生成

当向leveldb写入数据时,首先是将数据写入leveldb的Memtable(Memtable可能转化为IMMemtable)中,Memtable是存储在内存中的。只有经过compaction操作后,才会将内存中的数据写入到磁盘中的sstable中。
当要读数据时,首先在Memtable中查找,若没有找到,则在sstable中继续查找。而sstable是存储在磁盘中的,这样就需要进行多次磁盘操作,速度会非常慢。为了加快查找速度,leveldb在采用了Cache的方式,尽最大可能减少随机读操作。

cache分为Table Cache和 Block Cache两种,其中Table Cache中缓存的是sstable的索引数据,Block Cache缓存的是Block数据,Block Cache是可选的,即可以在配置中来选择是否打开这个功能。

当要进行Compaction操作调用CompactMemTable()时,会调用WriteLevel0Table(),此时则会创建一个Meta File,并保存在Table Cache中,然后可通过Table Cache进行读取。

leveldb中的Cache主要用到了双向链表、哈希表和LRU(least recently used)思想。

1、LRUHandle

LRUHandle表示了Cache中的每一个元素,通过指针形成一个双向循环链表:

struct LRUHandle {
  void* value;//cache存储的数据
  void (*deleter)(const Slice&, void* value);//是将数据从Cache中清除时执行的函数
  LRUHandle* next_hash;//解决hash碰撞,指向下一个hash值相同的节点
  LRUHandle* next;//next和prev构成双向循环链表
  LRUHandle* prev;
  size_t charge;      // 所占内存大小
  size_t key_length;
  uint32_t refs;
  uint32_t hash;      // Hash of key(); used for fast sharding and comparisons
  char key_data[1];   // Beginning of key

  Slice key() const {
    if (next == this) {
      return *(reinterpret_cast<Slice*>(value));
    } else {
      return Slice(key_data, key_length);
    }
  }
};

在Table Cache中,Cache的key值是SSTable的文件名称,Value部分包含两部分,一个是指向磁盘打开的SSTable文件的文件指针,这是为了方便读取内容;另外一个是指向内存中这个SSTable文件对应的Table结构指针。这样就将不同的sstable文件像cache一样进行管理。

leveldb通过LRUHandle 结构将hash值相同的所有元素串联成一个双向循环链表,通过指针next_hash来解决hash 碰撞。

2、HandleTable

leveldb通过HandleTable维护一个哈希表:

class HandleTable {
 public:
  HandleTable() : length_(0), elems_(0), list_(NULL) { Resize(); }
  ~HandleTable() { delete[] list_; }

  LRUHandle* Lookup(const Slice& key, uint32_t hash);
  LRUHandle* Insert(LRUHandle* h);
  LRUHandle* Remove(const
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值