数据结构
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>
库定义的函数。