redis设计与实现:简单动态字符串SDS

1、SDS定义

SDS遵循C字符串以空字符结尾的惯例,保存空字符的一字节空间不计算在SDS的len属性里面。空字符对于SDS使用者是透明的,遵循空字符结尾的好处是SDS可以直接重用一部分C字符串函数库里面的函数。

 

 

 

2、SDS和C字符串的区别

1)常数复杂度获取字符串长度C语言获取一个字符串的长度需要遍历整个字符串时间复杂度为O(N),而SDS在属性len中记录了字符串长度,获取字符串长度的时间复杂度为O(1)

2)杜绝缓冲区溢出:C字符串在执行拼接字符串时,如果长度不够会产生缓冲区溢出的问题,而SDS在拼接字符串时,会先检查空间是否足够,如果不满足会将空间自动扩展至执行修改所需的大小,然后再执行操作。

3)减少修改字符串时带来的内存重分配次数:C字符串的长度和底层数组的长度之间存在着关联性,每次增加或缩小一个C字符串,程序都需要对C字符串的数据进行内存重分配操作,为了避免C字符串的这种缺陷,SDS通过未使用空间解除了字符串长度和底层数组间的关系,通过未使用空间SDS实现了空间预分配和惰性空间释放两种优化策略。

a)空间预分配:用于优化SDS字符串的增长操作,当SDS的API需要对字符串进行空间扩展的时候,不仅会为SDS分配所必须的空间外,还会额外分配未使用空间。

额外分配未使用空间的策略:对SDS进行修改后,长度小于1M,那么程序分配和len属性同样大小的未使用空间,这时SDS len属性的值和free属性的值相同 ,如:修改后SDS的长度为13字节,那么程序也会分配13字节的未使用空间,SDS buf的实际长度为13+13+1 = 27字节(额外的一字节用于保存空字符); 如果对SDS进行修改后,长度大于等于1M,那么程序会分配1M的未使用空间,如:修改后SDS的长度为30M,那么程序会分配1M的未使用空间,SDS buf的实际长度为30M+1M+1byte 。

b)惰性空间释放:用于优化SDS字符串的缩短操作,当需要缩短SDS的字符串时,程序并不立即使用内存重分配来回收缩短后多出来的字节,而是使用free属性将这些字节的数量记录下来,并等待将来使用。

4)二进制安全:C字符串必须符合某种编码,字符串里面不能包含空字符,使得C字符串只能保存文本。SDS的API都是二进制安全的,都会以处理二进制的方式处理SDS存放在buf数组里的数据,写入什么样,读取就是什么样,redis不是用buf属性来保存字符,而是保存一系列的二进制数据。

5)兼容部分C字符串函数:

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值