redis数据结构

SDS是一种动态字符串,在Redis中用于优化C字符串的不足,如它自身保存长度信息,防止缓冲区溢出,减少内存重分配,并且是二进制安全的。在3.x版本中,SDS对不同长度的字符串进行了优化,使用不同字节数表示长度和空闲空间,通过位运算标识字符串类型。此外,SDS的指针直接指向buf[],兼容C语言的string.h库函数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

SDS动态字符串(SDS)与C字符串的区别:

1.C语言对字符串长度的统计,就完全来自遍历,

SDS自己本身就保存了长度的信息

2.杜绝缓冲区溢出。C是不记录字符串长度的,一旦我们调用了拼接的函数,如果没有提前计算好内存,是会产生缓存区溢出的。SDS结构存储了当前长度,还有free未使用的长度。

3.减少修改字符串时带来的内存重分配次数。C语言字符串底层也是一个数组,每次创建的时候就创建一个N+1长度的字符。Redis为了避免C字符串这样的缺陷,就分别采用了两种解决方案:1空间预分配。2惰性空间释放

4.二进制安全

SDS数据结构优化:

1.在 Redis3.x 版本中不同长度的字符串占用的头部是相同的,如果某一字符串很短但是头部却占用了更多的空间,这未免太浪费了。所以我们将 SDS 分为三种级别的字符串:

  • 短字符串(长度小于32),len和free的长度用1字节即可;

  • 长字符串,用2字节或者4字节;

  • 超长字符串,用8字节。

我们可以在 SDS 中新增一个 type 字段来标识类型,但是没必要使用一个 4 字节的int类型去做!可以使用 1 字节的char类型,通过位运算(3位即可标识2^3种类型)来获取类型。

对齐填充
 Redis选择不对齐,原因:

有个细节各位需要知道,即 SDS 的指针并不是指向 SDS 的起始位置(len位置),而是直接指向buf[],使得 SDS 可以直接使用 C 语言string.h库中的某些函数,做到了兼容,十分nice~。

如果不进行对齐填充,那么在获取当前 SDS 的类型时则只需要后退一步即可flagsPointer = ((unsigned char*)s)-1;相反,若进行对齐填充,由于 Padding 的存在,我们在不同的系统中不知道退多少才能获得flags,并且我们也不能将 sds 的指针指向flags,这样就无法兼容 C 语言的函数了,也不知道前进多少才能得到 buf[]

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值