redis设计与实现(一)简单动态字符串

Redis没有直接使用C语言传统的字符串表示(以空字符结尾的字符数组,以下简称C字符串),而是自己构建了一种名为简单动态字符串(simple dynamic string,SDS)的抽象类型,并将SDS用作Redis的默认字符串表示。

例如:SET msg "hello world"

是保存了msg和hello world的SDS。

SDS的定义

每个sds.h/sdshdr结构表示一个SDS值。

/*
 * 保存字符串对象的结构
 */
struct sdshdr {
    
    // buf 中已占用空间的长度
    int len;


    // buf 中剩余可用空间的长度
    int free;


    // 数据空间
    char buf[];
};

SDS与C字符串的区别

常数复杂度获取字符串长度

在c语言中,获取字符串长度我们要一个个遍历字符数组。这样的话复杂度是O(N)。而sdshdr的len属性记录了字符串长度,所以获取长度的复杂度是O(1).

杜绝缓冲区溢出

c字符串有一个拼接函数:cha *strcat(char *dest, const char *src);
假设内存中有两个紧邻字符串:

如果一个程序员通过执行strcat(s1,"Cluster");那么Cluster会把后面空间的字符串覆盖掉。

而sdshdr则在拼接时会进行空间检查看是否足够,不够的话就将进行扩展。


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

如果用c语言字符数组进行字符串拼接,每次都需要重新分配内存。而SDS通过free字段,实现了空间预分配和惰性空间释放两种优化策略。

1.空间预分配
每次对SDS进行修改后,如果len属性的值小于1M,则分配相同大小的free内存空间。如果len属性的值大于1M,则分配1M的free内存空间,供以后使用。
2.惰性空间释放
当需要缩短SDS保存的字符串时,并不是立即回收空间,而是将这些字节放在free属性中,供以后使用。

保存二进制格式数据

如果我们在c语言中的字符数组中保存数据是这种形式:

那么c语言中以空字符判断只能读到Redis,而用SDS可以保证写入是什么样,读出是什么样,可以不仅仅用来存放字符串,而且可以存放二进制的表情文件内容等。

兼容部分C字符串函数

虽然SDS的API都是二进制安全的,但它们一样遵循C字符串以空字符结尾的惯例。这样保存的文本数据就可以重用一部分<string.h>库定义的函数。
例如:我们对比SDS和另一个C字符串:strcasecmp(sds->buf,"hello world");

总结

c字符串与SDS之间的区别:


SDS API





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值