Redis底层数据结构之SDS(simple dynamic string)

最近在找工作,一直问底层实现,接下来记录一下redis的底层实现。今天说下 简单动态字符串,也就是SDS。

SDS是redis的核心数据。虽然简单,但特别重要。包含字符串的键值对的数据类型都是由SDS实现的,而不是简单的一个C语言字符串,下面看一下这个SDS是什么样子的。

  1.SDS数据结构

struct sdshdr{

 //字符串长度
   int len;
 //buf数组中未使用的字节数量
   int free;
//字节数组,用于保存字符串
   char buf[];

}

如上,其实只有len,free,buf。   

2.而为什么不用C字符串,而用SDS 

   下面说几个原因

     ①可以直接获取字符串的长度。SDS用len直接表示了,而C语言字符串需要遍历计数,时间复杂度是 O(1)与O(N)的区别。

   ②可以减少动态申请内存次数。因为有free的存在,可以在这里进行内存的增删。

   ③二进制安全,由于C字符串结尾是空字符串,所以如果有图片之类的压缩字符文件,在C语言中看到空字符串就认为结束了,这样不能标志二进制数据。而SDS是用len来表示字符串结束。

 3.SDS具体使用简单介绍

  ①例如

   redis> SET msg "hello world"

在这条简单的命令中,  msg是一个msg对象,hello world也是一个SDS对象。这对象就如上面所定义的结构体那样。

②例如

redis> RPUSH fruits " apple"   "banana" "cherry"

 在这条命令中,fruits 是一个SDS对象

apple ,banana,cherry 也分别代表一个SDS对象

③其他方面应用简介

AOF缓冲区,客户端状态输入缓冲区都是由SDS实现的

4.C字符串与SDS区别

①获取字符串长度复杂度为O(N);获取字符串长度复杂度为O(1)

②API是不安全的,可能造成缓冲区溢出;API是安全的,不会造成缓冲区溢出

③修改字符串长度必然需要执行N此内存重分配;修改字符串长度N次最多需要执行N次内存重分配。

④只能保存文本数据;可以保存文本或二进制数据

⑤可以使用<string.h>库所有函数;可以使用部分<string.h>库中的函数

参考书籍:《Redis设计与实现》黄建宏 著

PS:只是为了学习记录,如果有侵权告知,立马删除。如果有错误,请留言,我尽快改正。

猜你喜欢

转载自blog.csdn.net/wuye_lh/article/details/107021924