第2章 简单动态字符串
Redis自己构建了一种名为简单动态字符串(SDS)的抽象类型,并将其作为Redis的默认字符串表示.在Redis中,包含字符串值的键值对在底层都是SDS实现的.C字符串只会作为字面量使用.
1. SDS的定义
struct sdshdr{
// 记录出发数组中已经使用了的字符数量
// 也就是sds所保存的字符串的长度
int len;
// 记录空闲空间的数量
int free;
// 字节数组,存储字符数据
char buf[];
}
SDS遵循C字符串以空字符(’\0’)结尾的惯例,目的是为了直接重用一部分C字符串库函数.但是这个空字符是不计入len属性中的.
2. SDS和C字符串的区别
C字符串并不能满足Redis在安全性,效率以及功能方面的要求.
(1). 获取字符串长度
SDS可以常数复杂度的获取字符串的长度,因为数据结构中已经存储了字符串的长度,不需要遍历数组去求累计和.
(2). 杜绝缓冲区溢出
在修改前会判断空间是否足够使用(free字段的值),而如果使用C字符串,需要先进行手动判断,保证空间足够.
SDS API对SDS进行修改时,API会检查SDS的空间是否满足修改所需的要求.如果不足,则会自动进行扩容.
(3). 减少修改字符串时带来的内存充分配次数
C字符串的底层总是空间大小刚好合适(n+1).这样对字符串进行修改时,就经常会涉及到内存的重分配.SDS中保留了空闲空间,接触了字符串长度和底层数组长度的关联.
通过未使用空间,SDS实现了==空间预分配和惰性空间释放==两种优化策略.
1). 空间预分配
每次都额外分配内存,减少内存重新分配.优化SDS的增长.
额外分配的内存等于所使用的内存,但不超过1 MB.
拓展SDS时会优先使用空闲空间,如果空闲空间不足,才会重新分配内存.
2). 惰性空间释放
长度缩短时,不会立刻回收内存.优化SDS缩短.
SDS提供了相应API,可以手动的真正释放SDS未使用的空间.从而不会造成内存浪费.
(4). 二进制安全
不需要考虑’/0’的意义,那么就可以存储二进制数据.
(5). 兼容部分C字符串函数
来源:CSDN
作者:Benjamin-__
链接:https://blog.csdn.net/Benjalin_76_84/article/details/104214591