// File: /workspace/github_c_makefile_star2_O2/nilyang[P]redis-tdd-annotation/src/dict.c
// Function: dictRehash
int dictRehash(dict *d, int n) {

    // 只可以在 rehash 进行中时执行
    if (!dictIsRehashing(d)) return 0;

    // 进行 N 步迁移
    // T = O(N)
    while(n--) {
        dictEntry *de, *nextde;

        /* Check if we already rehashed the whole table... */
        // 如果 0 号哈希表为空，那么表示 rehash 执行完毕
        // T = O(1)
        if (d->ht[0].used == 0) {
            // 释放 0 号哈希表
            zfree(d->ht[0].table);
            // 将原来的 1 号哈希表设置为新的 0 号哈希表
            d->ht[0] = d->ht[1];
            // 重置旧的 1 号哈希表
            _dictReset(&d->ht[1]);
            // 关闭 rehash 标识
            d->rehashidx = -1;
            // 返回 0 ，向调用者表示 rehash 已经完成
            return 0;
        }

        /* Note that rehashidx can't overflow as we are sure there are more
         * elements because ht[0].used != 0 */
        // 确保 rehashidx 没有越界
        assert(d->ht[0].size > (unsigned)d->rehashidx);

        // 略过数组中为空的索引，找到下一个非空索引
        while(d->ht[0].table[d->rehashidx] == NULL) d->rehashidx++;

        // 指向该索引的链表表头节点
        de = d->ht[0].table[d->rehashidx];
        /* Move all the keys in this bucket from the old to the new hash HT */
        // 将链表中的所有节点迁移到新哈希表
        // T = O(1)
        while(de) {
            unsigned int h;

            // 保存下个节点的指针
            nextde = de->next;

            /* Get the index in the new hash table */
            // 计算新哈希表的哈希值，以及节点插入的索引位置
            h = dictHashKey(d, de->key) & d->ht[1].sizemask;

            // 插入节点到新哈希表
            de->next = d->ht[1].table[h];
            d->ht[1].table[h] = de;

            // 更新计数器
            d->ht[0].used--;
            d->ht[1].used++;

            // 继续处理下个节点
            de = nextde;
        }
        // 将刚迁移完的哈希表索引的指针设为空
        d->ht[0].table[d->rehashidx] = NULL;
        // 更新 rehash 索引
        d->rehashidx++;
    }

    return 1;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
pushq %rax
movl 0x50(%rdi), %eax
xorl %ebx, %ebx
cmpl $-0x1, %eax
je 0x218ad
movl %esi, %ebp
movq %rdi, %r14
leaq 0x10(%rdi), %r12
leaq 0x30(%rdi), %rcx
movq %rcx, (%rsp)
subl $0x1, %ebp
jb 0x2187a
cmpq $0x0, 0x28(%r14)
je 0x2187f
movl %eax, %ecx
cmpq %rcx, 0x18(%r14)
jbe 0x218be
movslq %eax, %rcx
shlq $0x3, %rcx
addq (%r12), %rcx
incl %eax
movq (%rcx), %r13
testq %r13, %r13
jne 0x2185f
movl %eax, 0x50(%r14)
addq $0x8, %rcx
jmp 0x2181f
movq (%r13), %rdi
movq 0x10(%r13), %r15
movq (%r14), %rax
callq *(%rax)
andl 0x40(%r14), %eax
movq 0x30(%r14), %rcx
movq (%rcx,%rax,8), %rdx
movq %rdx, 0x10(%r13)
movq %r13, (%rcx,%rax,8)
decq 0x28(%r14)
incq 0x48(%r14)
movq %r15, %r13
testq %r13, %r13
jne 0x21833
movq 0x10(%r14), %rax
movslq 0x50(%r14), %rcx
andq $0x0, (%rax,%rcx,8)
leal 0x1(%rcx), %eax
movl %eax, 0x50(%r14)
jmp 0x217fc
pushq $0x1
popq %rbx
jmp 0x218ad
movq 0x10(%r14), %rdi
callq 0x283cd
movq (%rsp), %rax
movups (%rax), %xmm0
movups 0x10(%rax), %xmm1
movups %xmm1, 0x10(%r12)
movups %xmm0, (%r12)
xorps %xmm0, %xmm0
movups %xmm0, (%rax)
movups %xmm0, 0x10(%rax)
orl $-0x1, 0x50(%r14)
movl %ebx, %eax
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x6889d(%rip), %rdi     # 0x8a162
leaq 0x74c7f(%rip), %rsi     # 0x9654b
movl $0x17f, %edx            # imm = 0x17F
callq 0x4906b
pushq $0x1
popq %rdi
callq 0x1f3b0