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

Redis 的简单动态字符串(Simple Dynamic String, SDS)是 Redis 数据库内部用于存储字符串的一种自定义数据结构,它是 Redis 对传统 C 语言字符串(以空字符 ‘\0’ 结尾的字符数组)的一种增强版本,旨在解决原生 C 字符串在实际使用中遇到的动态增长、性能瓶颈和二进制安全等问题。下面是一些关于 SDS 关键特性和源码解析要点:

SDS 结构定义

在 Redis 源码中,SDS 结构通常定义如下:

typedef char *sds;

struct sdshdr {
    // 记录已占用空间(包括结束符'\0')
    int len;
    // 记录未使用的预留空间大小
    int free;
    // 字节数组,用于存储字符串内容
    char buf[];
};

实际上,SDS 是通过 sdshdr 结构体来包装原始的 C 字符数组 buf,并在其前增加两个额外的字段 lenfree,分别记录已经使用的字符数量(不含结束符)和剩余可用空间大小。

SDS 主要特点

  1. O(1) 时间复杂度获取字符串长度:由于 SDS 内部维护了已使用的长度信息 len,所以获取字符串长度不再需要遍历整个字符串,时间复杂度降为 O(1)。

  2. 空间预分配:SDS 在执行字符串增长操作时,不仅分配当前所需的空间,还会根据配置预先分配额外的未使用空间,从而减少连续增长时的频繁内存重分配。

  3. 惰性释放:当缩短字符串时,不会立即回收多出来的空间,而是将这部分空间记入 free 字段,以便后续可能的增长操作复用。

  4. 二进制安全:SDS 可以容纳包含 ‘\0’ 字符在内的任意二进制数据,这使得它不仅可以存储文本字符串,还能存储任何形式的二进制数据。

  5. 兼容 C 字符串:虽然 SDS 是自定义类型,但由于末尾仍然保留了 ‘\0’ 结束符,所以可以直接传递给 C 语言标准库中的字符串处理函数使用。

SDS 常用操作

Redis 提供了一系列针对 SDS 的 API 函数,例如:

  • sdsnewlen()sdsempty() 创建新的 SDS 字符串;
  • sdscat()sdscatsds()sdscpy() 等函数用于拼接、复制字符串;
  • sdsgrowzero() 动态调整 SDS 缓冲区大小;
  • sdsfree() 释放 SDS 所占用的内存。

这些函数在执行过程中都会考虑到 SDS 的特性,以确保字符串操作高效、安全并且避免常见陷阱。通过这样的设计,Redis 在处理大量字符串操作时获得了显著的性能优势。

  • 5
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值