理解Redis设计与实现(一):简单动态字符串(SDS)

版权声明:转载请注明原文地址。 https://blog.csdn.net/qq_39240270/article/details/88384976

       Redis没有直接使用C语言传统的字符串表示,而是自己构建了一种名为简单动态字符串(Simple Dynamic String,SDS)的抽象模型,并将SDS用作Redis的默认字符串表示, 在Redis中,C字符串只会作为字符串字面量用在一些无需对字符串值进行修改的地方。当Redis需要的是一个可以被修改的字符串值时,Redis就会使用SDS来表示字符串值,比如在Redis的数据库中,包含字符串的键值对在底层都是由SDS实现的。SDS还被用来做缓冲区(buffer):AOF模块中的AOF缓冲区,以及客户端状态中的输入缓冲区。

1、SDS的定义

       每个sds.h/sdshdr(sds.h中的sdshdr结构)表示一个SDS值:

struct sdshdr{
	//记录buf数组中已经使用字节的数量
	//等于SDS所保存字符串的长度
	int len;
	//记录buf数组中未使用字节的数量
	int free;
	//字节数组,用于保存字符串
	char buf[];
};

结构示意图:
在这里插入图片描述
分析:

  • free属性值为0,表示这个SDS没有多余的空间
  • len属性为5,表示这个SDS保存了一个5字节长的字符串
  • buf属性为一个字符数组,前面五个保存字符串中的字符,最后一个保存空字符’\0’,空字符不算进len中

2、SDS与C字符串的区别

       C语言使用长度为N+1的字符数组来表示长度为N的字符串,并且字符数组最后一个元素总是一个空字符,不能满足Redis对字符串在安全性,效率以及功能分配的要求。

C字符串 SDS
获取字符串长度的复杂度为O(N) 获取字符串长度的复杂度为O(1)
API是不安全的,可能会造成缓冲区溢出 API是安全的,不会造成缓冲区溢出
修改字符串长度N次必然需要执行N次内存重分配 修改字符串长度N次最多需要执行N次内存重分配
只能保存文本数据 可以保存文本或者二进制数据
可以使用所有<string.h>库中的函数 可以使用一部分<string.h>库中的函数

3、SDS对比C字符串的优点

  1. 常熟复杂度获取字符串长度
  2. 杜绝缓冲区溢出
  3. 减少修改字符串长度时所需的内存重分配次数
  4. 二进制安全
  5. 兼容部分C字符串函数

参考资料

黄健宏. Redis 设计与实现 [M]. 机械工业出版社, 2014.

猜你喜欢

转载自blog.csdn.net/qq_39240270/article/details/88384976