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的细节可以看原书或者别的资料。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。