redis源码系列之一-sds

本文探讨Redis中sds的使用,分析sds优于传统C字符串的原因,讲解sds不同版本的数据结构及其优势,以及如何通过优化减少空间浪费。同时,文章提及了sds的创建、释放、扩容和拼接等API的源码实现。
摘要由CSDN通过智能技术生成

本月开始更新redis源码系列:

其他文章链接稍后更新~~

1.sds的介绍

2.为什么不使用string而是使用sds?

1.保存了一个len,可以直接获取字符串长度

2.杜绝缓冲区溢出

3.减少字符串修改时重新分配内存次数

4.二进制安全

3.sds3.2之前的数据结构

struct sds {
    int len;// buf 中已占用字节数
    int free;// buf 中剩余可用字节数
    char buf[];// 数据空间,柔性数组的地址和结构体是连续的,这样查找内存更快(因为不需要额外通指针找到字符串的位置);可以很方便地通过柔性数组的首地址偏移得到结构体首地址,进而能很方便地获取其余量
};

这样设计的优点

 

 4.我们从一个简单的问题开始思考:不同长度的字符串是否有必要占用相同大小的头部?一个int占4字节,32位,在实际应用中,存放于Redis中的字符串往往没有这么长,每个字符串都用4字节存储未免太浪费空间了。我们考虑三种情况:短字符串,len和free的长度为1字节就够了;长字符串,用2字节或4字节;更长的字符串,用8字节。

问题1:如何区分这3种情况?
问题2:对于短字符串来说,头部还是太长了。以长度为1字节的字符串为例,len和free本身就占了2个字节,能不能进一步压缩呢?
对于问题1,我们考虑增加一个字段flags来标识类型,用最小的1字节来存储,且把flags加在柔性数组buf之前,这样虽然多了1字节,但通过偏移柔性数组的指针即能快速定位flags,区分类型,也可以接受;

对于问题2,由于len已经是最小的1字节了,再压缩只能考虑用位
来存储长度了。
结合两个问题,5种类型(长度1字节、2字节、4字节、8字节、小于1字节)的SDS至少要用3位来存储类型(23 =8),1个字节8位,剩余的5位存储长度,可以满足长度小于32的短字符串。

5.在Redis 5.0中,我们用如下sdshdr5结构来存储长度小于32的短字符串。

struct __attribute__ ((__packed__))sdshdr5 {
unsigned char flags; /* 低3位存储类型, 高5位存储长度 flags占1个字节,其低3位(bit)表示type,高5位(bit)表示长度࿰
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值