Redis 数据结构之SDS (Simple Dynamic String)简单动态字符串

SDS

Redis没有直接使用C语言传统的字符串,而自己构建了一种简单动态字符串(Simple Dynamic String)的抽象类型,简称为SDS。并将SDS作为Redis的默认字符串表示。

它主要有以下两个用途:

  • 实现字符串对象(StringObject)。
  • 在 Redis 程序内部用作 char* 类型的替代品。
SDS的定义
struct sdshdr{
     int len; //记录buf中已使用字节的数量等于SDS所保存的字符串的长度
     int free; //记录buf中未使用字节的长度
     char []buf; //字节数据,保存字符串
}

注意申请char数组buf的总空间为len+buf+1(空字符)。

SDS的优点
  • 获取字符串的时间复杂度低,O(1)。
  • 记录了未使用的字节长度,防止缓冲区溢出。若空间不足再申请,然后拼接。
惰性释放

字符串长度减少不会引起空间释放。

空间预分配

当对字符串进行修改的时候会预分配空间。当len属性值小于1MB时,buf数组的实际长度为 len(修改后的len值)*2+1byte,这时len和free相等,一个字节用于保存空字符。当len属性值大于1MB时,buf数组的实际长度为 len(修改后的len值)+1MB+1byte,这时free的值为1MB。

二进制安全

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

兼容部分C字符串函数

以空字符结尾。

SDS API

在这里插入图片描述

发布了187 篇原创文章 · 获赞 14 · 访问量 4万+

猜你喜欢

转载自blog.csdn.net/LU_ZHAO/article/details/105012283