一、简介

1.1 结构体

struct sdshdr {

  //记录buf数组中已使用字节的数量
  int len;
  
  //记录还未使用的长度
  int free;
  
  //用于存放具体的字符串值
  char buf[];
    
};

redis为什么要定义自己的字符串,而不是使用c自带的字符数组?

首先c自带的字符数组在获取其字符串的长度的时间复杂度是O(n),使用SDS的话,应为在存入字符串的时候就已经使用len字段记录了长度,所以其查询复杂度是O(1),另一方面SDS有
free字段用于记录字符数组还未使用的空间,这样的话,它就知道从何处开始可以继续写入字符,这样在拼接字符串的时候,如果发现free的空间足够的话,就可以直接将拼接的字符串
写入,这就是SDS的空间预分配,除此之外,SDS还采用了惰性空间释放的优化策略。

1.2 SDS的优化策略

1.2.1 空间预分配

为了减少字符串数组的重分配操作,SDS使用了空间预分配策略,在字符数组小于1M的情况下,每次创建一个SDS时都会预分配与实际字符长度一样长的预留空间,比如我要创建一个10字
节的数组,那么将会创建一个10+10+1的字符串数组,最后一个1是用来存0字符的,表示字符串的结尾。
当超过1M后,每次创建一个SDS,只会预分配1M的空间,这样在拼接字符串的时候,就不用频繁的重分配了。

1.2.2 空间惰性释放

这个策略用于字符串的缩短操作,当我们缩短一个字符串时,它不会立即释放掉空间,而是用free字段记录被释放的空间

1.2 优点

1)常数复杂度获取字符串长度。

2)杜绝缓冲区溢出。

3)减少修改字符串长度时所需的内存重分配次数。

4)二进制安全。

5)兼容部分c字符串函数。