1.简单动态字符串(SDS)
Redis没有直接使用C语言传统的字符串表示(以空字符结尾的字符数组),而是自己构建了一种名为简单动态字符串(SDS)的抽象类型,并作为Redis的默认字符串表示
1.1.SDS 的定义
每个sds.h/sdshdr结构表示一个SDS值
Struct sdshdr{
//记录buf数组中已使用的字节数量
//等于SDS所保存字符串的长度
Intlen;
//记录buf数组中未使用的字节数量
Intfree;
//字节数组,用于保存字符串
Charbuf[];
};
SDS遵循C字符串以空字符结尾的惯例,保存空字符的1字节空间不计算在SDS的len属性中,并额外分配1字节的空间
1.2 SDS与C字符串的区别
(1)SDS可以在O(1)时间复杂度获取字符串长度
Len即字符串长度。设置和更新SDS长度的工作是由SDS的API在执行时候自动完成的,使用SDS无须进行任何的手动修改长度的工作。
(2) 杜绝了发生缓冲区溢出的可能,当SDS需要对SDS
当SDS的API需要对SDS进行修改时,API会先检查SDS的空间是否满足修改所需的要求,如果不满足,API将会自动将SDS的空间扩展至执行修改所需求的大小,然后才执行实际的修改操作。
(3) 减少修改字符串时带来的内存重分配的次数
SDS实现了空间预分配和惰性空间释放两种优化策略
a. 空间预分配:用于优化SDS的字符串增长操作,当SDS的API对一个SDS进行修改,并且需要对SDS进行空间扩展的时候,程序不仅会为SDS分配修改所需要的空间,还会为SDS分配额外使用的未使用空间。额外分配的未使用空间数量由以下公式决定:
① 如果修改后len小于1MB,那么程序额外分配len相同大小的未使用空间(free属性),这时,len=free。如:修改后len变为13字节,那么程序也会分配13字节未使用空间,buf数组实际长度变为:13+13+1
② 如果修改后len大于等于1MB,则程序会分配1MB的未使用空间。
如:修改后len变为30,那么SDS的buf数组实际长度:30MB+1MB+1byte
b. 惰性空间释放:用于优化SDS的字符串缩短操作,当SDS的API需要缩短SDS保存的字符串时,程序并不立即使用内存重分配来回收缩短后多出来的字节,而是使用free属性将这些字节的数量记录下来,并等待将来使用
(4)二进制安全
SDS的buf字节数组不是用来保存字符,而是保存一系列二进制数据,保存特殊格式数据不会有任何问题(如:hello ‘\0’ world)
(5)兼容部分C字符串的函数
以‘\0’结尾,所以可以重用一部分
库定义的函数
总结: