专栏名称: 数据分析与开发
伯乐在线旗下账号,分享数据库相关技术文章、教程和工具,另外还包括数据库相关的工作。偶尔也谈谈程序员人生 :)
目录
相关文章推荐
数据中心运维管理  ·  弱电智能化中究竟有多少个子系统? ·  23 小时前  
数据中心运维管理  ·  超大规模数据中心如何重新思考冷却效率 ·  2 天前  
数据中心运维管理  ·  锂电池火灾处理难度 ·  昨天  
AustinDatabases  ·  P-MySQL ... ·  昨天  
阿里云大数据AI平台  ·  【5月重点功能发布】阿里云大数据+ AI ... ·  昨天  
阿里云大数据AI平台  ·  【5月重点功能发布】阿里云大数据+ AI ... ·  昨天  
51好读  ›  专栏  ›  数据分析与开发

Redis 内部数据结构详解(2):sds

数据分析与开发  · 公众号  · 数据库  · 2017-04-22 09:58

正文

请到「今天看啥」查看全文



以上这些操作都比较简单,我们简单解释一下:


  • 初始的字符串的值设为”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语言中,字符串是以’\0’字符结尾(NULL结束符)的字符数组来存储的,通常表达为字符指针的形式(char *)。它不允许字节0出现在字符串中间,因此,它不能用来存储任意的二进制数据。


我们可以在sds.h中找到sds的类型定义:


typedef char *sds;



肯定有人感到困惑了,竟然sds就等同于char *?我们前面提到过,sds和传统的C语言字符串保持类型兼容,因此它们的类型定义是一样的,都是char *。在有些情况下,需要传入一个C语言字符串的地方,也确实可以传入一个sds。但是,sds和char *并不等同。sds是Binary Safe的,它可以存储任意二进制数据,不能像C语言字符串那样以字符’\0’来标识字符串的结束,因此它必然有个长度字段。但这个长度字段在哪里呢?实际上sds还包含一个header结构:



sds一共有5种类型的header。之所以有5种,是为了能让不同长度的字符串可以使用不同大小的header。这样,短字符串就能使用较小的header,从而节省内存。


一个sds字符串的完整结构,由在内存地址上前后相邻的两部分组成:


  • 一个header。通常包含字符串的长度(len)、最大容量(alloc)和flags。sdshdr5有所不同。


  • 一个字符数组。这个字符数组的长度等于最大容量+1。真正有效的字符串数据,其长度通常小于最大容量。在真正的字符串数据之后,是空余未用的字节(一般以字节0填充),允许在不重新分配内存的前提下让字符串数据向后做有限的扩展。在真正的字符串数据之后,还有一个NULL结束符,即ASCII码为0的’\0’字符。这是为了和传统C字符串兼容。之所以字符数组的长度比最大容量多1个字节,就是为了在字符串长度达到最大容量时仍然有1个字节存放NULL结束符。


除了sdshdr5之外,其它4个header的结构都包含3个字段:


  • len: 表示字符串的真正长度(不包含NULL结束符在内)。


  • alloc: 表示字符串的最大容量(不包含最后多余的那个字节)。


  • flags: 总是占用一个字节。其中的最低3个bit用来表示header的类型。header的类型共有5种,在sds.h中有常量定义。


#define SDS_TYPE_5  0

#define SDS_TYPE_8  1

#define SDS_TYPE_16 2

#define SDS_TYPE_32 3

#define SDS_TYPE_64 4







请到「今天看啥」查看全文