《Redis设计与实现》读书笔记(二)
3.字典
- C语言中没有内置字典,Redis数据库拿字典做为底层实现,须要构建字典结构及其增删查改API。在Redis中,字典的底层是哈希表,dictionary hash table。dictht定义以下。

- 这里的table是一个数组,数组中每一个元素都是指向dictEntry的指针。dictEntry保存着键值对,其定义以下。

- 上边字段中,含义或者做用比较模糊的就是*next指针了。这个字段的做用是解决键冲突的。示例以下。

- 好,铺垫完了,开始进入字典结构。

- 这里的每一个字段都有重要的做用。type和privdata指针支持了字典的多态。实现多态的原理:type为dictType结构的指针,而dictType则是保存了用于处理特定键值对的类型特定函数,privdata保存了须要传给类型特定函数的可选参数。

- ht字段保存了两个哈希表,第一个表是正常使用,第二个则是rehash的时候使用。rehashidx字段也是rehash进度相关,没有进行rehash的时候,值为-1。完整的字典,普通状态下的示意图以下。

-
添加键值对到字典的步骤:算法
- 根据键值对计算哈希值和索引值
- 根据索引值找到哈希表数组(dictEntry[])的指定索引
- 将键值对信息存放在dictEntry里边
- 上边的三个步骤逻辑上存在一个问题——索引冲突!
- 根据哈希算法的不一样,哈希碰撞的几率不一样。键值对A和键值对B被分配到相同的索引,怎么办!
- 链地址法,这也就是dictEntry里边有个next指针的缘由了。后添加的会被添加到表头。示意图以下。

- 至此,字典的功能实现基本完成,可是,工程实现尚未!什么意思?工程的意思是对字典的操做是持续不断的,大量的。这个时候就须要rehash,优化哈希表。好比,dictEntry数组的有些索引没有值,有些存在比较长的链。
- 因此,从工程的角度考虑,rehash这个步骤必不可少。dict结构中有几个字段是用于rehash的。rehash的细节能够看原书或者别的资料。
欢迎关注本站公众号,获取更多信息