Redis设计与实现之简单动态字符串
简单动态字符串:
Redis是使用C语言编写的,但是并没有使用C语言的现有的字符串类型来保存包含字符串的健值对。而是redis自己构建了一个名为简单动态字符串(simple dynamic string,SDS)的抽象类型,那么当初开发redis的作者是基于什么样的考虑呢?
当我们通过redis客户端命令 set msg "hello world",redis在底层创建的是一个键值对,键和值的底层都是SDS结构,SDS的数据接口包含三个属性:
int len //记录buf数组中已使用字节数量
int free//记录buf数组中未使用的字节数量
char buf[] //字节数组,用于保存字符串
1.len属性方便常数复杂度获取字符串的长度,而用C的字符串,复杂度是O(N)
2.杜绝缓冲区溢出,C字符串如果在修改字符串之前不分配足够空间,会造成内容溢出。SDS的空间分配策略是先判断是否满足修改所需空间,不满足会进行自动空间扩展,然后去真正修改操作。
3.减少修改字符串时带来的内存重分配次数。C字符串底层是N+1个字符长的数据,多出来的1是保存空字符串用的。每次拼接都需要内存重分配。
SDS会在第一次修改字符串时,数组空间进行扩容,扩容空间会高于实际所需空间,这样避免了每次修改都需要扩容。删除部分字符数据也是删除内容,但是空间保留。为将来修改新增派上用场。
4.二进制安全:SDS以处理二进制的方式来处理SDS存放在buf字节数组的数据,写入是什么,读取就是什么。所以不是字符数组而是字节数组。C字符串会把读取的第一个空字符串认为是字符串的结尾,所以字符串中不能保存空字符,所以C字符串只能保存文本,无法保存图片,影像,音频等二进制数据。
5.兼容部分C字符串函数。