wangxiaoxue 2019-12-10
一.使用场景
redis没有直接使用C语言传统的字符串表示(以空字符结尾的字符数组,以下简称C字符串),而是构建了简单动态字符串(Simple dynamic String SDS)的抽象类型,并将SDS作为默认的字符串表示形式。
redis里面C字符串只用在字符串字面量(String literal) ,用在一些无需对字符串修改的地方。
比如打印日志redisLog(REDIS_WARING,"redis is now ready to exit, bye bye...")
1.redis需要的不仅仅是一个字符串字面量,而是一个可修改的字符串值时,redis就会使用SDS来表示字符串值,比如在redis数据库里面,包含字符串值的键值对在底层都是由SDS实现的。
2.SDS还被用作缓冲区:AOF模式中的缓冲区,以及客户端状态中的输入缓冲区,都是SDS实现的。
二.定义
1.每一个sds.h/sdshdr结构表示SDS的值
struct sdshdr {
//记录buf数组中已使用的字节数量
//等于SDS所保存的字符串长度
int len;
//记录buf数组中未使用的字节数量
int free;
//字节数组,用于保存字符串
char buf[];
}
free为0,表示SDS没有分配任何未使用空间
len =5,表示SDS保存了5字节长度的字符串
buf 是一个char类型的数组,数组的前五个字节分别保存了 ‘r‘,‘e‘,‘d‘,‘i‘,‘s‘ 五个字符,最后一个字节则表示了空字符‘\0‘
SDS遵循了C字符串以空字符结尾的惯例,保存空字符串的1个字节空间,不计算在SDS的属性里面,并且为控制符串分配额外的1字节空间,
以及添加空字符到字符串末尾等操作,都是有SDS自动完成的,所以这个空字符对于SDS使用者是完全透明的,
遵循空字符结尾这一惯例的好处是,SDS可以重用一部分C字符串函数库里的函数。
图2-2,展示了buf数组分配了5个未使用空间的字节,所以 free=5;
三.SDS和C字符串区别
1.常数复杂度获取字符串长度
2.杜绝缓冲区溢出
3.减少修改字符串时带来的内存分配次数
4.二进制安全
5.兼容部分C字符串函数
四.总结
五.SDS API
六.重点回顾