redis set类型数据结构字典之rehash

160 阅读2分钟

小知识,大挑战!本文正在参与「程序员必备小知识」创作活动

6redis set类型数据结构字典之rehash

要将一个新的键值对添加到字典里面时,程序需要先根据键值对的键计算出哈希值和索引值,然后再根据索引值将包含新键值对的哈希表节点放到哈希表数据的指定索引上边

当两个或以上数量的键被分配了哈希表数据的同一个索引上面时,redis的哈希表使用链地址法来解决键冲突,每个哈希表节点都有一个next指针,多个哈希表节点可以用next指针构成一个单向链表,被分配到同一个索引的多个节点用这个单向链表连接起来,解决键冲突的问题。采用头插法

rehash

随着操作的不断执行,哈希表保存的键值对会逐渐增多或减少,为了让哈希表的负载因子维持一个合理范围,当哈希表保存的键值对数量太多或太少时,程序需要对哈希表的大小进行相应的扩展或收缩,这就需要rehash重新散列

rehash步骤:

  1. 为字典的ht[1]哈希表分配空间,这个哈希表的空间大小取决于要执行的操作,以及ht[0]当前包含的键值对数量
    • 如果执行扩展操作,ht[1]的大小为大于等于ht[0].used*2的2的n次方,比如ht[0].used是4,那么h1大小为4*2,8符合4乘以2的2的n次方
    • 如果执行收缩操作,ht[1]的大小为第一个大于等于ht[0].used的2的n次方
  2. 将保存在ht[0]中的所有键值对rehash到ht[1] :rehash就是重新计算键的哈希值和索引值,然后将键值对放置到ht[1]哈希表的指定位置上。
  3. 当ht[0]包含的所有键值对都迁移到ht[1]之后,释放ht[0],将ht[1]设置为ht[0],并在ht[1]新创建一个空白哈希表,为下一次rehash做准备