第一部分之简单字符串SDS(第二章)

一,什么是SDS?

1.引出SDS
C字符串:c语言中,用空字符结尾的字符数组表示字符串
简单动态字符串(SDS):Redis中,用SDS来表示字符串。在Redis中,包含字符串值的键值对在底层都是由SDS实现的
首先,Redis使用C语言写的,但是Redis没有使用C语言传统的字符串表示,它自己构建了简单字符串的抽象类型来表示字符串。

2.SDS的定义
一个sdshdr结构表示一个SDS值。结构如下:
struct sdshdr {
    //记录buf数组中已使用字节的数量
    int len;
    
    //记录buf数组中未使用字节的数量
    int free;

//char类型的数组,用来保存字符串
    char buf[];    
}
注意:SDS还是遵循了C字符串以空字符结尾的惯例,最后一个字节保存空字符‘\0‘。这样做的好处是SDS可以重用一些C字符串函数库里面的函数。

3.SDS和C字符串的区别
A.结构上

B.获取字符串的长度时:
    C字符串需要遍历整个字符串,当发现空字符时,停止计数。时间复杂度为O(n)。
    SDS中的len属性记录了SDS的长度。时间复杂度为O(1)。
C.杜绝缓冲区溢出:
由于C字符串不记录自身的长度。当修改字符串之前,如果没有为字符串分配(我们手动分配)足够的空间,会造成缓冲区溢出
当修改SDS字符串时,API会先检查SDS的空间是否满足修改所需要的要求(通过 len free 来判断)。如果不满足,API会自动(不需要我们手动分配)修改SDS空间的大小

D.减少内存重新分配次数
对于C字符串来说,每次修改时,都需要对保存这个C字符串的数组进行一次内存重新分配操作。
    如果拼接字符串,在拼接之前,程序需要先通过内存重新分配扩展底层数组的空间大小。否则会缓冲区溢出
    如果缩短字符串,在截断字符串之后,程序需要通过内存重新分配来释放不用的空间。否则会内存泄漏
对于SDS来说,通过未使用空间 len free,实现了空间预分配和惰性空间释放两种优化策略。
    空间预分配(字符串增长):修改之后,如果SDS的长度小于1MB,程序分配和len同样大小的未使用(len free)
                空间。如果大于1MB的空间,程序分配1MB的未使用空间。
    惰性空间释放(字符串缩短):缩短字符串后,程序不是立即使用内存重新分配来回收缩短后多出来的字节,
                而是使用free属性将这些字节的数量记录起来,等待将来使用。

E.二进制安全

只关心二进制化的字符串,不关心具体格式,只会严格按照二进制的数据存取,不会根据某种特殊的标志来解析。
C字符串中,空字符串被当做字符串的结尾来解析的。比如存hello world字符串时,C字符串只会保存hello。因为对于中间的空格,C字符串解析成空字符,当做这个字符串的结尾。world就丢失了。但是SDS字符串,写入是什么样,它被读取就是什么样。那么SDS是如何判断字符串是否结束呢?通过len属性的值获取字符串的长度,字符串长度是多少,在读取字符串的时候就读取多少长度。

F.兼容部分C字符串函数
通过遵循C字符串以空字符结尾的惯例,SDS可以在有需要的时候重用<String.h>函数库

原文地址:https://www.cnblogs.com/inspred/p/10658296.html

时间: 2024-10-11 00:06:04

第一部分之简单字符串SDS(第二章)的相关文章

【C语言探索之旅】 第一部分第四课第二章:变量的世界之变量声明

内容简介 1.课程大纲 2.第一部分第四课第二章:变量的世界之变量声明 3.第一部分第四课第三章预告:变量的世界之显示变量内容 课程大纲 我们的课程分为四大部分,每一个部分结束后都会有练习题,并会公布答案.还会带大家用C语言编写三个游戏. C语言编程基础知识 什么是编程? 工欲善其事,必先利其器 你的第一个程序 变量的世界 运算符 条件表达式 循环语句 实战:第一个C语言小游戏 函数 练习题 习作:完善第一个C语言小游戏 C语言高级技术 模块化编程 进击的指针,C语言王牌 数组 字符串 预处理

perl5 第二章 简单变量

第二章 简单变量  by flamephoenix 一.整型 二.浮点数 三.字符串 基本上,简单变量就是一个数据单元,这个单元可以是数字或字符串.一.整型 1.整型   PERL最常用的简单变量,由于其与其它语言基本相同,不再赘述.   例:   $x = 12345;   if (1217 + 116 == 1333) {   # statement block goes here   }  整型的限制:   PERL实际上把整数存在你的计算机中的浮点寄存器中,所以实际上被当作浮点数看待.在

Unity 游戏框架搭建 2019 (九~十二) 第一章小结&amp;第二章简介&amp;第八个示例

第一章小结 为了强化教程的重点,会在合适的时候进行总结与快速复习. 第二章 简介 在第一章我们做了知识库的准备,从而让我们更高效地收集示例. 在第二章,我们就用准备好的导出工具试着收集几个示例,这些示例中有的是我们后续库的基础工具,也有的是在项目中非常实用的小工具,还有一些示例是实践了在框架搭建方向上非常重要的 C# 语法知识. 第二章大纲如下. 第八个示例(一) 在之前,我们完成了一个导出的功能.但是在完成这个功能的过程中,我们也遇到了一些问题.我们回忆一下,在<MenuItem 复用>的这

《Entity Framework 6 Recipes》翻译系列 (3) -----第二章 实体数据建模基础之创建一个简单的模型 (转)

第二章 实体数据建模基础 很有可能,你才开始探索实体框架,你可能会问“我们怎么开始?”,如果你真是这样的话,那么本章就是一个很好的开始.如果不是,你已经建模,并在实体分裂和继承方面感觉良好,那么你可以跳过本章. 本章将带你漫游使用实体框架建模的基本实例,建模是实体框架的核心特性,同时也是区别实体框架和微软早期的数据访问平台的特性.一旦建好模,你就可以面向模型编写代码,而不用面向关系数据库中的行和列. 本章以创建一个简单概念模型的实例开始,然后让实体框架创建底层的数据库,剩下的实例,将向你展示,如

《Unity3D 游戏开发经典教程》 第一第二章学习

花时间看了第一和第二章的内容,将书上的例子做成了个一个简单的游戏Protype. git 源码地址:https://github.com/crj8812/Unity3D            UGDE 蓝色为子弹,红色为被击垮的墙壁

Java 线程第三版 第一章Thread导论、 第二章Thread的创建与管理读书笔记

第一章 Thread导论 为何要用Thread ? 非阻塞I/O I/O多路技术 轮询(polling) 信号 警告(Alarm)和定时器(Timer) 独立的任务(Task) 并行算法 第二章 Thread的创建与管理 一.什么是Thread ? Thread是所在主机执行的应用程序任务(task). 只有一个线程的例子: public class Factorial { public static void main(String[] args) { int n = 5; System.ou

高项3.7日第一次课,第一章信息化基础知识与第二章信息系统服务管理梳理

第一章 信息化的基础知识 1.国家信息化体系要素: 主要包括6要素,信息技术应用(龙头).信息资源(关键).信息网络(必要手段).信息技术产业(基础).信息化人才(成功之本).信息化法规政策和规范(保障). 2.电子政务: 电子政务建设的指导原则: (1)统一规划,加强领导. (2)需求主导,突出重点. (3)统一规划,拉动产业. (4)统一标准,保障安全. 主要任务: (1)电子政务网络由政务内网和政务外网构成,两网之间物理隔离,政务外网与互联网之间逻辑隔离.政务内网主要是副省级以上政务部门的

《TCP/IP详解 卷1:协议》读书笔记(第一章 概述 &amp; 第二章 链路层)

第一章 概述 TCP/IP协议族:四层协议系统 链路层(数据链路层.网络接口层)设备驱动程序和网络接口卡. 网络层(互联网层)处理分组在网络中的活动,点对点服务.IP.ICMP.IGMP 运输层提供端对端通信.TCP.UDP 应用层处理应用程序细节.Telnet.FTP.SMTP.SNMP 部分概念 构造互联网最简单的方法是把两个或多个网络通过路由器(Router)进行连接.路由器的好处是为不同类型的物理网络提供连接:以太网.令牌环网.点对点的链接等等. 网络层IP协议提供的是一种不可靠的服务.

Java 螺纹第三版 第一章Thread介绍、 第二章Thread创建和管理学习笔记

第一章 Thread导论 为何要用Thread ? 非堵塞I/O I/O多路技术 轮询(polling) 信号 警告(Alarm)和定时器(Timer) 独立的任务(Task) 并行算法 第二章 Thread的创建与管理 一.什么是Thread ? Thread是所在主机运行的应用程序任务(task). 仅仅有一个线程的样例: public class Factorial { public static void main(String[] args) { int n = 5; System.o