Redis源码剖析——intset

/ 0评 / 0

intset是Redis源码里一个比较基础的组件,和非常多的部分有耦合,因此也就不单独谈其所关联的部分了。总的来说intset实现了这样一个东西:一个多编码的顺序整型数据存储结构。(以下代码位于intset.c与intset.h)

其基本结构非常简单

image.png

encoding字段支持的整型结构有:

image.png

length与contents分别为存储内容的长度与内容的首地址。

其实本质上来说,就是实现了一个比较小巧的多类型兼容的顺序向量或者说顺序表,当然通俗来说数组也问题不大。这样的结构其实大部分语言原生都没有,你可能会说通过泛型,但是注意,不同的泛型也是无法良好的传参兼容的,这样的多编码支持结构还真得自己去实现。

这部分源码没有太多值得说的地方,其内容也比较简单,毕竟只是一个比较好的多编码顺序表,其相关的基本方法如下:

image.png

你一定好奇为什么这些基本方法的入参都直接是int64_t类型,不是要兼容三种吗?这部分其实是通过简单的判断该value的数据大小范围来判断的,如下:

image.png

那么问题又来了,可以看到一个intset结构的enconding是和自己绑定的,那么向一个encoding为32位的intset表中插入一个超过32位整型大小但在64位之类的value时,会发生什么?或者说intset是怎么处理的?

答案是intset会进行编码提升,向更大的位宽扩充:

image.png

这个函数真的是写的相当好,非常精简的实现了这一逻辑,一般人真想不到这样写!

还值得一提的是,intset同时考虑好了字节序的问题。Redis为了统一存储字节序,将所有的value转换为小端存储。Redis为此自己实现了一个字节序转换工具,位于endianconv.h与endianconv.c,Redis为了压榨性能,对于大端机涉及的网络字节序转换直接什么也不做,小端机才真正调用转换函数。

以上就是intset的全部内容,其他有趣细节就不做多余的展开了,有兴趣的朋友不妨自己去看一看。



发表评论

电子邮件地址不会被公开。 必填项已用*标注