Redis源码分析系列二十五: 我如何改造redis的rehash过程

昨晚看了下redis的populateCommandTable.大致原理我是明白的,

不过我觉得代码写的有点绕,有些细节的控制看得会让人晕头转向。

我自己想了下,如果让我根据其原理来自己写的话,我的思路会是如下:

考虑到有两个哈希表ht[0],ht[1],刚开始ht[0]没有成员,ht[1]没有成员。

1)ht[0]为空,申请缓冲区,size=4.同时加入第一个命令。

2)ht[0]还可以放一个,放入第2个命令。

3)ht[0]不满,放入第3个命令。

4)ht[0]不满,放入第4个命令,

此时ht[0].used==ht[0].size.立刻设置ht[0].rehash=0;

表示ht[0]需要rehash了。

5)需要放入第5个命令,由于ht[0].rehash=0.表明ht[0]不可以放入命令了,

那么此时需要放入ht[1]中,此时ht[1]肯定是NULL,为ht[1]申请缓冲区,大小为2*ht[0].size.

对ht[0]执行单步一个桶的rehash到ht[1]中,同时加入第5个命令到ht[1]中。

6)后续加入命令时,每次先对ht[0]执行单步一个桶的rehash到ht[1]中,同时加入当前命令到ht[1]中。

7)对ht[1]执行完 ht[0]的单步rehash和加入新命令到ht[1]中后,一旦发现ht[0].used=0.

立即将ht[1]赋值给ht[0],释放ht[1]的缓冲区,标记ht[0].rehash=-1.

此处后来补充:

同时根据更新后的ht[0]的used和size情况决定ht[0].rehash是否需要再次rehash.


从数学角度来分析,每次rehash结束后,ht[1]赋值给ht[0]后,更新后的ht[0]里最多有多少个节点?

稍微分析一下,就知道此时ht[0].used<=ht[0].size.

什么情况下ht[0]. used=ht[0].size?

就是之前每次rehash, 只从ht[0]取出一个节点出来到ht[1]中,这也意味着老的ht[0]的每个桶里有且只有一个节点。

~~~~~~~~~~~

然后rehash结束后,再加入命令,就跟刚开始加入节点一样了。


通过上面的方法来改造,对细节更容易让人理解,对ht[0],ht[1]的关系看代码更容易清楚,

特别是2个哈希表的节点数量的关系。

反正如果让我写,我就这么写。


说了这么多,为啥要费尽功夫做rehash,还不是为了减少每个桶下面的节点数量,减少查找时间。

典型的以空间换时间的做法。

                                        ---强子哥哥  QQ 837500869

转载于:https://my.oschina.net/qiangzigege/blog/179672

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值