《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数组里的数据,程序不会对其中的数据做任何限制、过滤或者假设,数据在写入时是什么样子,读取时就是什么样子