Redis-底层数据结构-简单动态字符串

简单动态字符串(SDS)

redis是C语言实现的,但redis中的字符串并没有直接用C语言中的字符串表示,而是自己构建了一种简单的动态字符串类型(SDS)。

在redis里面,C字符串只用作字面量,用在一些不会修改的地方,eg:打日志。

SDS的结构

struct sdshdr {
	// 记录buf数组已经使用的字节数量
	// 等于SDS所保存字符串的长度
	int len;
	
	// 记录buf数组未经使用的字节数量
	int free;
	
	// 字节数据,用于保存字符串
	char buf[];
}

图2-1展示了一个SDS示例:
在这里插入图片描述

  • free属性的值为0,表示这个SDS没有分配任何未使用的空间。
  • len属性的值为5,表示这个SDS保存了一个5字节长的字符串。
  • buf属性是一个char类型的数组,数组的前5个字节分别保存了’R’、‘e’、‘d’、‘i’、‘s’ 五个字符,最后一个字节保存了空字符’\0’。(注:SDS遵循C字符串以空字符串结尾的惯例)

SDS与C字符串的区别

  • 常数复杂度获取字符串长度。获取C字符串的长度,需要遍历整个字符串,直至空字符串;SDS直接获取len属性即可获取长度。
  • 杜绝缓冲区溢出。C字符串进行数据拼接时,假设用户已经主动分配了足够内存,假设不成立时会造成缓冲区溢出;SDS使用sdscat函数进行字符串拼接时,sdscat会先检查给定的SDS的空间是否足够,空间不够的话,sdscat会先扩展SDS空间,之后才执行拼接操作。
  • 减少修改字符串时带来的内存重分配次数。C字符串每次进行增长或者缩短字符串的操作时,都必须通过内存重分配调整C字符串底层数组的大小;SDS通过“空间预分配”和“惰性空间释放”减少内存重分配次数。
  • SDS是二进制安全的。C字符串只能保存文本数据,SDS API会以处理二进制的方式处理SDS保存在buf数组里的数据。
  • 兼容部分C字符串函数。

SDS减少内存重分配的方式

1、空间预分配
空间预分配用于优化SDS的字符串增长操作:当SDS空间需要扩展时,程序不仅会为SDS分配修改必须的空间,还会分配额外的未使用空间。
在下次进行字符串增长操作时,SDS API会先检查未使用空间是否足够,足够的话,无须进行内存重分配。

2、惰性空间释放
惰性空间释放是用于优化SDS的字符串缩短操作,当SDS API需要缩短SDS保存的字符串时,程序并不立即使用内存重分配来回收缩短后多出的字节,而是使用free属性将这些字节的数量记录起来,并等待将来使用。
同时,SDS也提供了相应的API,可以在有需要的时候,真正释放SDS未使用空间,避免内存浪费。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值