hello,大家好。欢迎坐客老张的读书圈,这里专注于好书内容分享。
上一期我们介绍了本书的引言部分 redis为何性能如此强悍。其中也提到了专门设计的数据结构。这期一起来看第二章redis 字符串的结构《简单动态字符串》 大家也知道这个名称是根据英文 Simple Dynamic String 直译过来的。
作者在本章开头就提出了一个问题让大家思考: 如何实现一个扩容方便且二进制安全的字符串?不知道这个问题你有没有被面试官问到过,反正老张是被问到过。
大家知道在C语言中,用"0" 表示字符串的结束,如果字符串中本身就包含 "0" 字符,那么字符串就会被截断,即非二进制安全;假如使用某种机制,保证读写字符串时不损害其内容,则是二进制安全。
由这个问题引入sds的设计。
struct sds { int len; // buf中已占用的字节数 int free; // buf中剩余可用的字节数 char buf[]; // 真正存放字符串的数据空间}
这样就可以通过len字段,知道该取多少个字节的字符。就算中间有0也都取出来。而且
早起的redis3.2之前的sds就是这样设计的。
那么redis为什么要这么设计呢?主要有以下几点原因:
- 有单独的统计变量len 和 free 可以很方便地得到字符串已使用 和 空闲长度。
- 字符串内容放在柔性数组buf中(如果有需要,可以留言 咱单独介绍下柔性数组),sds对上层暴露的指针不是指向结构体sds的指针,而是指向柔性数组buf的指针。上层可以像读取C字符串一样读取sds的内容,这样兼容C语言处理字符串的各种函数。
- 由于有长度统计变量len的存在,读写字符串时就可以不依赖"0"结束符,保证了二进制安全。这样就算字符串中间有"0"也会继续读取后面的内容。
这里引入了柔性数组的概念。
之所以用柔性数组存放字符串,是因为柔性数组的地址和结构体是连续的,这样查找内存更快(因为不需要额外通过指针找到字符串的位置);可以很方便的通过柔性数组的首地址,这样就可以通过移动指针获得其他的变量了。
那么这样设计有没有什么问题呢?欢迎留言讨论。下期我们继续交流沟通。
大家如果喜欢老张的分享,欢迎点赞,转发,关注三连。
您的支持也是老张坚持原创的动力。希望老张能和你们一起成长。
#读书# #Redis# #程序员# #编程# #缓存#