redis源码之:跳跃表skiplist

news2024/11/15 19:34:36

老规矩,先来看看大致结构:
在这里插入图片描述

debug所用demo如下:

#include "src/server.h"

void testSDS();
void testAlign();
void testZipList();
void testSkipList();
void testQuickList();

int main(int argc, char **argv) {
//    testAlign();
//    testSDS();
//    testZipList();
//    testQuickList();
    testSkipList();
}

void testSkipList(){
    zskiplist *my_list = zslCreate();
    sds sds01 = sdsnew("0001a");
    sds sds02 = sdsnew("0002a");
    sds sds03 = sdsnew("0003a");
    sds sds04 = sdsnew("0004a");
    sds sds05 = sdsnew("0005a");
    zslInsert(my_list,1,sds01);
    zslInsert(my_list,2,sds02);
    zslInsert(my_list,3,sds03);
    zslInsert(my_list,4,sds04);
    zslInsert(my_list,5,sds05);
    
}

skiplist本质是有序的链表,每个节点可能会属于多层,至少属于一层,是个典型的以空间换时间的结果,大致的数据结构如下:

typedef struct zskiplistNode {//skiplist节点
    sds ele;              //节点字符串内容
    double score;         //节点分值,主要用于插入排序比对
    struct zskiplistNode *backward; //除了header节点和header后的一个节点,其余节点的backward都指向前面节点
    struct zskiplistLevel {  
        struct zskiplistNode *forward;//当前节点在当前层,指向的下一个节点
        unsigned long span; //到下一个节点间隔多少个元素,即步长。
    } level[];  //每个节点都可能属于多层
} zskiplistNode;

typedef struct zskiplist {
    struct zskiplistNode *header, *tail;//定义头结点和尾节点
    unsigned long length; //node节点数量
    int level; //当前list用了多少层
} zskiplist;

从上图可以看出:
level0:header-》node0-》node1-》node2->node3
level1和level2都是:header-》node0->node2

一、创建skiplist并初始化
在这里插入图片描述

二、节点插入
节点插入是构建skiplist最核心的逻辑,主要调用zslInsert()方法:
在这里插入图片描述

关于level的生成:

int zslRandomLevel(void) {
  int level = 1;
  //0-65535 <0.25*65535的概率
   while ((random()&0xFFFF) < (ZSKIPLIST_P * 0xFFFF))
       level += 1;//每次加一的概率为0.25
   return (level<ZSKIPLIST_MAXLEVEL) ? level : ZSKIPLIST_MAXLEVEL;
}

那么为1的概率:1-0.25
大于1的概率:0.25
为2的概率:0.25*(1-0.25)
为3的概率:0.25* 0.25*(1-0.25)
为n的概率:0.25^n-1 * (1-0.25),
n最大为32

delete和update相对没什么新的技术点,这里就不做更深入研究了。

与红黑树对比有何优势劣势:
同二分查找,红黑树和跳跃表的时间复杂度都能达到Olog(n).,但跳跃表实现上更加简单易懂;
跳跃表牺牲一定的空间用于层级管理,但是层级中只是保存了节点指针,相对而言,空间的牺牲较小;
跳跃表的插入删除影响的局部范围小并发能力强,红黑树可能会涉及树的旋转调整,影响较大;
跳跃表可以很方便通过层级节点定位实现范围查找;

Redis源码剖析之跳表(skiplist)
【Redis】skiplist跳跃表
Skiplist论文原地址

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/642777.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

flutter DevTools(1)

在VSCODE中调试 第一步&#xff1a; ① 切换到 vscode 的调试和运行模式, ② 配置好 .vscode 中的启动项 launch.json ③ 共有四种模式 [1] debug : 模式编译产物适合纯 Flutter 侧代码的开发、调试 [2] profile : 的用来做性能分析和测试 [3] release : 的用于打包发布 [4]…

DBeaver连接(DM)达梦数据库

DBeaver连接(DM)达梦数据库 文章目录 1.下载驱动2.DBeaver新建驱动3.连接DM数据库4.JDBC 接口 DBeaver是一款功能强大的数据库管理工具&#xff0c;可以连接多种类型的数据库。下面是连接达梦数据库的步骤&#xff1a; 打开DBeaver并点击“连接”按钮。在弹出的“连接”对话框中…

几个直接在TigerISP上查看全志芯片接Sensor分辨率的方法

TigerISP是全志提供的量产工具&#xff0c;在连接TigerISP时需要填写Sensor名称、Sensor分辨率、Sensor帧率及选择ISP通道、Vich、Wdr模式等… 准备工作&#xff1a;打开debugfs 操作&#xff1a;adb shell进入系统后输入以下两个命令&#xff1a; mount -t debugfs mone /s…

如何成功实施一个数据治理项目?实施步骤有哪些?

企业数字化转型以数据为中心&#xff0c;通过数据驱动业务发展、管理协同和运营。因此&#xff0c;数字化转型关键在于数据&#xff0c;数据治理则需先行。从而更好激发数据生产要素潜能&#xff0c;实现业务数据化、数据价值化&#xff0c;助力企业数字化转型。 那么何为数据…

零代码产品新秀敲敲云与明星产品简道云、轻流对比

零代码产品正在成为当今技术领域的热门话题。随着人们对更快、更简单的开发流程的需求不断增加&#xff0c;零代码产品正在作为一种解决方案得到越来越多的关注。 零代码技术源于低代码技术&#xff0c;与低代码不同的是&#xff0c;零代码不需要任何代码编写。这意味着即使是普…

让人头疼的时序数据预测,这个方案居然三步就搞定了?

数字化时代&#xff0c;时序数据预测已经从一种理论研究转变为各行业实际运营中的关键工具&#xff0c;这种预测可以覆盖广泛的业务领域&#xff0c;比如&#xff1a; 利用历史销售数据进行未来销售趋势的预测 根据既往的电力消耗数据预估未来电力需求 基于过去的股市行情预测未…

释放 OpenAI 和 ESP-BOX 的力量:ChatGPT 与乐鑫 SoC 融合指南

当前&#xff0c;我们正见证着一场技术革命&#xff0c;而 OpenAI 正处于这场变革的最前沿。其中最激动人心的创新之一就是ChatGPT&#xff0c;它运用自然语言处理的力量&#xff0c;打造出更加引人入胜、直观的用户体验。而将 OpenAI 的 API 与物联网设备相结合&#xff0c;更…

Spring Cloud Kubernetes配置使用详情

目录 一、 为什么你需要 Spring Cloud Kubernetes&#xff1f; 二、 Starter 三、 用于 Kubernetes 的 DiscoveryClient 四、Kubernetes 原生服务发现&#xff08;service discovery&#xff09; 五、Kubernetes PropertySource 的实现 1、使用 ConfigMap PropertySource …

Unreal Engine 5.1 AI行为树基础入门

ai行为树理解起来其实是npc根据自身一些情况进行一些逻辑执行&#xff0c;而这些逻辑是我们使用ai行为树去实现的。 ai行为树需要一个寻路网格体边界体积&#xff0c;在ue引擎中&#xff0c;体积Actor分为多种&#xff0c;寻路网格体边界体积只是其中的一种。 关于其它的体积&a…

leetcode:448. 找到所有数组中消失的数字(python3解法)

难度&#xff1a;简单 给你一个含 n 个整数的数组 nums &#xff0c;其中 nums[i] 在区间 [1, n] 内。请你找出所有在 [1, n] 范围内但没有出现在 nums 中的数字&#xff0c;并以数组的形式返回结果。 示例 1&#xff1a; 输入&#xff1a;nums [4,3,2,7,8,2,3,1] 输出&…

初识网络之https的加密与解密

目录 一、https协议的概念 二、加密的概念 三、为什么需要加密 四、常见的加密方式 1. 对称加密 2. 非对称加密 五、数据摘要&#xff08;数据指纹&#xff09; 六、数据签名 七、加密方案 1. 方案一&#xff1a;只使用对称加密 2. 方案二&#xff1a;只使用非对称加…

院士大咖齐聚蓉城,论道“疑难眼眶病学术论坛”

“全国疑难眼眶病诊疗带教基地”成立&#xff0c;力促“病有所医 ” 大咖云集&#xff0c;这是一场眼科界领军人汇聚一堂&#xff0c;聚焦疑难眼眶病突破性学术成果及前沿技术的高规格论坛; 规模空前&#xff0c;这是一场围绕眼眶病诊疗技术议题深入探讨交流&#xff0c;为我国…

行为型设计模式08-职责链模式

&#x1f9d1;‍&#x1f4bb;作者&#xff1a;猫十二懿 ❤️‍&#x1f525;账号&#xff1a;CSDN 、掘金 、个人博客 、Github &#x1f389;公众号&#xff1a;猫十二懿 职责链模式 1、职责链模式介绍 责任链模式&#xff08;Chain of Responsibility Pattern&#xff09;…

seatunnel入门案例,集群模式

目录 安装部署 解压 环境变量 安装plugin 添加资源jar包 SEATUNNEL 配置文件 env&#xff1a;环境设置 source&#xff1a;数据源设置 sink&#xff1a;数据去向设置 transform: 数据转换设置 运行方式 seatunnel 引擎(zeta) 本地模式 集群模式 安装部署 解压 tar…

Centos7在Nginx中配置SSL证书

我的环境 阿里云轻量应用服务器&#xff08;Linux, Centos7.9 x64&#xff09; 一、申请免费SSL证书 一年可以创建20个 下载证书&#xff08;我是Nginx服务器&#xff09; 下载到本地后&#xff0c;打开有两个文件&#xff1a; 二、将SSL证书文件上传至服务器 通过WinScp拖…

图像sensor的特性和驱动解析

1、更换OV9712并且做配置更改和测试 1.1、更改配置脚本 修改Hi3518E_SDK_V1.0.3.0\package\mpp\sample\Makefile.param 1.2、测试运行 运行官方SDK sample的测试版本&#xff08;打包到本地&#xff09; 运行ORTP传输的测试版本&#xff08;RTP实时预览&#xff09; 1.3、更…

如何高效合理规划每天的工作?

如何高效合理规划每天的工作&#xff1f; 〇、基本原则 梳理工作&#xff0c;明确目标。&#xff08;SMART法则&#xff09;轻重缓急&#xff0c;排优先级。&#xff08;四象限管理法则&#xff09;要事第一&#xff0c;尽管去做。&#xff08;GTD 理论&#xff09;限时deadl…

新买的电脑怎么用U盘重装系统?新买的电脑用U盘重装系统教程

新买的电脑怎么用U盘重装系统&#xff1f;用户新买了电脑&#xff0c;想知道怎么用U盘来重装新买的电脑&#xff0c;用U盘来重装电脑其实非常简单&#xff0c;用户需要准备一个U盘&#xff0c;然后完成U盘启动盘的安装&#xff0c;接着按照以下分享的新买的电脑用U盘重装系统教…

[Hadoop安装配置 ]

目录 前言: 执行步骤: 1 创建好目录文件,上传Hadoop版本压缩包,一般都是tar.gz 结尾包 1.1这里压缩包可以直接拖拽到指定虚拟机目录下, 例如xshell连接指定虚拟机, 然后可以拖拽,如果拖拽不了,那就需要设置一下配置, 或者 使用 xftp工具 连接xshell 然后上传文件 2 解压…

pandas---数据合并(concat、append、merge)

1. concat函数 pd.concat([data1, data2], axis1) 按照行或列进行合并&#xff0c;axis0为列索引&#xff0c;axis1为行索引。 df1 make_df([1, 2], [A, B]) df2 make_df([3, 4], [A, B]) display(df1, df2) # 默认上下合并&#xff0c;垂直合并 pd.concat([df1, df2]) …