Redis设计与实现之字符串类型在Redis中的底层实现SDS

我们知道Redis中最基础的类型就是字符串,但是Redis中的字符串与C语言中的常量字符串不相同,实际上是对C字符数组的封装,因为他需要支持动态扩张,支持值能够被修改,我们知道常量字符串是不能被修改的,read only,有点类似于C++中的std::string.

127.0.0.1:6379> set name zhangsan
OK

上面指令中,在Redis中,底层分别是保存着name和zhangsan的SDS类型的对象或者实例。

127.0.0.1:6379> LPUSH num 1 2 3 4
(integer) 4

同样的,底层对应着的是num,1,2,3,4等五个字符串的SDS字符串对象实例。

定义

struct sdshdr
{
	//当前字符串的长度,或者字符串数组已使用的容量
	int len;
	//数组中未使用字节的数量
	int free;
	//保存字符串的地方,以'\0'结尾
	char buf[];
};

学过C++的同学有没有感觉就是用结构图封装了一个简单string,C++中的string底层是一个指针,也支持扩容修改等操作。

如图所示:
在这里插入图片描述

从这里就可以看出来,SDS记录了字符串的长度,那么我们获取字符串长度是O(1)的,在C语言中,我们获取字符串长度是O(n)的,因为需要一直遍历到’\0’为止。

127.0.0.1:6379> STRLEN name
(integer) 8

API

也提供了一些给类型的一些操作,比如字符串的拷贝,连接,截取等,但是都比较安全的。

比如字符串的拼接,拼接前会进行查看当前剩余的空间够不够保存的,不够的会进行底层字符数组重分配,当然他可能会进行空间的预分配,为了提高效率,减少系统调用的发生。但是C语言不会进行检查,所以可能会发生内存越界等崩溃bug.

对于内存的回收,使用的是“惰性空间释放”,也就是不是直接将内存归还操作系统,而是移动free的位置即可,当然真正需要释放的时候,他会真正的将资源归还给操作系统,它提供了这样的接口。

二进制安全

C字符串

C字符串只能用于存放文本数据,对于图片,视频等二进制数据不能很好的支持,因为C字符串只能在末尾包含空的字符串,如果在中间包含,可能导致一些数据被丢失。

SDS

底层是一个数组,无所谓空的字符串,怎么存入,获取的时候怎么返回即可,所以能很好的支持二进制类型数据的存放。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值