字典只使用ht[0]哈希表,ht[1]哈希表只会在对ht[0]哈希表进行rehash时使用
键---->哈希值---->索引值
Redis使用MurmurHash算法,优点:即使输入的键有规律,算法仍然能给出一个好的随机分布性,速度块。
解决键冲突:链地址法。每个哈希表节点都有一个next指针,多个哈希表节点可以用next指针构成一个单向链表。程序总是将新节点添加到链表的表头位置O(1)
负载因子--->哈希表的拓展和收缩。
扩展:ht[1]的大小为第一个大于等于ht[0].used*2的2^n
收缩: ht[1]的大小为第一个大于等于ht[0].used的2^n
将ht[0]包含的所有键值对都迁移到ht[1]之后,ht[0]变为空表,释放ht[0],将ht[1]设置为ht[0],并在ht[1]新创建一个空白哈希表,为下一次rehash做准备
没有执行BGSAVE命令或BGREWRITEAOF命令:负载因子大于等于1 扩展与收缩
正在执行BGSAVE命令或BGREWRITEAOF命令:负载因子大于等于5扩展与收缩
rehash:分多次地,渐进式地完成
除了程序每次对字典执行指定操作时,还会顺带将ht[0]哈希表在rehashidx索引上的所有键值对rehash到ht[1]。
参考:《Redis设计与实现》