Redis的数据结构之SDS及常用API

Redis的数据结构之SDS

Redis没有使用C语言风格的字符串, 而是使用了一种叫SDS的简单动态字符串。

C风格的字符串用来作为字符串字面量, 比如打印日志。当表示一个可以被修改的字符串的时候, redis会用SDS表示。

redis是key_value型数据库, 它的key和value都是一个对象。

SDS除了保存数据库中的字符串外还用作缓冲区(buffer): AOF模块中的AOF缓冲区, 以及客户端状态中的输入缓冲区。

SDS的定义

//sds.h/sdshdr 结构表示一个SDS值
struct sdshdr {
    int len; //记录buf中使用的字节数量
    int free; //记录还未使用的字节数量
    int buf[]; //字节数组用来保存字符串
};

在这里插入图片描述
需要注意的是: buf中的最后有’\0’, 并且这个字符没有计入len中, 这样设计的原因是为了遵循C语言的标准, 这样就可以使用C语言的一些函数. 比如可以直接 printf("%s", s->buf);

SDS和C语言字符串的区别
  • 常数时间复杂度获取字符串长度

    C语言使用一个N+1长度的数组表示长度为N的字符串, 求C语言字符串长度需要遍历整个数组, 时间复杂度为O(N). 而 SDS 使用结构体中的len字段可以实现O(1)的时间复杂度求字符串的长度.

  • 杜绝缓冲区溢出

    C语言不记录字符串长度, 如果拼接字符串的时候分配的内存空间不够的话就会造成缓冲区溢出. 而SDS记录未使用的缓存区空间(free字段), 所以在拼接字符串的时候就会先检查内存够不够, 不够的话就扩展内存再进行拼接操作.

  • 减小修改字符串时带来的内存重新分配次数

    SDS的free字段会对SDS的空间进行预分配, 这样就可以避免像C语言字符串那样改变时需要重新分配内存的尴尬.

  • 二进制安全

    C语言字符串中字符必须符合某种编码, 除了字符串末尾之外不能包含空格, 否则容易被当做字符串结尾.这样就限制了保存二进制的能力.

    而redis为了确保可以在各种不同的场景中使用, Redis的API都是二进制安全的. 也就是说写进去什么样, 读出来就是什么样.

  • 兼容部分C语言字符串

    SDS以’\0’结尾, 所以可以复用C语言一些现成的函数, 比如strcasecmp函数.

SDS的主要API

函数作用时间复杂度
sdsnew创建一个包含给定C字符串的SDSO(N)
sdsempty创建一个空的SDSO(1)
sdsfree释放给定的SDSO(N)
sdslen返回SDS已经使用过的空间字符数O(1)
sdsavail返回SDS中未使用的空间字符数O(1)
sdsdup创建一个给定SDS的副本O(N)
sdsclear清空SDS中字符串保存的内容O(1) 惰性空间释放
sdscat将C字符串拼接到SDS字符串末尾O(N)
sdscatsds将SDS拼接到另一个SDS中O(N)
sdscpy将给定的C字符串复制并覆盖到SDS中的字符串O(N)
sdsgrowzero用空字符将SDS扩展至给定的长度O(N)
sdsrangeSDS区间内的数据保留, 区间之外的数据覆盖或清除O(N)
sdstrim传SDS和C字符串, 移除SDS左右两边分别在C出现的字符O(M*N)
sdscmp比较两个SDS是否相等O(N)
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值