redis设计与实现读书笔记二(SDS)

redis字符串实现

redis字符串并没有使用以空字符为结尾的字符数组来构建,而是实现了一套自身的字符串模式,也叫简单动态字符串(SDS,simple dynamic string).
SDS在sds.h/sdshdr中如下表示

struct sdshdr{
    int len;//buf数组中已使用字节数量,即sds所保存的字符串长度
    int free;//buf数组中未使用的字节的数量
    char buf[];//保存字符串
}

SDS遵循C字符串的已空字符结尾的惯例,这样sds便可以复用C字符串函数库的一些函数.无须为SDS编写已经存在的功能函数.比如打印输出等.

SDS特点:
* 获取字符串长度的时间复杂度降为O(1),通过len属性直接读取
* 杜绝缓冲区溢出,每次修改字符串时SDS API会检测是否分配了足够空间
* 减少字符串修改时内存分配的次数

SDS通过未使用空间解除了字符串长度和底层数组长度之间的关联,实现了空间预分配惰性空间释放两种优化策略

空间预分配策略:
优化SDS字符串增长的操作,增加长度时sds api不但会分配修改所必须的空间,还会分配额外的未使用空间.
1 修改后长度小于1MB,那么未使用空间和必须空间分配同等大小.
2 修改后长度大于 1MB,会分配1MB的未使用空间
3 无论1还是2 ,char []长度均会另外存储一个字符记录空字符

惰性空间释放
减小字符串长度时,并不会立即回收内存而是将减小的内存数量累加到未使用空间free属性上,下一次对字符串操作时 api会先判断未使用空间free是否满足大小,如果满足就使用未使用空间

总结一下c字符串和sds的区别

C字符串 SDS
获取字符串长度复杂度O(N) 获取字符串长度复杂度O(1)
api不安全会溢出 api安全,不会溢出
只能保存文本 可以保存文本或者二进制数据
修改字符串最多可分配N次空间 修改字符串至多N次
可使用c字符串函数 沿用部分了c字符串函数

你可能感兴趣的:(redis设计与实现)