【Redis设计与实现】简单动态字符串

简单动态字符串 — SDS

1. SDS类型定义

  Redis底层字符结构没有沿用C语言中的字符,从新定义了一种 SDS ( simple dynamic string )的抽象类型。

struct sdshdr {
    
    // 计入buf字符的长度
    int len;
    
    // 记录buf中空闲长度
    int free;
    
    // 字节组,
    char buf[]
}

2. SDS 特点

  遵循C 语言习惯,每个字符后使用’\0’结尾,最后一个空字符不计入 len 中。则SDS的buf字段 可以直接使用C语言函数库

3. SDS 优势

  • 降低长度获取复杂度
  • 杜绝缓冲区溢出
  • 减少字符串修改导致内存重新分配次数
  • 二进制安全
  • 兼容 C 字符串函数库(<String.h>)

3.1 降低长度获取复杂度

  C语言判断字符串长度,需要遍历存储所有字符,累加得到结果,复杂度为O(N),SDS 直接通过Len字段可以获取长度,复杂度为O(1)。

3.2. 杜绝缓冲区溢出

  C 语言在字符串 拼接时候,需要提前分配好空间,不然会因为内存不足,发生溢出或错误修改。SDS则会提前判断大小,内存不足会进行扩容。再拼接。

3.3 减少字符串修改导致内存重新分配的次数

  内存重新分配设计复杂的算法,比较耗时,程序修改字符串的情况不太常出现,同时Redis作为高性能数据库,频繁发生重新分配内存会对性能造成影响是不可取的。Redis解决这个问题是通过空间预分配和惰性空间释放。

  • 空间预分配

  当 SDS 字符串发生修改,并且需要 SDS 的需要扩容的时候,程序不仅会分配必要空间,还会额外对其分配未使用空间。额外分配未使用空间有两种方式:

  1. SDS 长度 < 1MB, 分配与 SDS 等长空间
  1. SDS 长度 >= 1MB, 分配 1MB 空间
  • 惰性空间释放

  当 SDS 字符串发生缩短操作,SDS 不会立刻将缩短后多出的字节释放,而是由 free 字段记录,当 SDS 发生修改需要时,添加的内容小于 free 字节长度,则无需重新分配空间。此外,我们无需担心内存泄露,SDS 提供 API 可以真正释放未使用空间。

3.4 二进制安全

  C 语言的字串因为编码问题,最后一个字符为空字符(‘\0’),不允许有其他字符,否则其他字符会被忽略,无法读取。因此受限,无法保存 图片,音频,压缩文件等二进制数据。SDS 结构中的 buf 保存的都是二进制数据,未对保存内容做任何的假设与限制。因此,SDS 保存前保存后一致。SDS 是通过 len 字段读取内容。保证完整读取。

3.5 兼容部分C字符串函数

  因为SDS 遵守 C 语言字符末尾使用空字符(‘\0’)结尾,如此我们可以直接使用 C 字符串函数库。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值