分析代码:https://github.com/aronszanto/sLSM-Tree

文章目录

  • LSM
    • LSM参数
    • LSM --- insert_key
    • LSM --- delete_key
    • LSM --- lookup
  • SkipList 跳表
    • SkipList --- insert_key

LSM

LSM参数

参数名 demo给的默认值 参数含义
eltsPerRun 800 每个run(skiplist)最大的KV数目
numRuns 20 内存层最多能持有多少 跳表
merged_frac 1.0 每次merge的时候merge多少占比的缓冲区runs,如果是1全部merge。
代码中用于计算_frac_runs_merged
bf_fp 0.001 BF的false positive
pageSize 1024 栅格指针数目
diskRunsPerLevel 20 disk的runs有多少层

LSM — insert_key

void insert_key(K &key, V &value) {if (C_0[_activeRun]->num_elements() >= _eltsPerRun) {++_activeRun;}if (_activeRun >= _num_runs) {do_merge();}C_0[_activeRun]->insert_key(key, value);filters[_activeRun]->add(&key, sizeof(K));
}

如果当前_activeRun指向的跳表满了,_activeRun++,指向下一个跳表

如果跳表都满了,执行do_merge。do_merge会把跳表落盘、清空跳表vector C_0和布隆过滤器vector filters

插入元素:C_0 和 filters

注意:插入也包含了修改的功能,详解这个文章:知乎 - 深入浅出分析LSM树(日志结构合并树)

LSM — delete_key

极其简单,插入墓碑标记 tombstone

原理可以看这个文章:知乎 - 深入浅出分析LSM树(日志结构合并树)

void delete_key(K &key) {insert_key(key, V_TOMBSTONE);
}

LSM — lookup

从新跳表往老跳表查找for (int i = _activeRun; i >= 0; --i) {

小于最小 or 大于最大 or not BF中可能存在

if (key < C_0[i]->get_min() || key > C_0[i]->get_max() || !filters[i]->mayContain(&key, sizeof(K)))

如果 ∈ [ m i n , m a x ] \in [min, max] ∈[min,max],并且BF认为可能存在,则在跳表中查找

src/skipList.hpp:171 lookup 函数两个形参都是传引用,忽略Clion的静态代码提示

如果找到了,判断一下是否为墓碑,不是墓碑就找到了


如果不在C_0,扫描所有的disk_level

SkipList 跳表

结点有3个成员变量

const K key;
V value;
SkipList_Node<K, V, MAXLEVEL> *_forward[MAXLEVEL + 1];


跳表的成员变量

K _minKey;
K _maxKey;
unsigned long long _n;
size_t _maxSize;
int cur_max_level;
Node *p_listHead;
Node *p_listTail;
uint32_t _keysPerLevel[MAXLEVEL];

构造的时候各层的首结点指向尾结点,cur_max_level = 1

SkipList(const K minKey, const K maxKey) : p_listHead(NULL), p_listTail(NULL),cur_max_level(1), max_level(MAXLEVEL), min((K) NULL), max((K) NULL),_minKey(minKey), _maxKey(maxKey), _n(0) {p_listHead = new Node(_minKey);p_listTail = new Node(_maxKey);for (int i = 1; i <= MAXLEVEL; i++) {p_listHead->_forward[i] = p_listTail;}
}

SkipList — insert_key

level从cur_max_level走到最小为1

如果下一个结点比key要小,走到下一个结点

下一个结点小于才能往下跳,如果等于则不会跳,保证后一句代码有机会跳到等于key的结点

        for (int level = cur_max_level; level > 0; level--) {while (currNode->_forward[level]->key < key) {currNode = currNode->_forward[level];}update[level] = currNode;}

跳到下一个结点的最底层(level 1)

        currNode = currNode->_forward[1];

更新跳表的情况(insert包含了增加 + 更新)

        if (currNode->key == key) {// update the value if the key already existscurrNode->value = value;
        } else {// if key isn't in the list, insert a new node!int insertLevel = generateNodeLevel();if (insertLevel > cur_max_level && insertLevel < MAXLEVEL - 1) {for (int lv = cur_max_level + 1; lv <= insertLevel; lv++) {update[lv] = p_listHead;}cur_max_level = insertLevel;}currNode = new Node(key, value);// fixme: 我觉得cur_max_level应该改为 min(insertLevel, MAXLEVEL - 1)for (int level = 1; level <= cur_max_level; level++) {currNode->_forward[level] = update[level]->_forward[level];update[level]->_forward[level] = currNode;}++_n;}

https://github.com/aronszanto/sLSM-Tree/blob/master/src/skipList.hpp#L132

Redis跳表(代码:t_zset.c

https://redisbook.readthedocs.io/en/latest/internal-datastruct/skiplist.html

sLSM-Tree 源码学习相关推荐

  1. JDK11源码学习05 | HashMap类

    JDK11源码学习05 | HashMap类 JDK11源码学习01 | Map接口 JDK11源码学习02 | AbstractMap抽象类 JDK11源码学习03 | Serializable接口 ...

  2. 第八课 k8s源码学习和二次开发原理篇-KubeBuilder使用和Controller-runtime原理

    第八课 k8s源码学习和二次开发原理篇-KubeBuilder使用和Controller-runtime原理 tags: k8s 源码学习 categories: 源码学习 二次开发 文章目录 第八课 ...

  3. 开源中国源码学习UI篇(一)之FragmentTabHost的使用分析

    最近在有意读开源中国的源码来提升Android开发能力,开通博客来提升一下自己的积极性- -我参考的是开源中国2.2版,完整源码地址为http://git.oschina.net/oschina/an ...

  4. 开源中国源码学习UI篇(二)之NavigationDrawer+Fragment的使用分析

    前文链接:开源中国源码学习UI篇(一)之FragmentTabHost的使用分析 开源中国2.2版,完整源码地址为:http://git.oschina.net/oschina/android-app ...

  5. Vue源码学习 - 组件化一 createComponent

    Vue源码学习 - 组件化一 createComponent 组件化 createComponent 构造子类构造函数 安装组件钩子函数 实例化 VNode 总结 学习内容和文章内容来自 黄轶老师 黄 ...

  6. ERNIE源码学习与实践:为超越ChatGPT打下技术基础!

    ★★★ 本文源自AlStudio社区精品项目,[点击此处]查看更多精品内容 >>> ERNIE学习与实践:为超越ChatGPT打下技术基础! ERNIE是BERT相爱相杀的好基友,由 ...

  7. 文心ERNIE源码学习与实践:为超越ChatGPT打下技术基础!

    ERNIE学习与实践:为超越ChatGPT打下技术基础! ERNIE是BERT相爱相杀的好基友,由ERNIE发展起来的文心大模型,是GPT3.0的强劲竞争对手,未来还会挑战ChatGPT的江湖地位! ...

  8. Shiro源码学习之二

    接上一篇 Shiro源码学习之一 3.subject.login 进入login public void login(AuthenticationToken token) throws Authent ...

  9. Shiro源码学习之一

    一.最基本的使用 1.Maven依赖 <dependency><groupId>org.apache.shiro</groupId><artifactId&g ...

  10. mutations vuex 调用_Vuex源码学习(六)action和mutation如何被调用的(前置准备篇)...

    前言 Vuex源码系列不知不觉已经到了第六篇.前置的五篇分别如下: 长篇连载:Vuex源码学习(一)功能梳理 长篇连载:Vuex源码学习(二)脉络梳理 作为一个Web前端,你知道Vuex的instal ...

最新文章

  1. 热泵精馏_精馏干货16 || 分子蒸馏
  2. java并发实战编程pdf_「原创」Java并发编程系列25 | 交换器Exchanger
  3. SQL递归查询(with as)
  4. 深入理解Hadoop之HDFS架构
  5. 只开窗不镀锡_推拉窗和平开窗哪个好?
  6. CentOS部署OpenStack过程-网络服务
  7. 查找国外硕士博士论文
  8. 一文读懂反向传播算法原理
  9. html js 在文本框选择自动计算乘,怎么让JS实现在文本框中输入数字时,同时输出这个数字,并再输出一个乘以0.39的值?...
  10. 身份实名认证API开发文档
  11. macos的pycharm无setting选项
  12. CSS 语法 网贷黑户正规查询系统,通过CSS选择器控制怎么查自己带过的网贷数量做一个个人网贷记录查询软件
  13. 跌宕起伏的区块链行业2022年如何发展?10大行业趋势
  14. rtl语言_21个最佳RTL WordPress主题(从右到左语言)
  15. 做美食与互联网产品的关系
  16. CS231n系列之 Lecture1:Introduction
  17. Go语言结构体指针为nil时的小坑
  18. In-memory Computing with SAP HANA读书笔记 - 第二章:SAP HANA overview
  19. js 地理位置查询经纬度定位地图
  20. 电脑上设置wifi热点的代码

热门文章

  1. Flume之——配置多个Sink源(一个Source对应多个Channel和Sink)
  2. Android中圆形图的几种实现方式
  3. 新浪云node加mysql_通过新浪云部署NideShop微信小程序商城(基于Node.js+MySQL+ThinkJS)...
  4. linux more命令用法,linux more命令详解
  5. php智能识别收货地址信息
  6. fileupload实现多文件批量上传
  7. poj 3666 Making the Grade zoj 3512 Financial Fraud 左偏树 or dp
  8. 艾美捷MTT细胞增殖检测试剂盒测定方案
  9. 实现echarts图表响应式效果
  10. MATLAB 遗传算法