redis源码之:跳跃表skiplist

news/2025/3/19 23:42:26/

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

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.25return (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.ppmy.cn/news/366270.html

相关文章

docker-compose 构建 Kafka 容器

在终端中创建一个名为 kafka 的目录&#xff0c;并进入该目录&#xff1a; mkdir kafka cd kafka创建一个名为 docker-compose-kafka.yml 的文件并打开它。将以下代码复制到文件中&#xff1a; sudo touch docker-compose-kafka.ymlversion: 2 services:zookeeper:image: wur…

utorrent下载速度慢

问题描述&#xff1a; 使用校园网从bt下载东西时下载速度特别慢&#xff0c;最高速度只有三四百k&#xff0c;检查磁盘使用百分比并不高&#xff0c;uTorrent中磁盘统计的缓存只有十几M。 解决方案&#xff1a; 打开网络属性&#xff0c;我用的是网线&#xff0c;属性如下所…

通过bt下载旧版debian镜像

我在上一篇文章中叙述了使用jigdo-lite下载debian镜像&#xff0c;我试验后&#xff0c;发现速度还是很慢&#xff0c;于是就有了这篇文章。 debian镜像站提供了bt下载方式&#xff0c;以debian9.11为例&#xff0c;在它的amd64目录下有bt-cd目录&#xff0c;这意味着你可以使用…

tinyTorrent: 从头写一个 Deno 的 BitTorrent 下载器

BitTorrent 想必大家应该都不陌生&#xff0c;中文名叫做“种子”。 “种子”到底是什么&#xff1f;我一直不太清楚。在写这个项目之前&#xff0c;我对“种子”的认识停留在使用层面。 当我想找一个资源的时候&#xff0c;我会搜索 xxx 种子&#xff0c;一般会在一些非常不…

mysql insert 慢_MYSQLinsert速度过慢

MYSQLinsert速度过慢最近在用MySQL做存储,测试中发现插入数据太慢了,插入速度只有20 MY SQL insert 速度过慢 最近在用MySQL做存储,测试中发现插入数据太慢了,插入速度只有20-30 条/秒,后来查资料后,将MySQL的1个参数:innodb_flush_log_at_trx_commit,1改为了0(修改方法…

传统方式不同的变态下载(BT)

BT下载是互联网下载方式之一。BT是一种互联网的P2P传输协议&#xff0c;全名"BitTorrent"&#xff0c;中文名"比特流" &#xff0c;已发展成一个有广大开发者群体的开放式传输协议。BT下载是通过一个P2P下载软件来实现的&#xff0c;具有下载的人越多下载速…

PC机装Openwrt19.07做BT下载机的详细配置

安装和相关的samba 共享等配置可以看另一篇&#xff1a;https://blog.csdn.net/lggirls/article/details/106228566 这里使用的是Aria2。 transmission的配置还没有搞清楚 1. 所需安装的插件 。 圈出来的两个是 web gui界面工具&#xff0c;也就是和打开迅雷软件类似的图形…

网友传秘方:解决新版SP1中BT下载慢问题

<script languagejavascript srchttp://www.shiqiaotou.com/donetk/Header.js></script> 声明&#xff1a;此文拒绝转载&#xff0c;否则将保留追究法律责任的权利。 自微软将Windows Vista SP1测试版更新到V.658后&#xff0c;很多网友都反应下载速度&#xff0c;…