看了《Redis设计与实现》第二章关于redis底层对于String类型的实现:SDS(Simple Dynamic String,简单动态字符串)的内容,在这里做一点简单的总结笔记。
一.SDS结构
struct sdshdr {
//记录buf数组中已经使用的字节的数量
//等于sds所保存字符串的长度
int len;
//记录buf数组中未使用字节的数量
int free;
//字节数组,用于保存字符串
char buf[];
}
二.SDS是在C字符串的基础上进行再封装
C语言使用长度为N+1的字符数组来表示长度为N的字符串,并且字符数组的最后一个元素总是空字符'\0',不满足Redis对字符串在安全性、效率以及功能的要求:
1.用空间换时间:C字符串不记录自身的长度信息,为了获取长度,需要遍历整个字符串,而SDS记录了本身的长度在len中,获取长度的复制度从O(N)变为O(1);
2.杜绝缓存区溢出:c字符串在增加内容时需要手动地为其分配足够的空间,否则容易缓存区溢出--->意外修改别的内存区域,SDS的空间配策略使得SDS在进行修改时会先检查空间是否满足修改所需的要求。不满足的话,会自动扩展空间。
3.减少内存重分配次数:提前预留未使用空间,减少耗时的复杂的内存重分配操作(亦是空间换时间)。通过未使用空间,SDS实现了空间预分配和惰性空间释放。
4.二进制安全:C字符数组是以空字符'\0'来判断字符串是否结束,二进制数据里若包含空字符将为误认为是字符串结尾,因此C字符串只能保存文本数据,而SDS不用空字符来判断字符串是否结束,因此SDS是二进制安全(binary-safe)的。--->可以保存二进制数据
5.兼容部分C字符串函数:在需要时重用<string.h>函数库,避免代码重复(redis是基于c语言写的)
三.SDS与JAVA中的字符串的对比
未完待续,哈哈