简单动态字符串
基本结构
simple dynamic string(sds)将c语言的字符串进行了简单的封装。
- free 记录了目前未使用
字节的数量(此处为1) - len 记录了buf数组当前已使用
字节的数量(此处为3) - buf 用于保存字符串(此处为"RGB")
使用go语言的代码实现
type sdshdr struct {
len int
free int
buf[] byte
}
优点
这样设计相比于c语言的字符串有很多优势
- 获取长度不用遍历
- 防止溢出
- 减少
重分配次数 二进制安全- 兼容部分c字符串的函数
重分配
因为c语言的字符串是无法修改的,而Redis这样的结构设计后可以动态扩容。扩容就会涉及到重新分配新的空间。一般我们能想到的策略就是分配旧的长度加新的长度的新字节数组,然后复制过去。
但是Redis被要求速度快,数据频繁修改且较大的话会极度影响性能和效率。
于是sds实现了空间预分配和惰性空间释放两种优化策略
-
空间预分配:
- len < 1MB --> free = len
- len >= 1MB --> free = 1MB 预分配也就是给free设置大一点
-
惰性空间释放:
不直接释放空间,而是用增加free的值来方便后面再扩展
二进制安全
c语言字符串只能保存文本,不能保存二进制,例如: '\0'不能出现在中间,c语言会误认为已经结尾了
所以sds底层用的是字节数组确保二进制的安全,主要是Redis的sds使用len来判断字符是否结束