Redis源码剖析——intset
intset是Redis源码里一个比较基础的组件,和非常多的部分有耦合,因此也就不单独谈其所关联的部分了。总的来说intset实现了这样一个东西:一个多编码的顺序整型数据存储结构。(以下代码位于intset.c与intset.h)
其基本结构非常简单
encoding字段支持的整型结构有:
length与contents分别为存储内容的长度与内容的首地址。
其实本质上来说,就是实现了一个比较小巧的多类型兼容的顺序向量或者说顺序表,当然通俗来说数组也问题不大。这样的结构其实大部分语言原生都没有,你可能会说通过泛型,但是注意,不同的泛型也是无法良好的传参兼容的,这样的多编码支持结构还真得自己去实现。
这部分源码没有太多值得说的地方,其内容也比较简单,毕竟只是一个比较好的多编码顺序表,其相关的基本方法如下:
你一定好奇为什么这些基本方法的入参都直接是int64_t类型,不是要兼容三种吗?这部分其实是通过简单的判断该value的数据大小范围来判断的,如下:
那么问题又来了,可以看到一个intset结构的enconding是和自己绑定的,那么向一个encoding为32位的intset表中插入一个超过32位整型大小但在64位之类的value时,会发生什么?或者说intset是怎么处理的?
答案是intset会进行编码提升,向更大的位宽扩充:
这个函数真的是写的相当好,非常精简的实现了这一逻辑,一般人真想不到这样写!
还值得一提的是,intset同时考虑好了字节序的问题。Redis为了统一存储字节序,将所有的value转换为小端存储。Redis为此自己实现了一个字节序转换工具,位于endianconv.h与endianconv.c,Redis为了压榨性能,对于大端机涉及的网络字节序转换直接什么也不做,小端机才真正调用转换函数。
以上就是intset的全部内容,其他有趣细节就不做多余的展开了,有兴趣的朋友不妨自己去看一看。
完
- 原文作者:Fh
- 原文链接:http://fhstack.github.io/post/2019-06-11-redisyuanmapouxiintset/
- 版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议进行许可,非商业转载请注明出处(作者,原文链接),商业转载请联系作者获得授权。