Redis数据结构-简单动态字符串(Simple Dynamic String,SDS)(待完善)

Redis关于 SDS的源文件在 src/sds.c sds.h/sdshdr

struct sdshdr {
    // buf 中已占用空间的长度
    int len;

    // buf 中剩余可用空间的长度
    int free;

    // 字节数组
    char buf[];
};

SDS本质上就是char *,因为有了表头sdshdr结构的存在,所以SDS比传统C字符串在某些方面更加优秀,并且能够兼容传统C字符串。

sds在Redis中是实现字符串对象的工具,并且完全取代char*..sds是二进制安全的,它可以存储任意二进制数据,不像C语言字符串那样以‘\0’来标识字符串结束,

因为传统C字符串符合ASCII编码,这种编码的操作的特点就是:遇零则止 。即,当读一个字符串时,只要遇到’\0’结尾,就认为到达末尾,就忽略’\0’结尾以后的所有字符。因此,如果传统字符串保存图片,视频等二进制文件,操作文件时就被截断了。

SDS表头的buf被定义为字节数组,因为判断是否到达字符串结尾的依据则是表头的len成员,这意味着它可以存放任何二进制的数据和文本数据,包括’\0’

SDS 和传统的 C 字符串获得的做法不同,传统的C字符串遍历字符串的长度,遇零则止,复杂度为O(n)。而SDS表头的len成员就保存着字符串长度,所以获得字符串长度的操作复杂度为O(1)。

总结下sds的特点是:可动态扩展内存、二进制安全、快速遍历字符串 和与传统的C语言字符串类型兼容

string 的惰性空间释放策略:

当要缩短SDS保存的字符串时,程序并不立即使用内存充分配来回收缩短后多出来的字节,而是使用表头的free成员将这些字节记录起来,并等待将来使用。

void sdsclear(sds s) {  //重置sds的buf空间,懒惰释放
    struct sdshdr *sh = (void*) (s-(sizeof(struct sdshdr)));
    sh->free += sh->len;    //表头free成员+已使用空间的长度len = 新的free
    sh->len = 0;            //已使用空间变为0
    sh->buf[0] = '\0';         //字符串置空
}

 1. 空间预分配:SDS将连续增长N次字符串所需的内存重分配次数从必定N次降低为最多N次

2. 惰性空间分配:避免了缩短字符串所需要的内存重分配操作,为将来可能有的增长操作提供了优化

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值