LLM4Binary/decompile-bench-makefile huggingface dataset:
// File: /workspace/github_c_makefile_star2_O3/nilyang[P]redis-tdd-annotation/src/debug.c
// Function: redisAssertPrintClientInfo
void _redisAssertPrintClientInfo(redisClient *c) {
    int j;

    bugReportStart();
    redisLog(REDIS_WARNING,"=== ASSERTION FAILED CLIENT CONTEXT ===");
    redisLog(REDIS_WARNING,"client->flags = %d", c->flags);
    redisLog(REDIS_WARNING,"client->fd = %d", c->fd);
    redisLog(REDIS_WARNING,"client->argc = %d", c->argc);
    for (j=0; j < c->argc; j++) {
        char buf[128];
        char *arg;

        if (c->argv[j]->type == REDIS_STRING && sdsEncodedObject(c->argv[j])) {
            arg = (char*) c->argv[j]->ptr;
        } else {
            snprintf(buf,sizeof(buf),"Object type: %d, encoding: %d",
                c->argv[j]->type, c->argv[j]->encoding);
            arg = buf;
        }
        redisLog(REDIS_WARNING,"client->argv[%d] = \"%s\" (refcount: %d)",
            j, arg, c->argv[j]->refcount);
    }
}

// Assembly:
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x80, %rsp
movq %rdi, %rbx
leaq 0x7cca4(%rip), %r14     # 0xc9fa8
cmpl $0x0, 0x834(%r14)
jne 0x4d32c
leaq 0x4e334(%rip), %rsi     # 0x9b649
movl $0x3, %edi
xorl %eax, %eax
callq 0x23223
movl $0x1, 0x834(%r14)
leaq 0x4e0cf(%rip), %rsi     # 0x9b402
movl $0x3, %edi
xorl %eax, %eax
callq 0x23223
movl 0x90(%rbx), %edx
leaq 0x4e0de(%rip), %rsi     # 0x9b42a
movl $0x3, %edi
xorl %eax, %eax
callq 0x23223
movl (%rbx), %edx
leaq 0x4e0dc(%rip), %rsi     # 0x9b43d
movl $0x3, %edi
xorl %eax, %eax
callq 0x23223
movl 0x30(%rbx), %edx
leaq 0x4e0d6(%rip), %rsi     # 0x9b44d
movl $0x3, %edi
xorl %eax, %eax
callq 0x23223
cmpl $0x0, 0x30(%rbx)
jle 0x4d402
leaq 0x4e0ed(%rip), %r14     # 0x9b47d
leaq 0x4e0c8(%rip), %r15     # 0x9b45f
movq %rsp, %r12
xorl %r13d, %r13d
movq 0x38(%rbx), %rax
movq (%rax,%r13,8), %rax
movl (%rax), %ecx
movl %ecx, %r8d
shrl $0x4, %r8d
andl $0xf, %r8d
andl $0xf, %ecx
je 0x4d3d6
movl $0x80, %esi
movq %r12, %rdi
movq %r15, %rdx
xorl %eax, %eax
callq 0x1f120
movq 0x38(%rbx), %rax
movq (%rax,%r13,8), %rax
movq %r12, %rcx
jmp 0x4d3e0
testb $0x7, %r8b
jne 0x4d3b7
movq 0x8(%rax), %rcx
movl 0x4(%rax), %r8d
movl $0x3, %edi
movq %r14, %rsi
movl %r13d, %edx
xorl %eax, %eax
callq 0x23223
incq %r13
movslq 0x30(%rbx), %rax
cmpq %rax, %r13
jl 0x4d39d
addq $0x80, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
retq
// File: /workspace/github_c_makefile_star2_O3/nilyang[P]redis-tdd-annotation/src/debug.c
// Function: redisLogObjectDebugInfo
void redisLogObjectDebugInfo(robj *o) {
    redisLog(REDIS_WARNING,"Object type: %d", o->type);
    redisLog(REDIS_WARNING,"Object encoding: %d", o->encoding);
    redisLog(REDIS_WARNING,"Object refcount: %d", o->refcount);
    if (o->type == REDIS_STRING && sdsEncodedObject(o)) {
        redisLog(REDIS_WARNING,"Object raw string len: %zu", sdslen(o->ptr));
        if (sdslen(o->ptr) < 4096) {
            sds repr = sdscatrepr(sdsempty(),o->ptr,sdslen(o->ptr));
            redisLog(REDIS_WARNING,"Object raw string content: %s", repr);
            sdsfree(repr);
        }
    } else if (o->type == REDIS_LIST) {
        redisLog(REDIS_WARNING,"List length: %d", (int) listTypeLength(o));
    } else if (o->type == REDIS_SET) {
        redisLog(REDIS_WARNING,"Set size: %d", (int) setTypeSize(o));
    } else if (o->type == REDIS_HASH) {
        redisLog(REDIS_WARNING,"Hash size: %d", (int) hashTypeLength(o));
    } else if (o->type == REDIS_ZSET) {
        redisLog(REDIS_WARNING,"Sorted set size: %d", (int) zsetLength(o));
        if (o->encoding == REDIS_ENCODING_SKIPLIST)
            redisLog(REDIS_WARNING,"Skiplist level: %d", (int) ((zset*)o->ptr)->zsl->level);
    }
}

// Assembly:
pushq %rbx
movq %rdi, %rbx
movl (%rdi), %edx
andl $0xf, %edx
leaq 0x4e081(%rip), %rsi     # 0x9b4a4
movl $0x3, %edi
xorl %eax, %eax
callq 0x23223
movl (%rbx), %edx
shrl $0x4, %edx
andl $0xf, %edx
leaq 0x4e076(%rip), %rsi     # 0x9b4b4
movl $0x3, %edi
xorl %eax, %eax
callq 0x23223
movl 0x4(%rbx), %edx
leaq 0x4e074(%rip), %rsi     # 0x9b4c8
movl $0x3, %edi
xorl %eax, %eax
callq 0x23223
movl (%rbx), %eax
movl %eax, %ecx
andl $0xf, %ecx
cmpl $0x4, %ecx
ja 0x4d552
leaq 0x4dcd5(%rip), %rdx     # 0x9b14c
movslq (%rdx,%rcx,4), %rcx
addq %rdx, %rcx
jmpq *%rcx
shrl $0x4, %eax
testb $0x7, %al
jne 0x4d552
movq 0x8(%rbx), %rax
movslq -0x8(%rax), %rdx
leaq 0x4e042(%rip), %rsi     # 0x9b4dc
movl $0x3, %edi
xorl %eax, %eax
callq 0x23223
movq 0x8(%rbx), %rax
cmpl $0xfff, -0x8(%rax)      # imm = 0xFFF
ja 0x4d552
callq 0x2845e
movq 0x8(%rbx), %rsi
movslq -0x8(%rsi), %rdx
movq %rax, %rdi
callq 0x29259
movq %rax, %rbx
leaq 0x4e021(%rip), %rsi     # 0x9b4f7
movl $0x3, %edi
movq %rax, %rdx
xorl %eax, %eax
callq 0x23223
movq %rbx, %rdi
popq %rbx
jmp 0x2850d
movq %rbx, %rdi
callq 0x4261c
leaq 0x4e035(%rip), %rsi     # 0x9b532
jmp 0x4d563
movq %rbx, %rdi
callq 0x3bbf6
leaq 0x4e017(%rip), %rsi     # 0x9b525
jmp 0x4d563
movq %rbx, %rdi
callq 0x3eadd
leaq 0x4e021(%rip), %rsi     # 0x9b540
movl $0x3, %edi
movl %eax, %edx
xorl %eax, %eax
callq 0x23223
movl $0xf0, %eax
andl (%rbx), %eax
cmpl $0x70, %eax
jne 0x4d552
movq 0x8(%rbx), %rax
movq 0x8(%rax), %rax
movl 0x18(%rax), %edx
leaq 0x4e009(%rip), %rsi     # 0x9b554
movl $0x3, %edi
jmp 0x4d56a
popq %rbx
retq
movq %rbx, %rdi
callq 0x39979
leaq 0x4dfb2(%rip), %rsi     # 0x9b515
movl $0x3, %edi
movl %eax, %edx
xorl %eax, %eax
popq %rbx
jmp 0x23223
// File: /workspace/github_c_makefile_star2_O3/nilyang[P]redis-tdd-annotation/src/debug.c
// Function: logStackContent
void logStackContent(void **sp) {
    int i;
    for (i = 15; i >= 0; i--) {
        unsigned long addr = (unsigned long) sp+i;
        unsigned long val = (unsigned long) sp[i];

        if (sizeof(long) == 4)
            redisLog(REDIS_WARNING, "(%08lx) -> %08lx", addr, val);
        else
            redisLog(REDIS_WARNING, "(%016lx) -> %016lx", addr, val);
    }
}

// Assembly:
pushq %r15
pushq %r14
pushq %rbx
movq %rdi, %rbx
movl $0xf, %r15d
leaq 0x4e0ab(%rip), %r14     # 0x9b68a
leaq (%rbx,%r15), %rdx
movq (%rbx,%r15,8), %rcx
movl $0x3, %edi
movq %r14, %rsi
xorl %eax, %eax
callq 0x23223
addq $-0x1, %r15
jb 0x4d5df
popq %rbx
popq %r14
popq %r15
retq
// File: /workspace/github_c_makefile_star2_O3/nilyang[P]redis-tdd-annotation/src/debug.c
// Function: logCurrentClient
void logCurrentClient(void) {
    if (server.current_client == NULL) return;

    redisClient *cc = server.current_client;
    sds client;
    int j;

    redisLog(REDIS_WARNING, "--- CURRENT CLIENT INFO");
    client = catClientInfoString(sdsempty(),cc);
    redisLog(REDIS_WARNING,"client: %s", client);
    sdsfree(client);
    for (j = 0; j < cc->argc; j++) {
        robj *decoded;

        decoded = getDecodedObject(cc->argv[j]);
        redisLog(REDIS_WARNING,"argv[%d]: '%s'", j, (char*)decoded->ptr);
        decrRefCount(decoded);
    }
    /* Check if the first argument, usually a key, is found inside the
     * selected DB, and if so print info about the associated object. */
    if (cc->argc >= 1) {
        robj *val, *key;
        dictEntry *de;

        key = getDecodedObject(cc->argv[1]);
        de = dictFind(cc->db->dict, key->ptr);
        if (de) {
            val = dictGetVal(de);
            redisLog(REDIS_WARNING,"key '%s' found in DB containing the following object:", (char*)key->ptr);
            redisLogObjectDebugInfo(val);
        }
        decrRefCount(key);
    }
}

// Assembly:
pushq %r15
pushq %r14
pushq %r12
pushq %rbx
pushq %rax
leaq 0x7c7c0(%rip), %rax     # 0xc9fa8
movq 0x1d0(%rax), %rbx
testq %rbx, %rbx
je 0x4d8e9
leaq 0x4df81(%rip), %rsi     # 0x9b780
movl $0x3, %edi
xorl %eax, %eax
callq 0x23223
callq 0x2845e
movq %rax, %rdi
movq %rbx, %rsi
callq 0x2f0da
movq %rax, %r14
leaq 0x497f4(%rip), %rsi     # 0x97019
movl $0x3, %edi
movq %rax, %rdx
xorl %eax, %eax
callq 0x23223
movq %r14, %rdi
callq 0x2850d
cmpl $0x0, 0x30(%rbx)
jle 0x4d8e9
leaq 0x4df4b(%rip), %r14     # 0x9b798
xorl %r15d, %r15d
movq 0x38(%rbx), %rax
movq (%rax,%r15,8), %rdi
callq 0x30d93
movq %rax, %r12
movq 0x8(%rax), %rcx
movl $0x3, %edi
movq %r14, %rsi
movl %r15d, %edx
xorl %eax, %eax
callq 0x23223
movq %r12, %rdi
callq 0x30b0c
incq %r15
movslq 0x30(%rbx), %rax
cmpq %rax, %r15
jl 0x4d850
testl %eax, %eax
jle 0x4d8e9
movq 0x38(%rbx), %rax
movq 0x8(%rax), %rdi
callq 0x30d93
movq %rax, %r14
movq 0x8(%rbx), %rax
movq (%rax), %rdi
movq 0x8(%r14), %rsi
callq 0x226ac
testq %rax, %rax
je 0x4d8d6
movq 0x8(%rax), %rbx
movq 0x8(%r14), %rdx
leaq 0x4dee5(%rip), %rsi     # 0x9b7a7
movl $0x3, %edi
xorl %eax, %eax
callq 0x23223
movq %rbx, %rdi
callq 0x4d413
movq %r14, %rdi
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
jmp 0x30b0c
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
retq
// File: /workspace/github_c_makefile_star2_O3/nilyang[P]redis-tdd-annotation/src/debug.c
// Function: redisLogHexDump
void redisLogHexDump(int level, char *descr, void *value, size_t len) {
    char buf[65], *b;
    unsigned char *v = value;
    char charset[] = "0123456789abcdef";

    redisLog(level,"%s (hexdump):", descr);
    b = buf;
    while(len) {
        b[0] = charset[(*v)>>4];
        b[1] = charset[(*v)&0xf];
        b[2] = '\0';
        b += 2;
        len--;
        v++;
        if (b-buf == 64 || len == 0) {
            redisLogRaw(level|REDIS_LOG_RAW,buf);
            b = buf;
        }
    }
    redisLogRaw(level|REDIS_LOG_RAW,"\n");
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x58, %rsp
movq %rcx, %r14
movq %rdx, %r15
movq %rsi, %rdx
movl %edi, %ebx
leaq 0x4dc5e(%rip), %rsi     # 0x9ba6b
xorl %eax, %eax
callq 0x23223
orl $0x400, %ebx            # imm = 0x400
testq %r14, %r14
je 0x4dea3
movl %ebx, 0x4(%rsp)
leaq -0x1(%r14), %r13
leaq 0x10(%rsp), %r12
xorl %ebp, %ebp
leaq 0x4dc77(%rip), %rbx     # 0x9bab0
movq %r12, %rcx
negq %rcx
movq %rcx, 0x8(%rsp)
movzbl (%r15,%rbp), %ecx
shrl $0x4, %ecx
movb (%rcx,%rbx), %cl
movb %cl, (%r12)
movzbl (%r15,%rbp), %ecx
andl $0xf, %ecx
movb (%rcx,%rbx), %cl
movb %cl, 0x1(%r12)
movb $0x0, 0x2(%r12)
cmpq %rbp, %r13
je 0x4de86
movq 0x8(%rsp), %rcx
addq %r12, %rcx
addq $0x2, %rcx
cmpq $0x40, %rcx
je 0x4de86
addq $0x2, %r12
jmp 0x4de97
movl 0x4(%rsp), %edi
leaq 0x10(%rsp), %r12
movq %r12, %rsi
callq 0x230d4
incq %rbp
cmpq %rbp, %r14
jne 0x4de44
movl 0x4(%rsp), %ebx
leaq 0x488e7(%rip), %rsi     # 0x96791
movl %ebx, %edi
callq 0x230d4
addq $0x58, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
// File: /workspace/github_c_makefile_star2_O3/nilyang[P]redis-tdd-annotation/src/intset.c
// Function: intsetSearch
static uint8_t intsetSearch(intset *is, int64_t value, uint32_t *pos) {
    int min = 0, max = intrev32ifbe(is->length)-1, mid = -1;
    int64_t cur = -1;

    /* The value can never be found when the set is empty */
    // 处理 is 为空时的情况
    if (intrev32ifbe(is->length) == 0) {
        if (pos) *pos = 0;
        return 0;
    } else {
        /* Check for the case where we know we cannot find the value,
         * but do know the insert position. */
        // 因为底层数组是有序的，如果 value 比数组中最后一个值都要大
        // 那么 value 肯定不存在于集合中，
        // 并且应该将 value 添加到底层数组的最末端
        if (value > _intsetGet(is,intrev32ifbe(is->length)-1)) {
            if (pos) *pos = intrev32ifbe(is->length);
            return 0;
        // 因为底层数组是有序的，如果 value 比数组中最前一个值都要小
        // 那么 value 肯定不存在于集合中，
        // 并且应该将它添加到底层数组的最前端
        } else if (value < _intsetGet(is,0)) {
            if (pos) *pos = 0;
            return 0;
        }
    }

    // 在有序数组中进行二分查找
    // T = O(log N)
    while(max >= min) {
        mid = (min+max)/2;
        cur = _intsetGet(is,mid);
        if (value > cur) {
            min = mid+1;
        } else if (value < cur) {
            max = mid-1;
        } else {
            break;
        }
    }

    // 检查是否已经找到了 value
    if (value == cur) {
        if (pos) *pos = mid;
        return 1;
    } else {
        if (pos) *pos = min;
        return 0;
    }
}

// Assembly:
movl 0x4(%rdi), %ecx
movl %ecx, %eax
subl $0x1, %eax
jae 0x4f275
xorl %ecx, %ecx
movl $0x0, %eax
jmp 0x4f32b
movzbl (%rdi), %r8d
movslq %eax, %r9
cmpl $0x4, %r8d
je 0x4f28f
cmpl $0x8, %r8d
jne 0x4f296
movq 0x8(%rdi,%r9,8), %r9
jmp 0x4f29c
movslq 0x8(%rdi,%r9,4), %r9
jmp 0x4f29c
movswq 0x8(%rdi,%r9,2), %r9
cmpq %rsi, %r9
jge 0x4f2a8
xorl %eax, %eax
jmp 0x4f32b
movzbl %r8b, %r9d
cmpb $0x4, %r9b
je 0x4f2be
cmpl $0x8, %r9d
jne 0x4f2c4
movq 0x8(%rdi), %rcx
jmp 0x4f2c9
movslq 0x8(%rdi), %rcx
jmp 0x4f2c9
movswq 0x8(%rdi), %rcx
cmpq %rsi, %rcx
jg 0x4f269
testl %eax, %eax
js 0x4f312
xorl %ecx, %ecx
leal (%rax,%rcx), %r10d
shrl %r10d
cmpb $0x4, %r8b
je 0x4f2ee
cmpl $0x8, %r9d
jne 0x4f2f5
movq 0x8(%rdi,%r10,8), %r11
jmp 0x4f2fb
movslq 0x8(%rdi,%r10,4), %r11
jmp 0x4f2fb
movswq 0x8(%rdi,%r10,2), %r11
cmpq %rsi, %r11
jge 0x4f306
leal 0x1(%r10), %ecx
jmp 0x4f30c
jle 0x4f321
leal -0x1(%r10), %eax
cmpl %ecx, %eax
jge 0x4f2d4
jmp 0x4f321
movq $-0x1, %r11
movl $0xffffffff, %r10d      # imm = 0xFFFFFFFF
xorl %ecx, %ecx
cmpq %rsi, %r11
sete %al
cmovel %r10d, %ecx
testq %rdx, %rdx
je 0x4f332
movl %ecx, (%rdx)
retq
// File: /workspace/github_c_makefile_star2_O3/nilyang[P]redis-tdd-annotation/src/intset.c
// Function: intsetRemove
intset *intsetRemove(intset *is, int64_t value, int *success) {

    // 计算 value 的编码方式
    uint8_t valenc = _intsetValueEncoding(value);
    uint32_t pos;

    // 默认设置标识值为删除失败
    if (success) *success = 0;

    // 当 value 的编码大小小于或等于集合的当前编码方式（说明 value 有可能存在于集合）
    // 并且 intsetSearch 的结果为真，那么执行删除
    // T = O(log N)
    if (valenc <= intrev32ifbe(is->encoding) && intsetSearch(is,value,&pos)) {

        // 取出集合当前的元素数量
        uint32_t len = intrev32ifbe(is->length);

        /* We know we can delete */
        // 设置标识值为删除成功
        if (success) *success = 1;

        /* Overwrite value with tail and update length */
        // 如果 value 不是位于数组的末尾
        // 那么需要对原本位于 value 之后的元素进行移动
        //
        // 举个例子，如果数组表示如下，而 b 为删除的目标
        // | a | b | c | d |
        // 那么 intsetMoveTail 将 b 之后的所有数据向前移动一个元素的空间，
        // 覆盖 b 原来的数据
        // | a | c | d | d |
        // 之后 intsetResize 缩小内存大小时，
        // 数组末尾多出来的一个元素的空间将被移除
        // | a | c | d |
        if (pos < (len-1)) intsetMoveTail(is,pos+1,pos);
        // 缩小数组的大小，移除被删除元素占用的空间
        // T = O(N)
        is = intsetResize(is,len-1);
        // 更新集合的元素数量
        is->length = intrev32ifbe(len-1);
    }

    return is;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %rbx
pushq %rax
movq %rdx, %r15
movq %rdi, %rbx
leaq -0x80000000(%rsi), %rax
movswq %si, %rcx
xorl %edx, %edx
cmpq %rsi, %rcx
setne %dl
leal 0x2(,%rdx,2), %ecx
testq %r15, %r15
je 0x4f366
movl $0x0, (%r15)
movabsq $-0x100000000, %rdx     # imm = 0xFFFFFFFF00000000
cmpq %rdx, %rax
movl $0x8, %eax
cmovbl %eax, %ecx
movl (%rbx), %r14d
cmpl %ecx, %r14d
jb 0x4f41f
leaq 0x4(%rsp), %rdx
movq %rbx, %rdi
callq 0x4f25f
testb %al, %al
je 0x4f41f
movl 0x4(%rbx), %ebp
testq %r15, %r15
je 0x4f3ae
movl $0x1, (%r15)
movl (%rbx), %r14d
movl 0x4(%rsp), %ecx
decl %ebp
cmpl %ebp, %ecx
jae 0x4f406
leaq 0x1(%rcx), %rax
movl 0x4(%rbx), %edx
leaq 0x8(%rbx), %rdi
cmpl $0x4, %r14d
je 0x4f3de
cmpl $0x8, %r14d
jne 0x4f3ed
leaq (%rdi,%rax,8), %rsi
leaq (%rdi,%rcx,8), %rdi
movl $0x3, %ecx
jmp 0x4f3fa
leaq (%rdi,%rax,4), %rsi
leaq (%rdi,%rcx,4), %rdi
movl $0x2, %ecx
jmp 0x4f3fa
leaq (%rdi,%rax,2), %rsi
leaq (%rdi,%rcx,2), %rdi
movl $0x1, %ecx
subl %eax, %edx
shll %cl, %edx
callq 0x1f780
movl (%rbx), %r14d
imull %ebp, %r14d
addq $0x8, %r14
movq %rbx, %rdi
movq %r14, %rsi
callq 0x29a61
movq %rax, %rbx
movl %ebp, 0x4(%rax)
movq %rbx, %rax
addq $0x8, %rsp
popq %rbx
popq %r14
popq %r15
popq %rbp
retq
// File: /workspace/github_c_makefile_star2_O3/nilyang[P]redis-tdd-annotation/src/intset.c
// Function: intsetRandom
int64_t intsetRandom(intset *is) {
    // intrev32ifbe(is->length) 取出集合的元素数量
    // 而 rand() % intrev32ifbe(is->length) 根据元素数量计算一个随机索引
    // 然后 _intsetGet 负责根据随机索引来查找值
    return _intsetGet(is,rand()%intrev32ifbe(is->length));
}

// Assembly:
pushq %rbx
movq %rdi, %rbx
callq 0x1faf0
xorl %edx, %edx
divl 0x4(%rbx)
movzbl (%rbx), %ecx
movslq %edx, %rax
cmpl $0x4, %ecx
je 0x4f47e
cmpl $0x8, %ecx
jne 0x4f485
movq 0x8(%rbx,%rax,8), %rax
jmp 0x4f48b
movslq 0x8(%rbx,%rax,4), %rax
jmp 0x4f48b
movswq 0x8(%rbx,%rax,2), %rax
popq %rbx
retq
// File: /workspace/github_c_makefile_star2_O3/nilyang[P]redis-tdd-annotation/src/intset.c
// Function: intsetGet
uint8_t intsetGet(intset *is, uint32_t pos, int64_t *value) {

    // pos < intrev32ifbe(is->length) 
    // 检查 pos 是否符合数组的范围
    if (pos < intrev32ifbe(is->length)) {

        // 保存值到指针
        *value = _intsetGet(is,pos);

        // 返回成功指示值
        return 1;
    }

    // 超出索引范围
    return 0;
}

// Assembly:
cmpl %esi, 0x4(%rdi)
jbe 0x4f4a9
movzbl (%rdi), %ecx
movslq %esi, %rax
cmpl $0x4, %ecx
je 0x4f4ac
cmpl $0x8, %ecx
jne 0x4f4b3
movq 0x8(%rdi,%rax,8), %rax
jmp 0x4f4b9
xorl %eax, %eax
retq
movslq 0x8(%rdi,%rax,4), %rax
jmp 0x4f4b9
movswq 0x8(%rdi,%rax,2), %rax
movq %rax, (%rdx)
movb $0x1, %al
retq
// File: /workspace/github_c_makefile_star2_O3/nilyang[P]redis-tdd-annotation/src/cluster.c
// Function: clusterLookupNode
clusterNode *clusterLookupNode(char *name) {
    sds s = sdsnewlen(name, REDIS_CLUSTER_NAMELEN);
    dictEntry *de;

    de = dictFind(server.cluster->nodes,s);
    sdsfree(s);
    if (de == NULL) return NULL;
    return dictGetVal(de);
}

// Assembly:
pushq %r14
pushq %rbx
pushq %rax
movl $0x28, %esi
callq 0x283f4
movq %rax, %r14
leaq 0x7a1b4(%rip), %rax     # 0xc9fa8
movq 0x7d0(%rax), %rax
movq 0x18(%rax), %rdi
movq %r14, %rsi
callq 0x226ac
movq %rax, %rbx
movq %r14, %rdi
callq 0x2850d
testq %rbx, %rbx
je 0x4fe1d
movq 0x8(%rbx), %rax
jmp 0x4fe1f
xorl %eax, %eax
addq $0x8, %rsp
popq %rbx
popq %r14
retq
// File: /workspace/github_c_makefile_star2_O3/nilyang[P]redis-tdd-annotation/src/cluster.c
// Function: createClusterNode
clusterNode *createClusterNode(char *nodename, int flags) {
    clusterNode *node = zmalloc(sizeof(*node));

    // 设置名字
    if (nodename)
        memcpy(node->name, nodename, REDIS_CLUSTER_NAMELEN);
    else
        getRandomHexChars(node->name, REDIS_CLUSTER_NAMELEN);

    // 初始化属性
    node->ctime = mstime();
    node->configEpoch = 0;
    node->flags = flags;
    memset(node->slots,0,sizeof(node->slots));
    node->numslots = 0;
    node->numslaves = 0;
    node->slaves = NULL;
    node->slaveof = NULL;
    node->ping_sent = node->pong_received = 0;
    node->fail_time = 0;
    node->link = NULL;
    memset(node->ip,0,sizeof(node->ip));
    node->port = 0;
    node->fail_reports = listCreate();
    node->voted_time = 0;
    node->repl_offset_time = 0;
    node->repl_offset = 0;
    listSetFreeMethod(node->fail_reports,zfree);

    return node;
}

// Assembly:
pushq %rbp
pushq %r14
pushq %rbx
movl %esi, %ebp
movq %rdi, %r14
movl $0x8d0, %edi            # imm = 0x8D0
callq 0x299b5
movq %rax, %rbx
leaq 0x8(%rax), %rdi
testq %r14, %r14
je 0x4fe60
movq 0x20(%r14), %rax
movq %rax, 0x20(%rdi)
movups (%r14), %xmm0
movups 0x10(%r14), %xmm1
movups %xmm1, 0x10(%rdi)
movups %xmm0, (%rdi)
jmp 0x4fe6a
movl $0x28, %esi
callq 0x3036a
callq 0x23461
movq %rax, (%rbx)
xorl %r14d, %r14d
movq %r14, 0x38(%rbx)
movl %ebp, 0x30(%rbx)
movq %rbx, %rdi
addq $0x40, %rdi
movq %r14, 0x8c0(%rbx)
xorps %xmm0, %xmm0
movups %xmm0, 0x888(%rbx)
movups %xmm0, 0x898(%rbx)
movups %xmm0, 0x8a6(%rbx)
movl $0x0, 0x8b8(%rbx)
movl $0x830, %edx            # imm = 0x830
xorl %esi, %esi
callq 0x1f110
callq 0x203fc
movq %rax, 0x8c8(%rbx)
xorps %xmm0, %xmm0
movups %xmm0, 0x870(%rbx)
movq %r14, 0x880(%rbx)
leaq -0x263e5(%rip), %rcx    # 0x29af7
movq %rcx, 0x18(%rax)
movq %rbx, %rax
popq %rbx
popq %r14
popq %rbp
retq
// File: /workspace/github_c_makefile_star2_O3/nilyang[P]redis-tdd-annotation/src/cluster.c
// Function: clusterAddNode
int clusterAddNode(clusterNode *node) {
    int retval;
    // 将 node 添加到当前节点的 nodes 表中
    // 这样接下来当前节点就会创建连向 node 的节点
    retval = dictAdd(server.cluster->nodes,
            sdsnewlen(node->name,REDIS_CLUSTER_NAMELEN), node);
    return (retval == DICT_OK) ? REDIS_OK : REDIS_ERR;
}

// Assembly:
pushq %r14
pushq %rbx
pushq %rax
movq %rdi, %rbx
leaq 0x7a0b2(%rip), %rax     # 0xc9fa8
movq 0x7d0(%rax), %rax
movq 0x18(%rax), %r14
addq $0x8, %rdi
movl $0x28, %esi
callq 0x283f4
movq %r14, %rdi
movq %rax, %rsi
movq %rbx, %rdx
callq 0x2249c
xorl %ecx, %ecx
negl %eax
sbbl %ecx, %ecx
movl %ecx, %eax
addq $0x8, %rsp
popq %rbx
popq %r14
retq
// File: /workspace/github_c_makefile_star2_O3/nilyang[P]redis-tdd-annotation/src/cluster.c
// Function: clusterNodeAddSlave
int clusterNodeAddSlave(clusterNode *master, clusterNode *slave) {
    int j;

    /* If it's already a slave, don't add it again. */
    // 如果 slave 已经存在，那么不做操作
    for (j = 0; j < master->numslaves; j++)
        if (master->slaves[j] == slave) return REDIS_ERR;

    // 将 slave 添加到 slaves 数组里面
    master->slaves = zrealloc(master->slaves,
        sizeof(clusterNode*)*(master->numslaves+1));
    master->slaves[master->numslaves] = slave;
    master->numslaves++;

    return REDIS_OK;
}

// Assembly:
pushq %r14
pushq %rbx
pushq %rax
movq %rsi, %r14
movq %rdi, %rbx
movslq 0x844(%rdi), %rax
movq 0x848(%rdi), %rdi
testq %rax, %rax
jle 0x4ff5a
xorl %ecx, %ecx
cmpq %r14, (%rdi,%rcx,8)
je 0x4ff86
incq %rcx
cmpq %rcx, %rax
jne 0x4ff4c
leaq 0x8(,%rax,8), %rsi
callq 0x29a61
movq %rax, 0x848(%rbx)
movslq 0x844(%rbx), %rcx
movq %r14, (%rax,%rcx,8)
leal 0x1(%rcx), %eax
movl %eax, 0x844(%rbx)
xorl %eax, %eax
jmp 0x4ff8b
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
addq $0x8, %rsp
popq %rbx
popq %r14
retq
// File: /workspace/github_c_makefile_star2_O3/nilyang[P]redis-tdd-annotation/src/cluster.c
// Function: clusterAddSlot
int clusterAddSlot(clusterNode *n, int slot) {

    // 槽 slot 已经是节点 n 处理的了
    if (server.cluster->slots[slot]) return REDIS_ERR;

    // 设置 bitmap
    clusterNodeSetSlotBit(n,slot);

    // 更新集群状态
    server.cluster->slots[slot] = n;

    return REDIS_OK;
}

// Assembly:
leaq 0x7a00e(%rip), %rcx     # 0xc9fa8
movq 0x7d0(%rcx), %r8
movslq %esi, %rdx
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
cmpq $0x0, 0x40028(%r8,%rdx,8)
je 0x4ffb5
retq
leal 0x7(%rsi), %eax
testl %esi, %esi
cmovnsl %esi, %eax
sarl $0x3, %eax
cltq
movzbl 0x40(%rdi,%rax), %r8d
movl %esi, %r9d
andb $0x7, %r9b
movl %r8d, %r10d
btsl %r9d, %r10d
movb %r10b, 0x40(%rdi,%rax)
andl $0x7, %esi
btl %esi, %r8d
jb 0x4ffea
incl 0x840(%rdi)
movq 0x7d0(%rcx), %rax
movq %rdi, 0x40028(%rax,%rdx,8)
xorl %eax, %eax
retq
// File: /workspace/github_c_makefile_star2_O3/nilyang[P]redis-tdd-annotation/src/cluster.c
// Function: clusterLockConfig
int clusterLockConfig(char *filename) {
    /* To lock it, we need to open the file in a way it is created if
     * it does not exist, otherwise there is a race condition with other
     * processes. */
    int fd = open(filename,O_WRONLY|O_CREAT,0644);
    if (fd == -1) {
        redisLog(REDIS_WARNING,
            "Can't open %s in order to acquire a lock: %s",
            filename, strerror(errno));
        return REDIS_ERR;
    }

    if (flock(fd,LOCK_EX|LOCK_NB) == -1) {
        if (errno == EWOULDBLOCK) {
            redisLog(REDIS_WARNING,
                 "Sorry, the cluster configuration file %s is already used "
                 "by a different Redis Cluster node. Please make sure that "
                 "different nodes use different cluster configuration "
                 "files.", filename);
        } else {
            redisLog(REDIS_WARNING,
                "Impossible to lock %s: %s", filename, strerror(errno));
        }
        close(fd);
        return REDIS_ERR;
    }
    /* Lock acquired: leak the 'fd' by not closing it, so that we'll retain the
     * lock to the file as long as the process exists. */
    return REDIS_OK;
}

// Assembly:
pushq %rbp
pushq %r14
pushq %rbx
movq %rdi, %rbx
xorl %r14d, %r14d
movl $0x41, %esi
movl $0x1a4, %edx            # imm = 0x1A4
xorl %eax, %eax
callq 0x1f640
cmpl $-0x1, %eax
je 0x5024f
movl %eax, %ebp
movl %eax, %edi
movl $0x6, %esi
callq 0x1f610
cmpl $-0x1, %eax
jne 0x502a1
callq 0x1f810
movl (%rax), %edi
cmpl $0xb, %edi
jne 0x50276
leaq 0x4bbd2(%rip), %rsi     # 0x9be10
movl $0x3, %edi
movq %rbx, %rdx
xorl %eax, %eax
callq 0x23223
jmp 0x50294
callq 0x1f810
movl (%rax), %edi
callq 0x1f630
leaq 0x4bb81(%rip), %rsi     # 0x9bde3
movl $0x3, %edi
movq %rbx, %rdx
movq %rax, %rcx
xorl %eax, %eax
callq 0x23223
jmp 0x5029b
callq 0x1f630
leaq 0x4bc3b(%rip), %rsi     # 0x9bebd
movl $0x3, %edi
movq %rbx, %rdx
movq %rax, %rcx
xorl %eax, %eax
callq 0x23223
movl %ebp, %edi
callq 0x1f170
movl $0xffffffff, %r14d      # imm = 0xFFFFFFFF
movl %r14d, %eax
popq %rbx
popq %r14
popq %rbp
retq
// File: /workspace/github_c_makefile_star2_O3/nilyang[P]redis-tdd-annotation/src/cluster.c
// Function: clusterAcceptHandler
void clusterAcceptHandler(aeEventLoop *el, int fd, void *privdata, int mask) {
    int cport, cfd;
    int max = MAX_CLUSTER_ACCEPTS_PER_CALL;
    char cip[REDIS_IP_STR_LEN];
    clusterLink *link;
    REDIS_NOTUSED(el);
    REDIS_NOTUSED(mask);
    REDIS_NOTUSED(privdata);

    /* If the server is starting up, don't accept cluster connections:
     * UPDATE messages may interact with the database content. */
    if (server.masterhost == NULL && server.loading) return;

    while(max--) {
        cfd = anetTcpAccept(server.neterr, fd, cip, sizeof(cip), &cport);
        if (cfd == ANET_ERR) {
            if (errno != EWOULDBLOCK)
                redisLog(REDIS_VERBOSE,
                    "Accepting cluster node: %s", server.neterr);
            return;
        }
        anetNonBlock(NULL,cfd);
        anetEnableTcpNoDelay(NULL,cfd);

        /* Use non-blocking I/O for cluster messages. */
        redisLog(REDIS_VERBOSE,"Accepted cluster node %s:%d", cip, cport);
        /* Create a link object we use to handle the connection.
         * It gets passed to the readable handler when data is available.
         * Initiallly the link->node pointer is set to NULL as we don't know
         * which node is, but the right node is references once we know the
         * node identity. */
        link = createClusterLink(NULL);
        link->fd = cfd;
        aeCreateFileEvent(server.el,cfd,AE_READABLE,clusterReadHandler,link);
    }
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x48, %rsp
movl %esi, %ebx
leaq 0x79a6a(%rip), %r12     # 0xc9fa8
cmpq $0x0, 0x650(%r12)
jne 0x50558
cmpl $0x0, 0x2f0(%r12)
jne 0x50611
movl $0xfffffc18, %ebp       # imm = 0xFFFFFC18
movl $0x1e8, %r14d           # imm = 0x1E8
addq 0x75a4e(%rip), %r14     # 0xc5fb8
leaq 0x10(%rsp), %r15
movl $0x2e, %ecx
movq %r14, %rdi
movl %ebx, %esi
movq %r15, %rdx
leaq 0xc(%rsp), %r8
callq 0x21dea
cmpl $-0x1, %eax
je 0x505e8
movl %eax, %r13d
xorl %edi, %edi
movl %eax, %esi
callq 0x21374
xorl %edi, %edi
movl %r13d, %esi
callq 0x2159f
movl 0xc(%rsp), %ecx
movl $0x1, %edi
leaq 0x4ba43(%rip), %rsi     # 0x9bff4
movq %r15, %rdx
xorl %eax, %eax
callq 0x23223
xorl %edi, %edi
callq 0x50a17
movl %r13d, 0x8(%rax)
movq 0x28(%r12), %rdi
movl %r13d, %esi
movl $0x1, %edx
leaq 0x4f4(%rip), %rcx       # 0x50ace
movq %rax, %r8
callq 0x20c22
incl %ebp
jne 0x5056f
jmp 0x50611
callq 0x1f810
cmpl $0xb, (%rax)
je 0x50611
movl $0x1e8, %edx            # imm = 0x1E8
addq 0x759ba(%rip), %rdx     # 0xc5fb8
leaq 0x4b9d4(%rip), %rsi     # 0x9bfd9
movl $0x1, %edi
xorl %eax, %eax
callq 0x23223
addq $0x48, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
// File: /workspace/github_c_makefile_star2_O3/nilyang[P]redis-tdd-annotation/src/cluster.c
// Function: clusterSetNodeAsMaster
void clusterSetNodeAsMaster(clusterNode *n) {

    // 已经是主节点了。
    if (nodeIsMaster(n)) return;

    // 移除 slaveof
    if (n->slaveof) clusterNodeRemoveSlave(n->slaveof,n);

    // 关闭 SLAVE 标识
    n->flags &= ~REDIS_NODE_SLAVE;

    // 打开 MASTER 标识
    n->flags |= REDIS_NODE_MASTER;

    // 清零 slaveof 属性
    n->slaveof = NULL;

    /* Update config and state. */
    clusterDoBeforeSleep(CLUSTER_TODO_SAVE_CONFIG|
                         CLUSTER_TODO_UPDATE_STATE);
}

// Assembly:
movl 0x30(%rdi), %eax
testb $0x1, %al
jne 0x5085c
pushq %r14
pushq %rbx
pushq %rax
movq %rdi, %rbx
movq 0x850(%rdi), %r14
testq %r14, %r14
je 0x5082d
movslq 0x844(%r14), %rcx
testq %rcx, %rcx
jle 0x5082d
movq 0x848(%r14), %rsi
xorl %edx, %edx
cmpq %rbx, (%rsi,%rdx,8)
je 0x5080b
incq %rdx
cmpq %rdx, %rcx
jne 0x507fb
jmp 0x5082d
leaq (%rsi,%rdx,8), %rdi
leaq (%rsi,%rdx,8), %rsi
addq $0x8, %rsi
notl %edx
addl %ecx, %edx
movslq %edx, %rdx
callq 0x1f780
decl 0x844(%r14)
movl 0x30(%rbx), %eax
andl $-0x4, %eax
incl %eax
movl %eax, 0x30(%rbx)
movq $0x0, 0x850(%rbx)
leaq 0x79761(%rip), %rax     # 0xc9fa8
movq 0x7d0(%rax), %rax
orl $0x6, 0x60078(%rax)
addq $0x8, %rsp
popq %rbx
popq %r14
retq
// File: /workspace/github_c_makefile_star2_O3/nilyang[P]redis-tdd-annotation/src/cluster.c
// Function: clusterDelSlot
int clusterDelSlot(int slot) {

    // 获取当前处理槽 slot 的节点 n
    clusterNode *n = server.cluster->slots[slot];

    if (!n) return REDIS_ERR;

    // 清除位图
    redisAssert(clusterNodeClearSlotBit(n,slot) == 1);

    // 清空负责处理槽的节点
    server.cluster->slots[slot] = NULL;

    return REDIS_OK;
}

// Assembly:
leaq 0x79744(%rip), %rax     # 0xc9fa8
movq 0x7d0(%rax), %rcx
movslq %edi, %rdx
movq 0x40028(%rcx,%rdx,8), %rsi
testq %rsi, %rsi
je 0x508cd
leal 0x7(%rdi), %ecx
testl %edi, %edi
cmovnsl %edi, %ecx
sarl $0x3, %ecx
movslq %ecx, %r8
movzbl 0x40(%rsi,%r8), %r9d
movl %edi, %ecx
andb $0x7, %cl
movl $0x1, %r10d
shll %cl, %r10d
notb %r10b
andb %r9b, %r10b
movb %r10b, 0x40(%rsi,%r8)
andl $0x7, %edi
btl %edi, %r9d
jae 0x508d3
decl 0x840(%rsi)
movq 0x7d0(%rax), %rax
movq $0x0, 0x40028(%rax,%rdx,8)
xorl %eax, %eax
retq
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
retq
pushq %rax
leaq 0x4bee9(%rip), %rdi     # 0x9c7c4
leaq 0x4b3db(%rip), %rsi     # 0x9bcbd
movl $0xfaa, %edx            # imm = 0xFAA
callq 0x4ca32
movl $0x1, %edi
callq 0x1f3b0
// File: /workspace/github_c_makefile_star2_O3/nilyang[P]redis-tdd-annotation/src/cluster.c
// Function: clusterDelNode
void clusterDelNode(clusterNode *delnode) {
    int j;
    dictIterator *di;
    dictEntry *de;

    /* 1) Mark slots as unassigned. */
    for (j = 0; j < REDIS_CLUSTER_SLOTS; j++) {
        // 取消向该节点接收槽的计划
        if (server.cluster->importing_slots_from[j] == delnode)
            server.cluster->importing_slots_from[j] = NULL;
        // 取消向该节点移交槽的计划
        if (server.cluster->migrating_slots_to[j] == delnode)
            server.cluster->migrating_slots_to[j] = NULL;
        // 将所有由该节点负责的槽设置为未分配
        if (server.cluster->slots[j] == delnode)
            clusterDelSlot(j);
    }

    /* 2) Remove failure reports. */
    // 移除所有由该节点发送的下线报告
    di = dictGetSafeIterator(server.cluster->nodes);
    while((de = dictNext(di)) != NULL) {
        clusterNode *node = dictGetVal(de);

        if (node == delnode) continue;
        clusterNodeDelFailureReport(node,delnode);
    }
    dictReleaseIterator(di);

    /* 3) Remove this node from its master's slaves if needed. */
    // 将节点从它的主节点的从节点列表中移除
    if (nodeIsSlave(delnode) && delnode->slaveof)
        clusterNodeRemoveSlave(delnode->slaveof,delnode);

    /* 4) Free the node, unlinking it from the cluster. */
    // 释放节点
    freeClusterNode(delnode);
}

// Assembly:
pushq %r15
pushq %r14
pushq %rbx
movq %rdi, %rbx
leaq 0x796a3(%rip), %r15     # 0xc9fa8
movq 0x7d0(%r15), %rax
xorl %r14d, %r14d
cmpq %rbx, 0x20028(%rax,%r14,8)
jne 0x5092c
movq $0x0, 0x20028(%rax,%r14,8)
movq 0x7d0(%r15), %rax
cmpq %rbx, 0x28(%rax,%r14,8)
jne 0x50943
movq $0x0, 0x28(%rax,%r14,8)
movq 0x7d0(%r15), %rax
cmpq %rbx, 0x40028(%rax,%r14,8)
jne 0x5095c
movl %r14d, %edi
callq 0x5085d
movq 0x7d0(%r15), %rax
incq %r14
cmpq $0x4000, %r14           # imm = 0x4000
jne 0x5090f
movq 0x18(%rax), %rdi
callq 0x22aa0
movq %rax, %r14
movq %rax, %rdi
callq 0x22acf
testq %rax, %rax
je 0x50997
movq 0x8(%rax), %rdi
cmpq %rbx, %rdi
je 0x50992
movq %rbx, %rsi
callq 0x50d70
movq %r14, %rdi
jmp 0x50977
movq %r14, %rdi
callq 0x22b86
testb $0x2, 0x30(%rbx)
je 0x509f5
movq 0x850(%rbx), %r14
testq %r14, %r14
je 0x509f5
movslq 0x844(%r14), %rax
testq %rax, %rax
jle 0x509f5
movq 0x848(%r14), %rdx
xorl %ecx, %ecx
cmpq %rbx, (%rdx,%rcx,8)
je 0x509d6
incq %rcx
cmpq %rcx, %rax
jne 0x509c6
jmp 0x509f5
leaq (%rdx,%rcx,8), %rdi
leaq (%rdx,%rcx,8), %rsi
addq $0x8, %rsi
notl %ecx
addl %eax, %ecx
movslq %ecx, %rdx
callq 0x1f780
decl 0x844(%r14)
movq %rbx, %rdi
popq %rbx
popq %r14
popq %r15
jmp 0x50e98
// File: /workspace/github_c_makefile_star2_O3/nilyang[P]redis-tdd-annotation/src/cluster.c
// Function: clusterNodeRemoveSlave
int clusterNodeRemoveSlave(clusterNode *master, clusterNode *slave) {
    int j;

    // 在 slaves 数组中找到从节点 slave 所属的主节点，
    // 将主节点中的 slave 信息移除
    for (j = 0; j < master->numslaves; j++) {
        if (master->slaves[j] == slave) {
            memmove(master->slaves+j,master->slaves+(j+1),
                (master->numslaves-1)-j);
            master->numslaves--;
            return REDIS_OK;
        }
    }
    return REDIS_ERR;
}

// Assembly:
movslq 0x844(%rdi), %rcx
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
testq %rcx, %rcx
jle 0x50e3a
pushq %rbx
movq %rdi, %rbx
movq 0x848(%rdi), %r8
xorl %edx, %edx
cmpq %rsi, (%r8,%rdx,8)
je 0x50e19
incq %rdx
cmpq %rdx, %rcx
jne 0x50e09
jmp 0x50e39
leaq (%r8,%rdx,8), %rdi
leaq (%r8,%rdx,8), %rsi
addq $0x8, %rsi
notl %edx
addl %ecx, %edx
movslq %edx, %rdx
callq 0x1f780
decl 0x844(%rbx)
xorl %eax, %eax
popq %rbx
retq
// File: /workspace/github_c_makefile_star2_O3/nilyang[P]redis-tdd-annotation/src/cluster.c
// Function: freeClusterNode
void freeClusterNode(clusterNode *n) {
    sds nodename;

    nodename = sdsnewlen(n->name, REDIS_CLUSTER_NAMELEN);

    // 从 nodes 表中删除节点
    redisAssert(dictDelete(server.cluster->nodes,nodename) == DICT_OK);
    sdsfree(nodename);

    // 移除从节点
    if (n->slaveof) clusterNodeRemoveSlave(n->slaveof, n);

    // 释放连接
    if (n->link) freeClusterLink(n->link);
    
    // 释放失败报告
    listRelease(n->fail_reports);

    // 释放节点结构
    zfree(n);
}

// Assembly:
pushq %r14
pushq %rbx
pushq %rax
movq %rdi, %rbx
addq $0x8, %rdi
movl $0x28, %esi
callq 0x283f4
movq %rax, %r14
leaq 0x790f1(%rip), %rax     # 0xc9fa8
movq 0x7d0(%rax), %rax
movq 0x18(%rax), %rdi
movq %r14, %rsi
callq 0x22796
testl %eax, %eax
jne 0x50f56
movq %r14, %rdi
callq 0x2850d
movq 0x850(%rbx), %r14
testq %r14, %r14
je 0x50f2a
movslq 0x844(%r14), %rax
testq %rax, %rax
jle 0x50f2a
movq 0x848(%r14), %rdx
xorl %ecx, %ecx
cmpq %rbx, (%rdx,%rcx,8)
je 0x50f0b
incq %rcx
cmpq %rcx, %rax
jne 0x50efb
jmp 0x50f2a
leaq (%rdx,%rcx,8), %rdi
leaq (%rdx,%rcx,8), %rsi
addq $0x8, %rsi
notl %ecx
addl %eax, %ecx
movslq %ecx, %rdx
callq 0x1f780
decl 0x844(%r14)
movq 0x8c0(%rbx), %rdi
testq %rdi, %rdi
je 0x50f3b
callq 0x50a5c
movq 0x8c8(%rbx), %rdi
callq 0x2041c
movq %rbx, %rdi
addq $0x8, %rsp
popq %rbx
popq %r14
jmp 0x29af7
leaq 0x4b0b3(%rip), %rdi     # 0x9c010
leaq 0x4ad59(%rip), %rsi     # 0x9bcbd
movl $0x3cb, %edx            # imm = 0x3CB
callq 0x4ca32
movl $0x1, %edi
callq 0x1f3b0
// File: /workspace/github_c_makefile_star2_O3/nilyang[P]redis-tdd-annotation/src/cluster.c
// Function: clusterRenameNode
void clusterRenameNode(clusterNode *node, char *newname) {
    int retval;
    sds s = sdsnewlen(node->name, REDIS_CLUSTER_NAMELEN);

    redisLog(REDIS_DEBUG,"Renaming node %.40s into %.40s",
        node->name, newname);
    retval = dictDelete(server.cluster->nodes, s);
    sdsfree(s);
    redisAssert(retval == DICT_OK);
    memcpy(node->name, newname, REDIS_CLUSTER_NAMELEN);
    clusterAddNode(node);
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
pushq %rax
movq %rsi, %r15
movq %rdi, %rbx
leaq 0x8(%rdi), %r14
movl $0x28, %esi
movq %r14, %rdi
callq 0x283f4
movq %rax, %r12
leaq 0x4b0a2(%rip), %rsi     # 0x9c046
xorl %edi, %edi
movq %r14, %rdx
movq %r15, %rcx
xorl %eax, %eax
callq 0x23223
leaq 0x78fee(%rip), %r13     # 0xc9fa8
movq 0x7d0(%r13), %rax
movq 0x18(%rax), %rdi
movq %r12, %rsi
callq 0x22796
movl %eax, %ebp
movq %r12, %rdi
callq 0x2850d
testl %ebp, %ebp
jne 0x51029
movq 0x20(%r15), %rax
movq %rax, 0x20(%r14)
movups (%r15), %xmm0
movups 0x10(%r15), %xmm1
movups %xmm1, 0x10(%r14)
movups %xmm0, (%r14)
movq 0x7d0(%r13), %rax
movq 0x18(%rax), %r15
movl $0x28, %esi
movq %r14, %rdi
callq 0x283f4
movq %r15, %rdi
movq %rax, %rsi
movq %rbx, %rdx
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x2249c
leaq 0x47826(%rip), %rdi     # 0x98856
leaq 0x4ac86(%rip), %rsi     # 0x9bcbd
movl $0x43b, %edx            # imm = 0x43B
callq 0x4ca32
movl $0x1, %edi
callq 0x1f3b0
// File: /workspace/github_c_makefile_star2_O3/nilyang[P]redis-tdd-annotation/src/cluster.c
// Function: clusterBlacklistAddNode
void clusterBlacklistAddNode(clusterNode *node) {
    dictEntry *de;
    sds id = sdsnewlen(node->name,REDIS_CLUSTER_NAMELEN);

    // 先清理过期名单
    clusterBlacklistCleanup();

    // 添加节点
    if (dictAdd(server.cluster->nodes_black_list,id,NULL) == DICT_OK) {
        /* If the key was added, duplicate the sds string representation of
         * the key for the next lookup. We'll free it at the end. */
        id = sdsdup(id);
    }
    // 设置过期时间
    de = dictFind(server.cluster->nodes_black_list,id);
    dictSetUnsignedIntegerVal(de,time(NULL)+REDIS_CLUSTER_BLACKLIST_TTL);
    sdsfree(id);
}

// Assembly:
pushq %r14
pushq %rbx
pushq %rax
addq $0x8, %rdi
movl $0x28, %esi
callq 0x283f4
movq %rax, %rbx
callq 0x5104b
leaq 0x78edd(%rip), %r14     # 0xc9fa8
movq 0x7d0(%r14), %rax
movq 0x20(%rax), %rdi
movq %rbx, %rsi
xorl %edx, %edx
callq 0x2249c
testl %eax, %eax
jne 0x510ef
movq %rbx, %rdi
callq 0x28504
movq %rax, %rbx
movq 0x7d0(%r14), %rax
movq 0x20(%rax), %rdi
movq %rbx, %rsi
callq 0x226ac
movq %rax, %r14
xorl %edi, %edi
callq 0x1fc50
addq $0x3c, %rax
movq %rax, 0x8(%r14)
movq %rbx, %rdi
addq $0x8, %rsp
popq %rbx
popq %r14
jmp 0x2850d
// File: /workspace/github_c_makefile_star2_O3/nilyang[P]redis-tdd-annotation/src/cluster.c
// Function: clusterBlacklistExists
int clusterBlacklistExists(char *nodeid) {

    // 构建 SDS 表示的节点名
    sds id = sdsnewlen(nodeid,REDIS_CLUSTER_NAMELEN);
    int retval;

    // 清除过期黑名单
    clusterBlacklistCleanup();

    // 检查节点是否存在
    retval = dictFind(server.cluster->nodes_black_list,id) != NULL;
    sdsfree(id);

    return retval;
}

// Assembly:
pushq %rbp
pushq %rbx
pushq %rax
movl $0x28, %esi
callq 0x283f4
movq %rax, %rbx
callq 0x5104b
leaq 0x78e69(%rip), %rax     # 0xc9fa8
movq 0x7d0(%rax), %rax
movq 0x20(%rax), %rdi
movq %rbx, %rsi
callq 0x226ac
xorl %ebp, %ebp
testq %rax, %rax
setne %bpl
movq %rbx, %rdi
callq 0x2850d
movl %ebp, %eax
addq $0x8, %rsp
popq %rbx
popq %rbp
retq
// File: /workspace/github_c_makefile_star2_O3/nilyang[P]redis-tdd-annotation/src/cluster.c
// Function: markNodeAsFailingIfNeeded
void markNodeAsFailingIfNeeded(clusterNode *node) {
    int failures;

    // 标记为 FAIL 所需的节点数量，需要超过集群节点数量的一半
    int needed_quorum = (server.cluster->size / 2) + 1;

    if (!nodeTimedOut(node)) return; /* We can reach it. */
    if (nodeFailed(node)) return; /* Already FAILing. */

    // 统计将 node 标记为 PFAIL 或者 FAIL 的节点数量（不包括当前节点）
    failures = clusterNodeFailureReportsCount(node);

    /* Also count myself as a voter if I'm a master. */
    // 如果当前节点是主节点，那么将当前节点也算在 failures 之内
    if (nodeIsMaster(myself)) failures++;
    // 报告下线节点的数量不足节点总数的一半，不能将节点判断为 FAIL ，返回
    if (failures < needed_quorum) return; /* No weak agreement from masters. */

    redisLog(REDIS_NOTICE,
        "Marking node %.40s as failing (quorum reached).", node->name);

    /* Mark the node as failing. */
    // 将 node 标记为 FAIL
    node->flags &= ~REDIS_NODE_PFAIL;
    node->flags |= REDIS_NODE_FAIL;
    node->fail_time = mstime();

    /* Broadcast the failing node name to everybody, forcing all the other
     * reachable nodes to flag the node as FAIL. */
    // 如果当前节点是主节点的话，那么向其他节点发送报告 node 的 FAIL 信息
    // 让其他节点也将 node 标记为 FAIL
    if (nodeIsMaster(myself)) clusterSendFail(node->name);
    clusterDoBeforeSleep(CLUSTER_TODO_UPDATE_STATE|CLUSTER_TODO_SAVE_CONFIG);
}

// Assembly:
movl 0x30(%rdi), %eax
andl $0xc, %eax
cmpl $0x4, %eax
jne 0x51262
pushq %rbp
pushq %r15
pushq %r14
pushq %rbx
subq $0x10d8, %rsp           # imm = 0x10D8
movq %rdi, %rbx
leaq 0x78e16(%rip), %r15     # 0xc9fa8
movq 0x7d0(%r15), %rax
movl 0x14(%rax), %eax
movl %eax, %ebp
shrl $0x1f, %ebp
addl %eax, %ebp
sarl %ebp
callq 0x50cef
movq 0x8c8(%rbx), %rax
movq 0x8d470(%rip), %rcx     # 0xde628
movl 0x30(%rcx), %ecx
andl $0x1, %ecx
addl 0x28(%rax), %ecx
cmpl %ebp, %ecx
jle 0x51255
leaq 0x8(%rbx), %r14
leaq 0x4ae91(%rip), %rsi     # 0x9c065
movl $0x2, %edi
movq %r14, %rdx
xorl %eax, %eax
callq 0x23223
movl 0x30(%rbx), %eax
andl $-0xd, %eax
orl $0x8, %eax
movl %eax, 0x30(%rbx)
callq 0x23461
movq %rax, 0x868(%rbx)
movq 0x8d426(%rip), %rax     # 0xde628
testb $0x1, 0x30(%rax)
je 0x51247
movq %rsp, %rbx
movq %rbx, %rdi
movl $0x3, %esi
callq 0x52b4e
movq 0x20(%r14), %rax
movq %rax, 0x8c0(%rbx)
movups (%r14), %xmm0
movups 0x10(%r14), %xmm1
movaps %xmm1, 0x8b0(%rbx)
movaps %xmm0, 0x8a0(%rbx)
movl 0x4(%rbx), %esi
bswapl %esi
movq %rbx, %rdi
callq 0x52ae9
movq 0x7d0(%r15), %rax
orl $0x6, 0x60078(%rax)
addq $0x10d8, %rsp           # imm = 0x10D8
popq %rbx
popq %r14
popq %r15
popq %rbp
retq
// File: /workspace/github_c_makefile_star2_O3/nilyang[P]redis-tdd-annotation/src/cluster.c
// Function: clusterSendFail
void clusterSendFail(char *nodename) {
    unsigned char buf[sizeof(clusterMsg)];
    clusterMsg *hdr = (clusterMsg*) buf;

    // 创建下线消息
    clusterBuildMessageHdr(hdr,CLUSTERMSG_TYPE_FAIL);

    // 记录命令
    memcpy(hdr->data.fail.about.nodename,nodename,REDIS_CLUSTER_NAMELEN);

    // 广播消息
    clusterBroadcastMessage(buf,ntohl(hdr->totlen));
}

// Assembly:
pushq %r14
pushq %rbx
subq $0x10d8, %rsp           # imm = 0x10D8
movq %rdi, %rbx
movq %rsp, %r14
movq %r14, %rdi
movl $0x3, %esi
callq 0x52b4e
movq 0x20(%rbx), %rax
movq %rax, 0x8c0(%r14)
movups (%rbx), %xmm0
movups 0x10(%rbx), %xmm1
movaps %xmm1, 0x8b0(%r14)
movaps %xmm0, 0x8a0(%r14)
movl 0x4(%r14), %esi
bswapl %esi
movq %r14, %rdi
callq 0x52ae9
addq $0x10d8, %rsp           # imm = 0x10D8
popq %rbx
popq %r14
retq
// File: /workspace/github_c_makefile_star2_O3/nilyang[P]redis-tdd-annotation/src/cluster.c
// Function: clearNodeFailureIfNeeded
void clearNodeFailureIfNeeded(clusterNode *node) {
    mstime_t now = mstime();

    redisAssert(nodeFailed(node));

    /* For slaves we always clear the FAIL flag if we can contact the
     * node again. */
    // 如果 FAIL 的是从节点，那么当前节点会直接移除该节点的 FAIL
    if (nodeIsSlave(node) || node->numslots == 0) {
        redisLog(REDIS_NOTICE,
            "Clear FAIL state for node %.40s: %s is reachable again.",
                node->name,
                nodeIsSlave(node) ? "slave" : "master without slots");
        // 移除
        node->flags &= ~REDIS_NODE_FAIL;

        clusterDoBeforeSleep(CLUSTER_TODO_UPDATE_STATE|CLUSTER_TODO_SAVE_CONFIG);
    }

    /* If it is a master and...
     *
     * 如果 FAIL 的是一个主节点，并且：
     *
     * 1) The FAIL state is old enough.
     *    节点被标记为 FAIL 状态已经有一段时间了
     *
     * 2) It is yet serving slots from our point of view (not failed over).
     *    从当前节点的视角来看，这个节点还有负责处理的槽
     *
     * Apparently no one is going to fix these slots, clear the FAIL flag. 
     *
     * 那么说明 FAIL 节点仍然有槽没有迁移完，那么当前节点移除该节点的 FAIL 标识。
     */
    if (nodeIsMaster(node) && node->numslots > 0 &&
        (now - node->fail_time) >
        (server.cluster_node_timeout * REDIS_CLUSTER_FAIL_UNDO_TIME_MULT))
    {
        redisLog(REDIS_NOTICE,
            "Clear FAIL state for node %.40s: is reachable again and nobody is serving its slots after some time.",
                node->name);

        // 撤销 FAIL 状态
        node->flags &= ~REDIS_NODE_FAIL;

        clusterDoBeforeSleep(CLUSTER_TODO_UPDATE_STATE|CLUSTER_TODO_SAVE_CONFIG);
    }
}

// Assembly:
pushq %r15
pushq %r14
pushq %rbx
movq %rdi, %rbx
callq 0x23461
movq %rax, %r14
movl 0x30(%rbx), %eax
testb $0x8, %al
je 0x51381
testb $0x2, %al
jne 0x512ec
cmpl $0x0, 0x840(%rbx)
jne 0x51328
leaq 0x4adf4(%rip), %rcx     # 0x9c0de
jmp 0x512f3
leaq 0x4bb87(%rip), %rcx     # 0x9ce7a
leaq 0x8(%rbx), %rdx
leaq 0x4ada8(%rip), %rsi     # 0x9c0a6
movl $0x2, %edi
xorl %eax, %eax
callq 0x23223
movl 0x30(%rbx), %eax
andl $-0x9, %eax
movl %eax, 0x30(%rbx)
leaq 0x78c8e(%rip), %rcx     # 0xc9fa8
movq 0x7d0(%rcx), %rcx
orl $0x6, 0x60078(%rcx)
testb $0x1, %al
je 0x5137b
cmpl $0x0, 0x840(%rbx)
jle 0x5137b
subq 0x868(%rbx), %r14
leaq 0x78c65(%rip), %r15     # 0xc9fa8
movq 0x7c0(%r15), %rax
addq %rax, %rax
cmpq %rax, %r14
jle 0x5137b
leaq 0x8(%rbx), %rdx
leaq 0x4ad96(%rip), %rsi     # 0x9c0f3
movl $0x2, %edi
xorl %eax, %eax
callq 0x23223
andb $-0x9, 0x30(%rbx)
movq 0x7d0(%r15), %rax
orl $0x6, 0x60078(%rax)
popq %rbx
popq %r14
popq %r15
retq
leaq 0x4ad0d(%rip), %rdi     # 0x9c095
leaq 0x4a92e(%rip), %rsi     # 0x9bcbd
movl $0x511, %edx            # imm = 0x511
callq 0x4ca32
movl $0x1, %edi
callq 0x1f3b0
// File: /workspace/github_c_makefile_star2_O3/nilyang[P]redis-tdd-annotation/src/cluster.c
// Function: clusterStartHandshake
int clusterStartHandshake(char *ip, int port) {
    clusterNode *n;
    char norm_ip[REDIS_IP_STR_LEN];
    struct sockaddr_storage sa;

    /* IP sanity check */
    // ip 合法性检查
    if (inet_pton(AF_INET,ip,
            &(((struct sockaddr_in *)&sa)->sin_addr)))
    {
        sa.ss_family = AF_INET;
    } else if (inet_pton(AF_INET6,ip,
            &(((struct sockaddr_in6 *)&sa)->sin6_addr)))
    {
        sa.ss_family = AF_INET6;
    } else {
        errno = EINVAL;
        return 0;
    }

    /* Port sanity check */
    // port 合法性检查
    if (port <= 0 || port > (65535-REDIS_CLUSTER_PORT_INCR)) {
        errno = EINVAL;
        return 0;
    }

    /* Set norm_ip as the normalized string representation of the node
     * IP address. */
    if (sa.ss_family == AF_INET)
        inet_ntop(AF_INET,
            (void*)&(((struct sockaddr_in *)&sa)->sin_addr),
            norm_ip,REDIS_IP_STR_LEN);
    else
        inet_ntop(AF_INET6,
            (void*)&(((struct sockaddr_in6 *)&sa)->sin6_addr),
            norm_ip,REDIS_IP_STR_LEN);

    // 检查节点是否已经发送握手请求，如果是的话，那么直接返回，防止出现重复握手
    if (clusterHandshakeInProgress(norm_ip,port)) {
        errno = EAGAIN;
        return 0;
    }

    /* Add the node with a random address (NULL as first argument to
     * createClusterNode()). Everything will be fixed during the
     * handskake. */
    // 对给定地址的节点设置一个随机名字
    // 当 HANDSHAKE 完成时，当前节点会取得给定地址节点的真正名字
    // 到时会用真名替换随机名
    n = createClusterNode(NULL,REDIS_NODE_HANDSHAKE|REDIS_NODE_MEET);
    memcpy(n->ip,norm_ip,sizeof(n->ip));
    n->port = port;

    // 将节点添加到集群当中
    clusterAddNode(n);

    return 1;
}

// Assembly:
pushq %r15
pushq %r14
pushq %rbx
subq $0xb0, %rsp
movl %esi, %ebx
movq %rdi, %r15
leaq 0x34(%rsp), %r14
movl $0x2, %edi
movq %r15, %rsi
movq %r14, %rdx
callq 0x1f150
testl %eax, %eax
je 0x51470
movw $0x2, 0x30(%rsp)
leal -0xd8f0(%rbx), %eax
cmpl $0xffff2711, %eax       # imm = 0xFFFF2711
jb 0x5149c
movq %rsp, %rdx
movl $0x2, %edi
jmp 0x514b1
leaq 0x38(%rsp), %r14
movl $0xa, %edi
movq %r15, %rsi
movq %r14, %rdx
callq 0x1f150
testl %eax, %eax
je 0x5149c
movw $0xa, 0x30(%rsp)
movl $0xffff2710, %eax       # imm = 0xFFFF2710
leal (%rbx,%rax), %ecx
cmpl %eax, %ecx
ja 0x514a9
callq 0x1f810
movl $0x16, (%rax)
jmp 0x514d7
movq %rsp, %rdx
movl $0xa, %edi
movq %r14, %rsi
movl $0x2e, %ecx
callq 0x1fbc0
movq %rsp, %rdi
movl %ebx, %esi
callq 0x513a3
testl %eax, %eax
je 0x514e6
callq 0x1f810
movl $0xb, (%rax)
xorl %eax, %eax
addq $0xb0, %rsp
popq %rbx
popq %r14
popq %r15
retq
xorl %edi, %edi
movl $0xa0, %esi
callq 0x4fe27
movq %rax, %r14
movaps (%rsp), %xmm0
movaps 0x10(%rsp), %xmm1
movups %xmm0, 0x888(%rax)
movups %xmm1, 0x898(%rax)
movups 0x1e(%rsp), %xmm0
movups %xmm0, 0x8a6(%rax)
movl %ebx, 0x8b8(%rax)
leaq 0x78a83(%rip), %rax     # 0xc9fa8
movq 0x7d0(%rax), %rax
movq 0x18(%rax), %rbx
leaq 0x8(%r14), %rdi
movl $0x28, %esi
callq 0x283f4
movq %rbx, %rdi
movq %rax, %rsi
movq %r14, %rdx
callq 0x2249c
movl $0x1, %eax
jmp 0x514d9