Redis list源码分析

告别龟速下载!保姆级教程:用离线包5分钟搞定Arduino IDE的STM32开发环境(附最新库文件) 本文提供了一套完整的Arduino IDE离线配置方案,帮助开发者5分钟快速搭建STM32开发环境。通过详细的板支持包安装指南、文件校验方法和常见问题解决方案,彻底解决GitHub下载慢的问题,提升开发效率。 阅读详情

Redis List是一种基于双向链表实现的数据结构,其底层数据结构由两个指针指向前一个元素和后一个元素,以此构成一个双向链表。在Redis中,List提供了一系列的操作方法,例如添加元素、删除元素、获取元素等。

下面我们来分析一下Redis List的源码实现:

Redis List数据结构

Redis List的底层数据结构由以下结构体构成:

typedef struct listNode {
    struct listNode *prev;    //前一个元素指针
    struct listNode *next;    //后一个元素指针
    void *value;              //元素值
} listNode;

typedef struct list {
    listNode *head;           //链表头结点指针
    listNode *tail;           //链表尾结点指针
    unsigned long len;        //链表长度
    void *(*dup)(void *ptr);  //元素复制函数指针
    void (*free)(void *ptr);  //元素释放函数指针
    int (*match)(void *ptr, void *key);  //元素比较函数指针
} list;

其中,listNode表示链表中的一个节点,其包含一个指向前一个节点的指针prev、一个指向后一个节点的指针next、以及一个指向存储在该节点中的值的指针value。list则表示整个链表,包括一个指向头结点的指针head、一个指向尾结点的指针tail、链表长度len,以及用于对元素进行复制、释放和比较的函数指针。

Redis List操作函数

Redis List提供了一系列操作函数,包括:

  • listCreate():创建一个新的List结构体并返回其指针。
  • listAddNodeHead():将一个新元素添加到链表的头部。
  • listAddNodeTail():将一个新元素添加到链表的尾部。
  • listInsertNode():将一个新元素插入到指定节点之前或之后。
  • listDelNode():从链表中删除指定节点。
  • listIndex():获取链表中指定索引处的元素。
  • listLen():获取链表的长度。
  • listDup():复制整个链表。
  • listSearchKey():查找链表中与指定key匹配的元素。
  • listRotate():将链表中的最后一个元素移到头部。

其中,listAddNodeHead()和listAddNodeTail()是最基本的操作函数,它们用于在链表头部和尾部添加新元素,操作函数的实现如下:

listNode *listAddNodeHead(list *list, void *value) {
    listNode *node;

    node = zmalloc(sizeof(*node));     //分配新节点的空间
    node->value = value;               //设置节点值
    if (list->len == 0) {              //如果链表为空,则新节点既是头节点也是尾节点
    list->head = node;
    list->tail = node;
    node->prev = NULL;
    node->next = NULL;
} else {                            //否则将新节点插入到链表头部
    node->prev = NULL;
    node->next = list->head;
    list->head->prev = node;
    list->head = node;
}
list->len++;                        //更新链表长度
return node;
}

listNode *listAddNodeTail(list *list, void *value) {
listNode *node;
node = zmalloc(sizeof(*node));     //分配新节点的空间
node->value = value;               //设置节点值
if (list->len == 0) {              //如果链表为空,则新节点既是头节点也是尾节点
    list->head = node;
    list->tail = node;
    node->prev = NULL;
    node->next = NULL;
} else {                            //否则将新节点插入到链表尾部
    node->prev = list->tail;
    node->next = NULL;
    list->tail->next = node;
    list->tail = node;
}
list->len++;                        //更新链表长度
return node;
}

在这两个函数中,我们首先通过zmalloc()函数分配一个新节点的内存空间,并将节点的值设置为value。然后,我们根据链表是否为空,将新节点插入到链表头部或尾部。如果链表为空,那么新节点既是头节点也是尾节点;否则,我们需要将新节点插入到链表的头部或尾部,并更新链表的头结点指针和尾结点指针。最后,我们还需要更新链表的长度,将其加1。

除了基本的添加和删除操作,Redis List还提供了一些其他的操作函数,例如listIndex()函数用于获取指定索引处的元素,listSearchKey()函数用于查找与指定key匹配的元素,以及listRotate()函数用于将链表中的最后一个元素移到头部。这些函数的具体实现可以参考Redis的源代码。

scratch lenet(4): 开根号的C语言实现 使用C语言,分别使用二分法、牛顿法、卡马克快速法,求解正实数的开根号。包括公式推导、代码实现、运行结果,不使用任何第三方库和C标准库的数学库。 阅读详情

相关推荐

手把手教你学Simulink--双足机器人分数阶PID控制仿真

分数阶PID(Fractional-order PID, FOPID)控制是一种先进的控制策略,它扩展了传统的整数阶PID控制器的概念。FOPID控制器允许积分和微分项的阶次不是严格的整数,而是可以是任意实数,这为系统提供了更多的设计自由度,并可能带来更好的性能。在双足机器人控制中,分数阶PID控制可以用于改善机器人的平衡控制、轨迹跟踪等任务的性能。下面我们将详细介绍如何使用Simulink进行基于分数阶PID控制方法的双足机器人仿真研究。

MHD0815的博客 878

Redis从精通到入门——数据类型List实现源码详解

Redis数据类型之List详解List简介List的常用操作应用场景List实现ziplist源码阅读图解Ziplistzlentry数据结构quickList源码阅读图解quickList List简介 Redis中List列表中的每个字符串成为元素,一个列表最多可以存储2^32 - 1个元素。     在Redis中,可以对列表两端插入(LPUSH)和弹出(LPOP),还可以获取指定范围的元素列表、获取指定索引下标的元素等。列表是一种比较灵活的数据结构,可以充当

“实用”是软件压倒一切的要素 4408

CTFshow-pwn入门-前置基础pwn32-pwn34

CTFshow-pwn入门-前置基础pwn32-pwn34

你们de4月天的博客 1129

Redis之列表对象源码阅读

listTypeTryConversion:尝试将列表对象转换成linkedlist编码 void listTypeTryConversion(robj *subject, robj *value) { // 确保 subject 为 ZIPLIST 编码 if (subject->encoding != REDIS_ENCODING_ZIPLIST) return; ...

m0_37343985的博客 280

打包可以在Hadoop 3.3.1和Hive 3.1.2上使用的Tez 0.10.1 minimal

编译打包可以在Hadoop 3.3.1和Hive 3.1.2上使用的Tez 0.10.1

qq_42013533的博客 2615

FPGA数字下变频实战:用Vivado DDS IP核实现IQ采样与频率校正(附MATLAB仿真对比)

本文提供了一份基于Vivado DDS IP核实现FPGA数字下变频(DDC)的完整工程指南。详细阐述了IQ采样的原理、DDC链路构建、DDS频率校正的工程实现,并重点介绍了如何利用MATLAB搭建黄金参考模型进行全链路仿真与对比验证,分享了关键的调试技巧与性能优化建议。

t1u2v的博客 810

Redis源码剖析--列表t_list实现

Redis中的列表对象比较特殊,在版本3.2之前,列表底层的编码是 ziplist 和 linkedlist 实现的, 但是在版本3.2之后,重新引入了一个 quicklist 的数据结构,列表的底层都由quicklist实现。 这边是在看源码和实际验证的时候发现的区别,然后上网查证。由于目前使用的redis基本都在3.2了, 而且老版本肯定会被取代, 所以我们只分析3.2版本之后的实现。对于老...

harleylau的博客 2153

多目标进化算法——NSGA-II(python实现)

NSGA-II(python实现)--最全注释,痴呆能懂--

no___good的博客 5278

Redis源码剖析--列表list

上一篇博客Redis源码剖析–快速列表 带大家一起剖析了quicklist这个底层数据结构的实现原理。Redis对外开放的列表list结构就是采用quicklist作为底层实现(在新版本的Redis源码中,不再采用ziplist和sdlist两种结构,而是统一采用quicklist)。有关列表键的实现源码在t_list.c文件中,大家可以边看源码边看这篇博客,一起来理解。List概述其实在[Redi

ZeeCoder 1805

Windows系统监控实战:Grafana+Prometheus+node_exporter保姆级配置指南(含常见问题解决)

本文提供了一份详尽的Windows系统监控实战指南,详细讲解了如何从零部署Grafana、Prometheus和node_exporter(实际为windows_exporter)监控栈。内容涵盖核心组件认知、分步配置解析、高级生产环境考量,并重点针对配置过程中常见的“No Data”问题提供了系统性的排查手册,旨在帮助用户快速搭建稳定可靠的系统资源监控平台。

weixin_29197835的博客 1006

电子元器件-接口电路篇:RS-232、RS485/422、I2C、SPI、USB、网口

以上规定说明了RS-232C 标准对逻辑电平的定义。对于数据(信息码):逻辑“1”的传输的电平为-3V~-15V,逻辑“0”传输的电平为+3V~+15V;对于控制信号;接通状态(ON)即信号有效的电平为+3V~+15V,断开状态(OFF)即信号无效的电平为-3V~-15V,也就是当传输电平的绝对值大于3V 时,电路可以有效地检查出来;

qq_60226558的博客 887

Redis 5.0数据结构之压缩列表ziplist源码详解(一)

Redis基于C语言开发,由于C并未内置链表,因此Redis自己实现了一系列链表,有双端链表linkedlist、压缩列表ziplist、快速链表quicklist等,本篇将从源码角度展现压缩列表ziplist。

MSSPLANET的博客 1124

STM32Cube高效开发教程<基础篇>(一)----概述

一、 STM32系列器件和开发工具发展历史声明:本人水平有限,博客可能存在部分错误的地方,请广大读者谅解并向本人反馈错误。本专栏博客参考《STM32Cube高效开发教程(基础篇)》,有意向的读者可以购买正版书籍辅助学习,本书籍由王维波老师、鄢志丹老师、王钊老师倾力打造,书籍内容干货满满。一、 STM32系列器件和开发工具发展历史。

我的博客 1171

redis之list源码分析

list的数据结构 redis的list的结构为quicklist,并非简单的类似java的LinkedList链表或者ArrayList数组,而是将链表和数值结合的一种数据结构。 宏观上list是一个quicklist链表,通过双向指针前后连接,但是链表的每一个节点是一个ziplist字节数组,在字节数组上保存list的数据。默认配置下,每个ziplist最大为8K字节,在向满了的ziplist插入新数据时或拆分或新建ziplist来存放新数据。 typedef struct quicklist {

极客神殿 311

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

redis源码分析——list

文章目录quicklist数据结构quicklist的创建 quicklist quicklist是经过lzf算法压缩的ziplist列表 数据结构 typedef struct quicklist { quicklistNode *head; quicklistNode *tail; unsigned long count; /* total count o...

JnX的专栏 341

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

Redis源码分析 List实现

在版本3.2之前,Redis中的列表是 ziplist 和 linkedlist 实现的,在3.2之后,由quicklist实现。 双向链表linkedlist在表的两端进行push和pop操作非常方便,但是地址不连续,而且需要保持额外的指针。 ziplist是连续内存,存储效率高。但不利于修改操作,插入和删除需要重新申请和释放内存。 先看quicklist数据结构 /* Nod...

深度Java 1095

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

redis list 链表源码分析

// 双向链表 typedef struct listNode { struct listNode *prev; struct listNode *next; void *value; } listNode; typedef struct list { // 表头节点 listNode *head; // 表尾节点 listNo...

weixin_41791402的博客 218

Redis 6.0 源码阅读笔记(5) -- List 数据类型源码分析

使用GDB跟踪Redis源码list push过程 127.0.0.1:6379> LPUSH runoobkey redis runoobkey key redis value 当你push多个时:127.0.0.1:6379> LPUSH runoobkey redis2 redis3 存储的结构 redis 对于 List 的存储共有 3 种存储形式,其中 OBJ_ENCODING_LINKEDLIST已经彻底废弃不再讨论,其它两种存储形式的内

alpha_love的博客 555

redis高级篇之redis源码分析List类型quicklist底层演变 答疑159节

quicklist是 Redis 中一种高效的数据结构,通过结合双向链表和ziplist的优点,既提高了内存利用率,又保证了操作效率。每个quicklist节点包含一个ziplist,所有节点上的ziplist里面的元素首尾相连,形成整个quicklist的完整数据。这种设计非常适合 Redis 的使用场景,特别是对于需要高效存储和操作大量小数据项的应用。希望这篇详细的分析能帮助你更全面地理解quicklist的工作原理及其在 Redis 中的重要性。如果你还有其他问题或想深入探讨的内容,请随时告诉我!

2401_86733530的博客 1165

Redis学习之list底层链表源码分析

Redis底层链表的源码分析: 一.链表结点的结构(单个结点): // listNode 双端链表节点 typedef struct listNode { // 前置节点 struct listNode *prev; // 后置节点 struct listNode *next; // 节点的值 void *...

Y先森0.0 244

Redis高级之List底层源码(3)-List源码分析

在了解Redis中的list数据结构之前,先来回顾和学习一下单向链表和双向链表,以便更好的学习和理解Redis中List的底层数据结构Redis链表。

geminigoth的博客 201

Redis源码分析(十二)——列表类型t_list

继前面对字符串、

艰难困苦如同欢乐,终将成为人生最后的财富 1191

redis源码分析(四)、redis命令学习总结—链表List

一、链表List 链表被广泛用于实现 Redis 的各种功能, 比如列表键, 发布与订阅, 慢查询, 监视器, 等等。每个链表节点由一个 listNode 结构来表示, 每个节点都有一个指向前置节点和后置节点的指针, 所以 Redis 的链表实现是双端链表。每个链表使用一个 list 结构来表示, 这个结构带有表头节点指针、表尾节点指针、以及链表长度等信息。因为链表表头节点的前置节点和表尾节

chen 531

Redis 源码分析四:skip list

Skip list是一种多层次的有序链表,通过随机地选择层数来实现插入、查找和删除都是O(logn)的时间复杂度(和平衡树同样的效率,但实现比平衡树简单很多)。关于skip list的具体介绍可以参见William Pugh的论文:Skip Lists: A Probabilistic Alternative to Balanced Trees 。也可以参见上一篇日志。如下图,为一个简单的

754

Redis源码分析:数据结构之链表(list)

Redis源码分析:数据结构之链表(list)

qq_41317716的博客 447

Redis 6.0 源码阅读笔记(5)-List 数据类型源码分析

文章目录1. 存储的结构2. 数据存储源码分析 1. 存储的结构 redis 对于 List 的存储共有 3 种存储形式,其中 OBJ_ENCODING_LINKEDLIST已经彻底废弃不再讨论,其它两种存储形式的内存结构如下图示例: OBJ_ENCODING_ZIPLIST:底层结构类似数组,使用特定属性保存整个列表的元信息,如整个列表占用的内存大小,列表保存的数据开始的位置,列表保存的数据的个数等,其保存的数据被封装在 zlentry zlentry 是压缩列表保存数据的节点,其结构与 zipli

谈谈1974 966
上一篇: 说说NetCore线程池的详细原理
下一篇: 哈夫曼压缩算法原理
.NET跨平台
博客等级 码龄15年 6066粉丝 738原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值