《Redis 设计与实现》笔记 - 简单动态字符串

数据结构

struct sdshdr {

    // 记录 buf 数组中已使用字节的数量
    // 等于 SDS 所保存字符串的长度
    int len;

    // 记录 buf 数组中未使用字节的数量
    int free;

    // 字节数组,用于保存字符串
    char buf[];

};
+----+
|free|
|----|
|len |
|----|   +---+---+---+---+---+----+
|buf |-->|'R'|'e'|'d'|'i'|'s'|'\0'|
+----+   +---+---+---+---+---+----+

与 C 字符串的区别

字符数组

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

二进制安全

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

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

兼容部分 C 字符串函数

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

最后更新于