简介
redis中使用简单动态字符串(sample dynamic string — SDS)来作为默认的字符串表示。
结构
struct sdshdr {
unsigned int len; //buf数组已使用的字节数量,不包含空字符
unsigned int free; //buf数组中未使用的字节数量
char buf[]; //字节数组
};
优点
1、可以重用一部分C字符串函数库的函数
因为buf数组以空字符’\0’结尾,这和C字符串判断是否是一个字符串是一致的。
2、常数时间复杂度获取字符串长度
因为len记录了buf数组的长度,即获取时间复杂度未O(1).
3、杜绝缓冲区溢出
当SDS API需要对SDS进行修改时,API会先检查SDS的空间是否满足修改所需的要求,如果不满足的话,API会自动将SDS的空间扩展至执行修改所需的大小,然后才执行实际的修改操作。
4、减少修改字符串时带来的内存重分配次数
1、空间预分配(增加字符)
- 如果对SDS进行修改之后,SDS的长度(也就是len属性的值)将小于1MB,那么程序分配和len属性同样大小的未使用空间,这时SDS len属性的值将和free属性的值相同。
- 如果对SDS进行修改之后,SDS的长度将大于1MB,那么程序会分配1MB的未使用空间。
通过空间预分配策略,Redis可以减少连续执行字符串增长所需的内存重分配次数。
2. 惰性空间释放(减少字符)
当SDS的API需要缩短SDS保存的字符串时,程序并不立即使用内存重分配来回收缩短后多出来的字节,而是使用free属性将这些字节的数量记录起来,并等待将来使用。
5. 可以保存文本或者二进制数据
因为SDS使用len 属性的值而不是空字符来判断字符串是否结束。
适用场景
用来保存String类型的值,用作AOF模块中的AOF缓冲区,以及客户端状态中的输入缓冲区。
参考
《Redis设计与实现》