本文是《Redis内部数据结构详解》系列的第二篇,讲述Redis中使用最多的一个基础数据结构:sds。
不管在哪门编程语言当中,字符串都几乎是使用最多的数据结构。sds正是在Redis中被广泛使用的字符串结构,它的全称是Simple Dynamic String。与其它语言环境中出现的字符串相比,它具有如下显著的特点:
- 可动态扩展内存。sds表示的字符串其内容可以修改,也可以追加。在很多语言中字符串会分为mutable和immutable两种,显然sds属于mutable类型的。
- 二进制安全(Binary Safe)。sds能存储任意二进制数据,而不仅仅是可打印字符。
- 与传统的C语言字符串类型兼容。这个的含义接下来马上会讨论。
看到这里,很多对Redis有所了解的同学可能已经产生了一个疑问:Redis已经对外暴露了一个字符串结构,叫做string,那这里所说的sds到底和string是什么关系呢?可能有人会猜:string是基于sds实现的。这个猜想已经非常接近事实,但在描述上还不太准确。有关string和sds之间关系的详细分析,我们放在后面再讲。现在为了方便讨论,让我们先暂时简单地认为,string的底层实现就是sds。
在讨论sds的具体实现之前,我们先站在Redis使用者的角度,来观察一下string所支持的一些主要操作。下面是一个操作示例:
以上这些操作都比较简单,我们简单解释一下:
- 初始的字符串的值设为”tielei”。
- 第3步通过append命令对字符串进行了追加,变成了”tielei zhang”。
- 然后通过setbit命令将第53个bit设置成了1。bit的偏移量从左边开始算,从0开始。其中第48~55bit是中间的空格那个字符,它的ASCII码是0x20。将第53个bit设置成1之后,它的ASCII码变成了0x24,打印出来就是’$’。因此,现在字符串的值变成了”tielei$zhang”。
- 最后通过getrange取从倒数第5个字节到倒数第1个字节的内容,得到”zhang”。
这些命令的实现,有一部分是和sds的实现有关的。下面我们开始详细讨论。
sds的数据结构定义
我们知道,在C语言中,字符串是以’