// File: /workspace/github_c_makefile_star2_O0/nilyang[P]redis-tdd-annotation/src/dict.c
// Function: dictGetRandomKey
dictEntry *dictGetRandomKey(dict *d)
{
    dictEntry *he, *orighe;
    unsigned int h;
    int listlen, listele;

    // 字典为空
    if (dictSize(d) == 0) return NULL;

    // 进行单步 rehash
    if (dictIsRehashing(d)) _dictRehashStep(d);

    // 如果正在 rehash ，那么将 1 号哈希表也作为随机查找的目标
    if (dictIsRehashing(d)) {
        // T = O(N)
        do {
            h = random() % (d->ht[0].size+d->ht[1].size);
            he = (h >= d->ht[0].size) ? d->ht[1].table[h - d->ht[0].size] :
                                      d->ht[0].table[h];
        } while(he == NULL);
    // 否则，只从 0 号哈希表中查找节点
    } else {
        // T = O(N)
        do {
            h = random() & d->ht[0].sizemask;
            he = d->ht[0].table[h];
        } while(he == NULL);
    }

    /* Now we found a non empty bucket, but it is a linked
     * list and we need to get a random element from the list.
     * The only sane way to do so is counting the elements and
     * select a random index. */
    // 目前 he 已经指向一个非空的节点链表
    // 程序将从这个链表随机返回一个节点
    listlen = 0;
    orighe = he;
    // 计算节点数量, T = O(1)
    while(he) {
        he = he->next;
        listlen++;
    }
    // 取模，得出随机节点的索引
    listele = random() % listlen;
    he = orighe;
    // 按索引查找节点
    // T = O(1)
    while(listele--) he = he->next;

    // 返回随机节点
    return he;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x40, %rsp
movq %rdi, -0x10(%rbp)
movq -0x10(%rbp), %rax
movq 0x28(%rax), %rax
movq -0x10(%rbp), %rcx
addq 0x48(%rcx), %rax
cmpq $0x0, %rax
jne 0x2449f
movq $0x0, -0x8(%rbp)
jmp 0x245c7
movq -0x10(%rbp), %rax
cmpl $-0x1, 0x50(%rax)
je 0x244b2
movq -0x10(%rbp), %rdi
callq 0x23870
movq -0x10(%rbp), %rax
cmpl $-0x1, 0x50(%rax)
je 0x2452b
jmp 0x244be
callq 0x1f9d0
movq -0x10(%rbp), %rcx
movq 0x18(%rcx), %rcx
movq -0x10(%rbp), %rdx
addq 0x38(%rdx), %rcx
xorl %edx, %edx
divq %rcx
movl %edx, %eax
movl %eax, -0x24(%rbp)
movl -0x24(%rbp), %eax
movq -0x10(%rbp), %rcx
cmpq 0x18(%rcx), %rax
jb 0x24507
movq -0x10(%rbp), %rax
movq 0x30(%rax), %rax
movl -0x24(%rbp), %ecx
movq -0x10(%rbp), %rdx
subq 0x18(%rdx), %rcx
movq (%rax,%rcx,8), %rax
movq %rax, -0x38(%rbp)
jmp 0x2451a
movq -0x10(%rbp), %rax
movq 0x10(%rax), %rax
movl -0x24(%rbp), %ecx
movq (%rax,%rcx,8), %rax
movq %rax, -0x38(%rbp)
movq -0x38(%rbp), %rax
movq %rax, -0x18(%rbp)
cmpq $0x0, -0x18(%rbp)
je 0x244be
jmp 0x24559
jmp 0x2452d
callq 0x1f9d0
movq -0x10(%rbp), %rcx
andq 0x20(%rcx), %rax
movl %eax, -0x24(%rbp)
movq -0x10(%rbp), %rax
movq 0x10(%rax), %rax
movl -0x24(%rbp), %ecx
movq (%rax,%rcx,8), %rax
movq %rax, -0x18(%rbp)
cmpq $0x0, -0x18(%rbp)
je 0x2452d
jmp 0x24559
movl $0x0, -0x28(%rbp)
movq -0x18(%rbp), %rax
movq %rax, -0x20(%rbp)
cmpq $0x0, -0x18(%rbp)
je 0x24586
movq -0x18(%rbp), %rax
movq 0x10(%rax), %rax
movq %rax, -0x18(%rbp)
movl -0x28(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x28(%rbp)
jmp 0x24568
callq 0x1f9d0
movslq -0x28(%rbp), %rcx
cqto
idivq %rcx
movl %edx, %eax
movl %eax, -0x2c(%rbp)
movq -0x20(%rbp), %rax
movq %rax, -0x18(%rbp)
movl -0x2c(%rbp), %eax
movl %eax, %ecx
addl $-0x1, %ecx
movl %ecx, -0x2c(%rbp)
cmpl $0x0, %eax
je 0x245bf
movq -0x18(%rbp), %rax
movq 0x10(%rax), %rax
movq %rax, -0x18(%rbp)
jmp 0x245a1
movq -0x18(%rbp), %rax
movq %rax, -0x8(%rbp)
movq -0x8(%rbp), %rax
addq $0x40, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)