Redis核心数据结构之SDS和链表(三)

news2024/11/25 0:25:46

SDS与C字符串的区别

二进制安全

C字符串中的字符必须符合某种编码(比如ASCII),并且除了字符串的末尾之外,字符串里面不能包含空字符,否则最先被程序读入的空字符将被误认为是字符串结尾,这些限制使得C字符串只能保存文本数据,而不能保存像图片、音频、视频、压缩文件这样的二进制数据。
虽然数据库一般用于保存文本数据,但使用数据库来保存二进制数据的场景也不少见,因此,为了确保Redis可以适用于各种不同的场景,SDS的API都是二进制安全的(binary-safe),所有SDS API都会以处理二进制的方式来处理SDS存放在buf数组里的数据,程序不会对其中的数据做任何限制、过滤、或者假设,数据在写入时是什么样的,它被读取时就是
什么样的。这也是将SDS的buf属性称为字节数组的原因——Redis不是用这个数组来保存字符,而是用它来保存一系列二进制数据.

通过使用二进制安全的SDS,而不是C字符串,使得Redis不仅可以保存文本数据,还可以保存任意格式的二进制数据

例子

举个例子,如果有一种使用空字符来分割多个单词的特殊数据格式,
如图所示,那么这种格式就不能使用C字符串来保存,因为C字符串所用
的函数只会识别出其中的"Redis",而忽略之后的"Cluster"
在这里插入图片描述
例如,使用SDS来保存之前提到的特殊数据格式就没有任何问题,因为
SDS使用len属性的值而不是空字符来判断字符串是否结束,如图所示
在这里插入图片描述

兼容部分C字符串函数

虽然SDS的API都是二进制安全的,但它们一样遵循C字符串以空字符结尾的惯例:这些API总会将SDS保存的数据的末尾设置为空字符,并且总会在为buf数组分配空间时多分配一个字节来容纳这个空字符,这是为了让那些保存文本数据的SDS可以重用一部分<string.h>库定义的函数

例子

举个例子,如图所示,如果有一个保存文本数据的SDS值sds,那么我们就可以重用<string.h>/strcasecmp函数,使用它来对比SDS保存的字符串和另一个C字符串:

strcasecmp(sds->buf, "hello world");

这样Redis就不用自己专门去写一个函数来对比SDS值和C字符串值了。
与此类似,还可以将一个保存文本数据的SDS作为strcat函数的第二个参数,将SDS保存的字符串追加到一个C字符串的后面:

strcat(c_string, sds->buf);

这样Redis就不用专门编写一个将SDS字符串追加到C字符串之后的函数了。通过遵循C字符串以空字符结尾的惯例,SDS可以在有需要时重用<string.h>函数库,从而避免了不必要的代码重复
在这里插入图片描述

总结比较

在这里插入图片描述

链表

概述

链表提供了高效的节点重拍能力,以及顺序性的节点访问方式,并且可以通过增删节点来灵活地调整链表的长度。作为一种常用的数据结构,链表内置在很多高级的变成语言里面,因为Redis使用的C语言并没有内置这种数据结构,所以Redis构建了自己的链表实现。链表在Redis中的应用
非常广泛,比如列表键的底层实现之一就是链表。当一个列表键包含了数量比较多的元素,又或者列表中包含的元素都是比较长的字符串时,Redis就会使用链表作为列表键的底层实现。

除了链表键之外,发布与订阅、慢查询、监视器等功能也用到了链表,Redis服务器本身还使用链表来保存多个客户端的状态信息,以及使用链表来构建客户端输出缓冲区(output buffer)

例子

举个例子,以下展示的integers列表键包含了从1到1024共1024个整数:
integers列表键的底层实现就是一个链表,链表中的每个节点都保存了一个整数值。

redis> LLEN integers
(integer) 1024
redis> LRANGE integers 0 10
 1) "11"
 2) "10"
 3) "7"
 4) "6"
 5) "5"
 6) "4"
 7) "3"
 8) "2"
 9) "1"
10) "0"

链表和链表节点的实现

每个链表节点使用一个adlist.h/listNode结构来表示:

typedef struct listNode {
 // 前置节点
 struct listNode *prev;
 // 后置节点
 struct listNode *next;
 // 节点的值
 void *value;
}listNode;

多个listNode可以通过prev和next指针组成双端链表,如图
在这里插入图片描述
虽然仅仅使用多个listNode结构就可以组成链表,但使用adlist.h/list来持有链表的话,操纵起来会更方便。list结构为链表提供了表头指针head、表尾指针tail,以及链表长度计数器len,而dup、free和match成员则是用于实现多态链表所需的类型特定函数:

  • 1.dup函数用于复制链表节点所保存的值
  • 2.free函数用于释放链表节点所保存的值
  • 3.match函数则用于对比链表节点所保存的值和另一个输入值是否相等
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;

如图是由一个list结构和三个listNode结构组成的链表
在这里插入图片描述

特点总结

Redis的链表实现的特性可以总结如下:

  • 1.双端:链表节点带有prev和next指针,获取某个节点的前置节点和后置节点的复杂度都是O(1)
  • 2.无环:表头节点的prev指针和表尾节点next指针都指向NULL,对链表的访问以NULL为终点
  • 3.带有表头指针和表尾指针:通过list结构的head指针和tail指针,程序获取链表的表头节点和表尾节点的复杂度为O(1)
  • 4.带链表长度计数器:程序使用list结构的len属性来对list持有的链表节点进行计数,程序获取链表中节点数量的复杂度为O(1)
  • 5.多态:链表节点使用void*指针来保存节点值,并且可以通过list结构的dup、free、match三个属性为节点值设置类型特定函数,所以链表可以用于保存各种不同类型的值

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

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

相关文章

fastadmin自定义弹出框的回调问题

使用了 vue 更改了 fastadmin 项目的列表页面 但是&#xff0c;当点击 添加时&#xff0c; 弹出 fastadmin 的弹出框&#xff0c;添加也是fastadmin 自带的 上面的代码有点不如意的地方&#xff0c;就是 当我们新增完成之后&#xff0c; 在关闭弹出窗时&#xff0c;想让当前…

keycloak18.0.0==本地源码启动

github下载源码&#xff0c; 版本18.0.0 java和maven的版本如下 E:\keycloak-18.0.0>java -version java version "21.0.1" 2023-10-17 LTS Java(TM) SE Runtime Environment (build 21.0.112-LTS-29) Java HotSpot(TM) 64-Bit Server VM (build 21.0.112-LTS-…

Qt QPainter的使用方法

重点&#xff1a; 1.QPainter在QWidget窗口的paintEvent中使用。 2.QPainter通常涉及到设置画笔、设置画刷、绘图&#xff08;QPen、QBrush、drawxx&#xff09;三个流程。 class Widget : public QWidget {Q_OBJECTprotected:void paintEvent(QPaintEvent *event) Q_DEC…

Linux第71步_将linux中的多个文件编译成一个驱动模块

学习目的&#xff1a;采用旧字符设备测试linux系统点灯&#xff0c;进一步熟悉其设计原理。采用多文件参与编译&#xff0c;深度学习编写Makefile&#xff0c;有利于实现驱动模块化设计。 1、创建MyOldLED目录 输入“cd /home/zgq/linux/Linux_Drivers/回车” 切换到“/home…

个人健康管理系统|基于微信小程序的个人健康管理系统设计与实现(源码+数据库+文档)

个人健康管理小程序目录 目录 基于微信小程序的个人健康管理系统设计与实现 一、前言 二、系统设计 三、系统功能设计 1、用户信息管理 2 运动教程管理 3、公告信息管理 4、论坛信息管理 四、数据库设计 1、实体ER图 五、核心代码 六、论文参考 七、最新计算机毕设…

2024最新算法:斑翠鸟优化算法(Pied Kingfisher Optimizer ,PKO)求解23个基准函数

一、斑翠鸟优化算法 斑翠鸟优化算法&#xff08;Pied Kingfisher Optimizer ,PKO&#xff09;&#xff0c;是由Abdelazim Hussien于2024年提出的一种基于群体的新型元启发式算法&#xff0c;它从自然界中观察到的斑翠鸟独特的狩猎行为和共生关系中汲取灵感。PKO 算法围绕三个不…

售前方案工程师:程序员跨界闯新天,解码售前方案的魅力与挑战

在程序员的多元职业迷宫中&#xff0c;除了前端花园的绚烂和后端洞穴的深邃&#xff0c;还存在着一条独特的赛道——售前方案工程师。 这一角色融合了技术深度与商业洞察&#xff0c;是技术与市场交汇的桥头堡&#xff0c;为那些渴望将技术实力转化为商业价值的程序员提供了一…

【推荐】JuiceSSH 一款可以在手机端免费使用的SSH客户端工具

文章目录 一&#xff0c;官网地址二&#xff0c;下载链接三&#xff0c;使用说明 一&#xff0c;官网地址 https://juicessh.com/ 二&#xff0c;下载链接 https://juicessh.com/changelog#v3.2.2 三&#xff0c;使用说明 使用相当简单&#xff0c;手机上点击“快速连接…

GEE 将裁剪后的Sentinel-2影像 在ArcGIS中去除空值

在ArcGIS中&#xff0c;可以使用栅格计算器&#xff08;Raster Calculator&#xff09;工具来设置NoData值为空。以下是在ArcGIS中将NoData值设置为空的步骤&#xff1a; 打开ArcGIS软件并加载下载的Sentinel-2影像数据。 影像Nodata空值以黑色背景呈现&#xff0c;影响矢量数据…

就业班 2401--3.6 Linux Day12--计划任务和邮件和ssh远程连接

一、计划任务 计划任务概念解析 在Linux操作系统中&#xff0c;除了用户即时执行的命令操作以外&#xff0c;还可以配置在指定的时间、指定的日期执行预先计划好的系统管理任务&#xff08;如定期备份、定期采集监测数据&#xff09;。RHEL6系统中默认已安装了at、crontab软件…

Vue源码系列讲解——过滤器篇【二】(工作原理)

目录 1. 前言 2. resolveFilter函数分析 3. 串联过滤器原理 4. 过滤器接收参数 5. 小结 1. 前言 通过上一篇用法回顾我们知道&#xff0c;过滤器有两种使用方式&#xff0c;分别是在双花括号插值中和在 v-bind 表达式中。但是无论是哪一种使用方式&#xff0c;过滤器都是写…

Python 系统学习总结(基础语法+函数+数据容器+文件+异常+包+面向对象)

&#x1f525;博客主页&#xff1a; A_SHOWY&#x1f3a5;系列专栏&#xff1a;力扣刷题总结录 数据结构 云计算 数字图像处理 力扣每日一题_ 六天时间系统学习Python基础总结&#xff0c;目前不包括可视化部分&#xff0c;其他部分基本齐全&#xff0c;总结记录&#xff0…

快速上手:剧本杀dm预约平台小程序的制作流程

在当今的娱乐市场中&#xff0c;剧本杀已经成为一种备受欢迎的娱乐方式。为了给玩家提供更好的服务和体验&#xff0c;开发一个剧本杀DM预约平台小程序是至关重要的。下面&#xff0c;我们将详细介绍如何使用乔拓云第三方平台开发这样一个预约平台。 首先&#xff0c;打开乔拓云…

QLC SSD:LDPC纠错算法的优化方案

随着NAND TLC和QLC出现,LDPC也在不断的优化研究,提升纠错能力。小编看到有一篇来自Microchip发布的比较详细的LDPC研究数据,根据自己的理解分析解读给大家,如有错误,请留言指正! 文档中测试LDPC(Low-Density Parity-Check)码是为了评估其在不同配置下对数据错误的有效…

基于51单片机的四位并行数据主从机传输设计

基于51单片机的四位并行数据主从机传输设计[proteus仿真] 主从机通信系统这个题目算是课程设计和毕业设计中常见的题目了&#xff0c;本期是一个基于51单片机的四位并行数据主从机传输设计 需要的源文件和程序的小伙伴可以关注公众号【阿目分享嵌入式】&#xff0c;赞赏任意文…

spring 事务失效的 12 种场景

文章目录 spring 事务失效的 12 种场景一、事务不生效1.访问权限问题2. 方法用 final 修饰3.方法内部调用&#xff08;自己玩自己&#xff09;3.1 新加一个 Service 方法3.2 在该 Service 类中注入自己3.3 通过 AopContent 类 4.Bean没有纳入Spring IOC容器管理5.多线程调用&am…

时间轮奇妙旅程:深度解析Netty中的时间轮机制

欢迎来到我的博客&#xff0c;代码的世界里&#xff0c;每一行都是一个故事 时间轮奇妙旅程&#xff1a;深度解析Netty中的时间轮机制 前言时间轮的基本概念时间轮的工作机制netty中时间轮的实现时间轮实现细节&#xff1a;简化的源码示例&#xff1a; 时间轮的应用场景时间轮的…

调研图基础模型(Graph Foundation Models)

&#x1f349; CSDN 叶庭云&#xff1a;https://yetingyun.blog.csdn.net/ 图基础模型&#xff08;Graph Foundation Models&#xff0c;简称 GFMs&#xff09; 是一种经过预训练的图大模型&#xff0c;旨在处理不同领域的图数据和任务。让我们详细探讨一下这个概念。 Github …

掌握Nodejs高级图片压缩技巧提升web优化

掌握Nodejs高级图片压缩技巧提升web优化 在当今的数字时代,图像在网络开发中发挥着至关重要的作用。它们增强视觉吸引力、传达信息并吸引用户。然而,高质量的图像通常有一个显着的缺点——较大的文件大小会减慢网页加载时间。为了应对这一挑战并确保快速加载网站,掌握 Node…

SQL注入漏洞,常用注入函数及其pakachu漏洞靶场演示

目录 SQL注入漏洞概述 SQL注入的常用函数 漏洞分类与利用 1.基于联合查询的SQL注入 &#xff12;.盲注 时间盲注&#xff08;base on bool&#xff09;​编辑 &#xff13;.宽字节注入 4.inset&#xff0f;update&#xff0f;delete注入 &#xff15;.header注入 &…