您的位置:首页 > 数据库 > Redis

Redis的简单动态字符串SDS、链表

2018-02-05 15:11 609 查看
Redis没有直接使用C语言传统的字符串表示,而是自己构建了一种名为简单动态字符串(simple dynamic string,SDS)的抽象类型,作为其默认字符串。SDS还被用作缓冲区。

在redis中创建一个新的键值对。键是一个SDS字符串对象;值可以是字符串对象、列表对象(list object)、哈希对象(hash object)、集合对象(set object)、有序集合对象(sorted set object)这五种对象其中的一种。

SDS的结构定义

SDS遵循C字符串以空字符结尾的惯例。这样可以重用一部分C字符串函数。



对上面的SDS执行拼接操作后,free和len都会是13。



1、空间预分配

 1、修改sds时,如果长度没有超过可用空间,不会新分配空间。
 2、如果对SDS进行修改之后,长度将小于1MB,那么程序分配和len属性同样大小未使用的空间。假设上图中len=13,那么free-13,sds的buf数组的实际长度是13+13+1=27字节。
 3、如果对修改后的长度大于1MB,那么程序会分配1MB未使用空间。那么实际长度是30M+1M+1byte。

2、惰性空间释放

对SDS进行缩短操作,程序不会立即回收多出来的字节。在有需要的时候,调用SDS的API来释放未使用空间。

二进制安全

C字符串的字符必须符合某种编码(比如ASCII),并且除了字符串的末尾之外,字符串里面不能包含空字符,否则最先被程序读入的空字符串将被误认为是字符串结尾,这些限制使得C字符串只能保存文本数据,而不能保存图片、音频、视频、压缩文件这样的二进制数据。

SDS的buf属性称为字节数组,因为这个数组不是来保存字符的,而是保存一系列的二进制数据。





链表

链表提供了高效的节点重排能力,以及顺序性的节点访问方式,还可以增删。因为Redis使用的C语言并没有内置这种数据结构,所以redis构建了自己的链表实现。

链表在redis中应用非常广泛,比如列表键的底层实现之一,当一个列表键包含了数量较多的元素,又或者列表中包含的元素都是较长的字符串时,就会用链表实现列表键。此外,发布于订阅、慢查询、监视器等功能也用到了链表。redis本身还用链表来保存多个客户端的状态信息,以及来构建客户端输出缓冲区。

listNode组成链表,adlist.h/list来持有前者。



多态的特性:链表节点使用void* 指针来保存节点值(void *为“无类型指针”,void *可以指向任何类型的数据。),并且可以通过list结构的dup、free、match三个属性为节点值设置类型,所以链表可以用于保存各种不同类型的值。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: