rehash是为了迁移redis的数据,redis在内存中是类似于java的hashmap形式存储的,相当于一个链表数组,数据是存放在dict里面的,也就是下面rehash的入口参数,dict里面存放两张hash表,rehash就是实现数据在这两张表之间进行迁移的。
rehash的源码在此,入口参数为dict和int
dictIsRehashing返回1代表仍然有key需要从老表迁移到新表,0代表迁移完了。
rehash是以桶(bucket)为单位进行迁移的,n是代表步数,每步完成一个bucket的迁移。一个bucket对应的是hash数组中的一个链表。
/* Performs N steps of incremental rehashing. Returns 1 if there are still
* keys to move from the old to the new hash table, otherwise 0 is returned.
*
* Note that a rehashing step consists in moving a bucket (that may have more
* than one key as we use chaining) from the old to the new hash table, however
* since part of the hash table may be composed of empty spaces, it is not
* guaranteed that this function will rehash even a single bucket, since it
* will visit at max N*10 empty buckets in total, otherwise the amount of
* work it does would be unbound and the function may block for a long time. */
int dictRehash(dict *d, int n) {
int empty_visits = n*10; /* Max number of empty buckets to visit. */
if (!dictIsRehashing(d)) return 0;
// 分n步执行,used参数表示节点数量,如果还没执行完n步且旧表还有数据,就执行循环。
while(n-- && d->ht[0].used != 0) {
dictEntry *de, *nextde;
/* Note that rehashidx can't overflow as we are sur