数据结构

  1. struct sdshdr {
  2. // 记录 buf 数组中已使用字节的数量
  3. // 等于 SDS 所保存字符串的长度
  4. int len;
  5. // 记录 buf 数组中未使用字节的数量
  6. int free;
  7. // 字节数组,用于保存字符串
  8. char buf[];
  9. };
  1. +----+
  2. |free|
  3. |----|
  4. |len |
  5. |----| +---+---+---+---+---+----+
  6. |buf |-->|'R'|'e'|'d'|'i'|'s'|'\0'|
  7. +----+ +---+---+---+---+---+----+

与 C 字符串的区别

字符数组

使用字节数组保存数据,同时杜绝了缓冲区溢出,并且减少了修改字符串时带来的内存重新分配次数。

二进制安全

C 字符串中的字符必须符合某种编码(例如 ASCII),并且除了字符串的末尾之外,字符串里不能包含空字符(’\0’),否则最先被程序读入的空字符将被会误认为是字符串的结尾。因此 C 字符串只能保存文本数据,而不能保存图片、音频、视频、压缩文件这样的二进制数据。

Redis 中的字符串时 二进制安全 的:所有 SDS API 都会以二进制的方式处理 SDS 存在在 buf 数组里的数据,程序不会对其中的数据做任何限制、过滤或者假设。因为 Redis SDS 是使用 len 属性的值而不是空字符来判断字符串是否结束的。

兼容部分 C 字符串函数

SDS 和 C 字符串一样以空字符结尾,因此 SDS 可以重用一部分 <string.h> 库定义的函数。