1简单动态字符串SDS

Posted use-d

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了1简单动态字符串SDS相关的知识,希望对你有一定的参考价值。

1、简单动态字符串SDS全称simple dynamic string。
SDS是Redis自己构建的抽象类型,并将SDS用作Redis的默认字符串表示。
 
例如:set msg "hello world"
其中键msg是一个字符串对象,对象的底层实现是一个保存着字符串msg的SDS;
其中值为hello world是一个字符串对象,对象的底层实现是一个保存着字符串"hello world"的SDS。
 
结构为:
struct sdshdr{
//记录buf数组中已经使用字符的长度 等于 SDS保存字符串的长度
int len;
//记录buf数组中未使用字节长度
int free;
//字符数组,用于保存字符串
char buf[];
}
 
SDS总是以‘‘空字符结尾,并且‘‘空字符不记录在len字段中,例如:
set name "Redis"
这个设置name="Redis"的键值对中,"Redis"的SDS格式如下:
struct sdshdr{
5;
0;
[‘R‘,‘e‘,‘d‘,‘i‘,‘s‘,‘‘];
}
2、SDS与C字符串区别
C字符串:
缺点:
获取字符串长度的复杂度为O(N)
API不安全,可能会造成缓存区溢出(对于一个字符串A后面拼接字符串B时,需要考虑A字符串的容量问题)
修改字符串长度N次必然需要执行N次内存重分配(即无论是缩小还是扩大C字符串的大小都需要进行内存分配)
只能保存文本数据(即C字符串是以‘‘结尾的,如果想保存‘‘这个特殊字符,则会导致数组提前被截取了)
优点:
可以使用所有<String.h>库中的函数
SDS:
优点:
获取字符串长度的复杂度为O(1)
API是安全的,不会造成缓存溢出问题
修改字符串长度N次最多需要执行N次内存重新分配(由于SDS结构中有free字段的存在,因此缩小时,会把没有的char算到free中(惰性空间释放),而放大(空间预分配)时如果len长度<1M,则扩大后的len=原有len*2,如果len长度>=1M,则扩大后的len=原有len+1M)
可以保存文本或者二进制数据(因为SDS获取字符串时是根据len长度算的,而不是根据‘‘结尾之前的字符串算)
可以使用一部分<String.h>库中函数(不需要重新实现)
 
总结:
为什么Redis速度快?
一部分原因:
Redis自建的SDS结构,包括获取字符串长度的复杂度为O(1)、修改字符串长度N次最多需要执行N次内存重新分配、可以使用一部分<String.h>库中函数(不需要重新实现)。

以上是关于1简单动态字符串SDS的主要内容,如果未能解决你的问题,请参考以下文章

redis设计与实现之SDS简单动态字符串

redis设计与实现之SDS简单动态字符串

redis设计与实现之SDS简单动态字符串

redis 简单动态字符串 SDS

Redis源码解析-SDS简单动态字符串

关于redis中SDS简单动态字符串