在Redis数据结构详细解释SDS
在Redis数据结构详细解释SDS广泛用于Redis的字符串。在Redis中,所有的数据都存储在词典(图),而该词典的关键是字符串类型,并对数据字典的值大的一部分,它也是一个字符串。以下是具体的存储结构的SDS:
正如你可以看到从图,有三个属性:莱恩,自由,和SDS缓冲阵列。这里,LEN字段用于存储字符数包含在SDS的字符串。自由场中使用buf数组保存零件的长度,而buf数组实际上是用来保存字符串。例如,下面的结构节省了你好世界!这个字符串:
这里需要注意的是,与SDS字符串一样,您需要在字符串的结尾添加一个 0来表示字符串的结束!字符串,而自由属性保留数组中的位数。buf数组实际保存字符串,位空字符和备用。
原因Redis使用SDS结构代替C字符串如下:
获取字符串长度的常数复杂度的长度。
通过读取SDS对象的莱恩属性的值,我们可以使用O(1)得到SDS对象保存的字符串的长度,而在C字符串中,我们必须遍历整个数组来得到字符串的长度,时间复杂度是O(n)。
消除缓冲区溢出
在C,如char* strcat(char* dest,字符串常量)功能连接到dest src结束,但C字符串dest数组假设有足够的空间来保存SRC dest数组,如果数组长度不够将导致缓冲区溢出;在SDS对象提供了类似的功能sdscat(SDS SDS,const char * T)和SDS sdscatsds(SDS,const SDS T),这两个函数调用之前会检查是否自由属性的目标对象的SDS可以保存的字符串的长度是相连的,如果不是,将目标对象SDS膨胀,使对象不会SDS缓冲区溢出造成的。
当修改的字符串被减少时内存重新分配的次数。
在修改时间的SDS,Redis通过空间预分配和释放确保惰性空间对象的后续SDS无BUF数组的频繁修改SDS往往指定空间对象;并为每个字符串,修改它,需要一个空间的分配和复制操作。
二进制安全
对于C字符串,因为迹象判断是否结束是一个字符串的第一年底开始0人物的遭遇,这限制了C字符串不能保存为图片,音频,视频,压缩文件等二进制存储的内容;并对SDS的对象,因为马克判断到底是len属性就是说,无论len长度,如果 0不影响是否结束使用含有缓冲数组的判断。
空间分配和惰性空间释放SDS以上。SDS通过这两种操作大大简化了字符串的修改和空间分配。
空间预分配意味着当SDS对象结构的增加,如修改增加或连接另一个字符串结束其内容,SDS将预先分配一定的空间来防止未来的修改。以下是空间预分配redis主代码:
SDS sdsmakeroomfor(SDS,size_t addlen){
结构sdshdr * SH * newsh;
获取s空闲空间的长度。
size_t自由= sdsavail(S);
size_t Len,newlen;
自由空间足够,无需扩展,直接返回。
如果返回的(自由> = addlen);
s占用了空间/获取长度
len = sdslen(S);
SH =(void *)(S(sizeof(struct sdshdr)));
所需的最小长度
newlen =(长+ addlen);
根据新长度,s分配所需的空间大小
如果(newlen < sds_max_prealloc)
/ /如果新的长度小于sds_max_prealloc
如何对所需的空间长度进行二次分配
newlen * = 2;
其他的
长度或长度加sds_max_prealloc分布
newlen = sds_max_prealloc;
o o(n)
newsh = zrealloc(SH,sizeof(struct sdshdr)+ newlen + 1);
内存分配不足,失败,返回
如果(newsh = = null)返回null;
/更新SDS自由长度
newsh ->自由= newlen -莱恩;
返回值
返回newsh -> buf;
}
从图中可以看出,当你想加入的SDS目标不是直接的短期收益将增加的缓冲数组的内容自由财产的内容可以添加到目标表的对象;当你想要长于自由SDS的目标对象属性添加内容,将计算长度增加内容和SDS和newlen,如果newlen小于sds_max_prealloc或1M,新创建的缓冲区数组的长度是newlen两倍,如果newlen大于sds_max_prealloc,新创建的缓冲区数组的长度是newlen + sds_max_prealloc,仅保留空间分布1m。空间预分配确保SDS对象的备用位长度最多为1倍展开后字符串的长度,这确保后续SDS对象修改将尽可能少地分配空间。
惰性空间释放是指当SDS的目的是减少手术时间,它不会直接而缩短的阵列目标的长度,但只有改变SDS对象值的len属性,数组的超出部分是存储在自由的属性,这样才能确保后续可能是SDS操作不需要增长分配空间。
最后,需要解释的是,SDS对象也被用作C和 0的字符串结尾。原因是,Redis也是用C语言写的。在0结束时,可以在C函数库的一部分中使用字符串操作的一些函数。
通过SDS对象可以发现上述描述,Redis在SDS对象大大减少了手术可能的字符串处理的复杂性,和大部分的操作基本上可以在很短的时间内完成,可确保高的Redis的字符串处理率。
谢谢你的阅读。我希望你能帮助你,谢谢你对这个站的支持。