《Redis设计与实现》黄建宏版的读书笔记
简单动态字符串
- Redis构建了一种名为简单动态字符串(simple dynamic string, SDS)的抽象类型,作为默认字符串表示。
- SDS遵循C字符串以空字符结尾的惯例,保存空字符的一个字节空间不计算在SDS的len属性里面,并且为空字符分配额外的一个字节,以及添加空字符到字符串末尾等操作,都是由SDS函数自动完成的,所以空字符对SDS的使用者来说是完全透明的。
struct sdshr {
// 记录buf数组中已使用字节的数量
// 等于sds所保存字符串的长度
int len;
// 记录buf数组中未使用字节的数量
int free;
// 字节数组,用户保存字符串
char buf[];
};
- SDS与传统C字符串的区别
C字符串 | SDS |
获取字符串长度的时间复杂度为O(n) | 获取字符串长度的时间复杂度为O(1) |
API 是不安全的,可能会造成缓冲区溢出 | API 是安全的,不会造成缓冲区溢出 |
修改字符串长度N次必然需要执行N次内存重分配 | 修改字符串长度N次最多需要执行N次内存重分配(预分配和惰性释放) |
只能保存文本数据 | 可以保存文本或者二进制数据(二进制安全) |
可以使用所有<string.>库中的函数 | 可以使用部分<string.>库中的函数 |
- SDS的预分配策略
- 如果对SDS进行修改后,SDS的长度(也就是len属性的值)小于1MB,那么程序分配和len属性同样大小的未使用空间。
- 如果对SDS进行修改后,SDS的长度将大于等于1MB,那么程序会分配1MB的未使用空间
- SDS的API都是二进制安全的,以处理二进制的方式来处理SDS存放在buf数组里的数据,程序不会对其中的数据做任何限制、过滤或者假设,数据在写入时是什么样子,读取时就是什么样子