SDS的定义
struct sdshdr {
int len; // 记录buf已使用字节的数量
int free; // 记录buf中未使用字节的数量
char buf[]; // 字节数组
}
杜绝缓冲区溢出
- char *strcat(char *dest, const char *src); dest空间不足会发生缓冲区溢出
- SDS拼接会先检查free,free不足会根据分配策略扩展SDS的空间
空间预分配
- len <= 1MB,free = len
- len > 1MB,free = 1MB
惰性空间释放
- 当缩短字符串时,并不立即回收缩短后多出来的字节,free记录多出来的字节
- 提供释放API,当有需要时,再真正释放未使用空间
二进制安全
- C字符串以'\0'作为识别字符串结尾,SDS以len作为识别字符串结尾
总结
C字符串与SDS之间的区别
| C字符串 | SDS |
|---|---|
| 获取字符串长度的时间复杂度O(N) | O(1) |
| API是不安全的,可能造成缓冲区溢出 | API是安全的,不会造成溢出 |
| 修改字符串长度N次必须执行N次内存重新分配 | 修改字符串长度N次最多执行N次内存重新分配 |
| 只能保存文本数据 | 可以保存文本或者二进制数据 |
| 只能保存文本数据 | 可以保存文本或者二进制数据 |
| 可以使用所有<string.h>库中的函数 | 可以使用一部分<string.h>库中的函数 |
参考
《Redis设计与实现》