Redis数据结构——SDS简单动态字符串

Redis中的简单动态字符串(SDS)是C语言字符串的增强版,提供常数时间获取长度、防止缓冲区溢出、减少内存重分配次数等优势。SDS在结构上包含len和free属性,确保了安全性和效率。此外,SDS是二进制安全的,适合存储各种数据格式,并能部分兼容C字符串函数。
摘要由CSDN通过智能技术生成

1,C语言中定义的字符串是以空字符结尾的字符数组,而Redis中自己构建了一种名为简单动态字符串(simple dynamic string,SDS)的抽象类型。
2,sds的结构如下:

struct sdshdr{
//记录buf数组中已使用字节的数量
//等于SDS所保存的字符串长度
int len;

//记录buf数组中未使用字节的数量
int free;

//字节数组,用于保存字符串
char buf[];
}

3,SDS与C字符串的区别
1)常数复杂度获取字符串长度,程序计算C字符串的长度的方法是遍历整个字符串,直到遇到空字符为止。这个操作的复杂度为O(N),而SDS在len属性中记录了SDS的长度,因此O(1)复杂度就可以获取。其实程序重复执行strlen函数也不会影响系统性能。
2)杜绝缓冲区溢出
因为C字符串不记录自身的长度,使用strcat函数的时候,不会先检测内存够不够,这就有可能造成缓冲区溢出。
SDS的空间分配策略杜绝了发生缓冲区溢出的可能性。当SDS的API需要对SDS进行修改时,API会先检查SDS的空间是否满足修改所需的要求,如果不满足要求的话,API会自动将SDS的空间扩展至执行修改所需的大小。
3)SDS可以减少修改字符串时带来的内存重分配次数
因为C字符串底层实现总是一个N+1个字符长度的数组,因为C字符串的长度和底层数组的长度之间存在着这种关联性,所以每次增长或缩短C字符串,程序总会对保存C字符串的数组进行一次内存重分配操作:
如果程序执行的是增长字符串的操作,比如拼接操作,那么在执行这个操作之前,程序需要先通过内存重分配来扩展底层数组空间大小——如果忘了这一步就会产生缓冲区溢出;
如果执行的是缩短字符串的操作,比如截断操作,那么在执行这个操作之后,程序需要通过内存重分配来释放字符串不再使用的那部分空间——如果忘了这一步就会产生内存泄漏。
SDS的额外分配的未使用空间数量由以下公式决定:
如果对SDS进行修改后,SDS的长度小于1MB,那么程序分配和len属性同样大小的未使用空间。如果修改后SDS的长度大于1MB,程序会分配1MB的未使用空间。
SDS的惰性空间释放并不是真正的释放空间,而是将要释放的空间加到free里面。
4)SDS是二进制安全的,SDS的API都会以处理二进制的方式来处理SDS存放在buf数组里的数据,数据在写入时什么样,它被读出时就是什么样。**Redis不是用buf这个数组来保存字符,而是用它来保存一系列二进制数据。**使用SDS来保存特殊数据格式就没有任何问题,因为SDS使用len属性的值而不是空字符来判断字符串是否结束。
5)SDS可以使用一部分C字符串函数

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值