每个sds.h/sdshdr结构表示一个SDS值:

struct sdshdr{
//记录buf数组重已使用字节的数量,等于SDS所保存字符串的长度
int len;
//记录buf数组中未使用字节的数量
int free;
//字节数组,用来保存字符串
char buf[];
}

free属性的值为0,表示这个SDS没有分配任何未使用空间。

len属性的值为5,表示这个SDS保存了一个五字节长的字符串。

buf属性是一个char类型的数组,最后一个字节保存空字符’\0’。

SDS遵循C字符串以空字符结尾的惯例,保存空字符的1字节空间不计算在SDS的len属性里面。

示例:

SDS遵循C字符串以空字符结尾的惯例,保存空字符的1字节空间不计算在SDS的len属性里面。

通过 len 属性,SDS 获取字符串长度时,其时间复杂度为 O(1) 。

通过检查SDS的空间是否满足修改所需的要求,杜绝了缓冲区溢出的可能性。

当 SDS API 需要对SDS进行修改时,API 会先检查SDS的空间是否满足修改所需的要求,如果不满足的话,API 会自动将SDS的空间扩展至执行修改所需的大小,然后才执行实际的修改操作。

通过未使用空间解除了字符串长度和底层数组长度之间的关联,减少了内存重分配的次数。

SDS中,buf 数组的长度不一定就是字符数量加一,数组里面可以包含未使用的字节,而这些字节的数量就由SDS的 free 属性记录。

通过未使用空间,SDS实现了空间预分配和惰性空间释放两种优化策略。

空间预分配用于优化SDS的字符串增长操作:当SDS的 API 对一个SDS进行修改,并且需要对SDS进行空间扩展的时候,程序不仅会为SDS分配修改所必要的空间,还会为SDS分配额外的未使用空间。

惰性空间释放用于优化SDS的字符串缩短操作:当SDS的 API 需要缩短SDS保存的字符串时,程序并不立即使用内存重分配来回收缩短后多出来的字节,而是使用 free 属性将这些字节的数量记录起来,并等待将来使用。

SDS 是二进制安全的。

所有 SDS API 都会以处理二进制的方式来处理SDS存放在 buf 数组里的数据。

SDS API