LLM4Binary/decompile-bench-makefile huggingface dataset:
// File: /workspace/github_c_makefile_star2_O2/nilyang[P]redis-tdd-annotation/src/t_string.c
// Function: incrDecrCommand
void incrDecrCommand(redisClient *c, long long incr) {
    long long value, oldvalue;
    robj *o, *new;

    // 取出值对象
    o = lookupKeyWrite(c->db,c->argv[1]);

    // 检查对象是否存在，以及类型是否正确
    if (o != NULL && checkType(c,o,REDIS_STRING)) return;

    // 取出对象的整数值，并保存到 value 参数中
    if (getLongLongFromObjectOrReply(c,o,&value,NULL) != REDIS_OK) return;

    // 检查加法操作执行之后值释放会溢出
    // 如果是的话，就向客户端发送一个出错回复，并放弃设置操作
    oldvalue = value;
    if ((incr < 0 && oldvalue < 0 && incr < (LLONG_MIN-oldvalue)) ||
        (incr > 0 && oldvalue > 0 && incr > (LLONG_MAX-oldvalue))) {
        addReplyError(c,"increment or decrement would overflow");
        return;
    }

    // 进行加法计算，并将值保存到新的值对象中
    // 然后用新的值对象替换原来的值对象
    value += incr;
    new = createStringObjectFromLongLong(value);
    if (o)
        dbOverwrite(c->db,c->argv[1],new);
    else
        dbAdd(c->db,c->argv[1],new);

    // 向数据库发送键被修改的信号
    signalModifiedKey(c->db,c->argv[1]);

    // 发送事件通知
    notifyKeyspaceEvent(REDIS_NOTIFY_STRING,"incrby",c->argv[1],c->db->id);

    // 将服务器设为脏
    server.dirty++;

    // 返回回复
    addReply(c,shared.colon);
    addReply(c,new);
    addReply(c,shared.crlf);
}

// Assembly:
pushq %r15
pushq %r14
pushq %rbx
subq $0x10, %rsp
movq %rsi, %r15
movq %rdi, %rbx
movq 0x8(%rdi), %rdi
movq 0x38(%rbx), %rax
movq 0x8(%rax), %rsi
callq 0x2f988
movq %rax, %r14
testq %rax, %rax
je 0x368aa
movq %rbx, %rdi
movq %r14, %rsi
xorl %edx, %edx
callq 0x2eec6
testl %eax, %eax
jne 0x369ad
leaq 0x8(%rsp), %rdx
movq %rbx, %rdi
movq %r14, %rsi
xorl %ecx, %ecx
callq 0x2f617
testl %eax, %eax
jne 0x369ad
movabsq $0x7fffffffffffffff, %rax # imm = 0x7FFFFFFFFFFFFFFF
movq 0x8(%rsp), %rdi
subq %rdi, %rax
testq %r15, %r15
jns 0x368e9
testq %rdi, %rdi
jns 0x368e9
leaq 0x1(%rax), %rcx
cmpq %r15, %rcx
jg 0x36903
testq %r15, %r15
setg %cl
testq %rdi, %rdi
setg %dl
andb %cl, %dl
cmpq %r15, %rax
setl %al
andb %dl, %al
cmpb $0x1, %al
jne 0x36917
leaq 0x585ee(%rip), %rsi     # 0x8eef8
movq %rbx, %rdi
callq 0x2c2da
jmp 0x369ad
addq %r15, %rdi
movq %rdi, 0x8(%rsp)
callq 0x2ea90
movq %rax, %r15
movq 0x8(%rbx), %rdi
movq 0x38(%rbx), %rax
movq 0x8(%rax), %rsi
movq %r15, %rdx
testq %r14, %r14
je 0x36942
callq 0x2fab8
jmp 0x36947
callq 0x2fa09
movq 0x8(%rbx), %rdi
movq 0x38(%rbx), %rax
movq 0x8(%rax), %rsi
callq 0x2fbc0
movq 0x8(%rbx), %rax
movq 0x38(%rbx), %rcx
movq 0x8(%rcx), %rdx
movl 0x30(%rax), %ecx
leaq 0x53b1a(%rip), %rsi     # 0x8a488
pushq $0x8
popq %rdi
callq 0x5b488
leaq 0x9062b(%rip), %rax     # 0xc6fa8
incq 0x560(%rax)
leaq 0x90e75(%rip), %r14     # 0xc7800
movq 0x48(%r14), %rsi
movq %rbx, %rdi
callq 0x2c10d
movq %rbx, %rdi
movq %r15, %rsi
callq 0x2c10d
movq (%r14), %rsi
movq %rbx, %rdi
callq 0x2c10d
addq $0x10, %rsp
popq %rbx
popq %r14
popq %r15
retq
// File: /workspace/github_c_makefile_star2_O2/nilyang[P]redis-tdd-annotation/src/t_string.c
// Function: appendCommand
void appendCommand(redisClient *c) {
    size_t totlen;
    robj *o, *append;

    // 取出键相应的值对象
    o = lookupKeyWrite(c->db,c->argv[1]);
    if (o == NULL) {

        // 键值对不存在。。。

        /* Create the key */
        // 键值对不存在，创建一个新的
        c->argv[2] = tryObjectEncoding(c->argv[2]);
        dbAdd(c->db,c->argv[1],c->argv[2]);
        incrRefCount(c->argv[2]);
        totlen = stringObjectLen(c->argv[2]);
    } else {

        // 键值对存在。。。

        /* Key exists, check type */
        // 检查类型
        if (checkType(c,o,REDIS_STRING))
            return;

        /* "append" is an argument, so always an sds */
        // 检查追加操作之后，字符串的长度是否符合 Redis 的限制
        append = c->argv[2];
        totlen = stringObjectLen(o)+sdslen(append->ptr);
        if (checkStringLength(c,totlen) != REDIS_OK)
            return;

        /* Append the value */
        // 执行追加操作
        o = dbUnshareStringValue(c->db,c->argv[1],o);
        o->ptr = sdscatlen(o->ptr,append->ptr,sdslen(append->ptr));
        totlen = sdslen(o->ptr);
    }

    // 向数据库发送键被修改的信号
    signalModifiedKey(c->db,c->argv[1]);

    // 发送事件通知
    notifyKeyspaceEvent(REDIS_NOTIFY_STRING,"append",c->argv[1],c->db->id);

    // 将服务器设为脏
    server.dirty++;

    // 发送回复
    addReplyLongLong(c,totlen);
}

// Assembly:
pushq %r15
pushq %r14
pushq %rbx
movq %rdi, %rbx
movq 0x8(%rdi), %rdi
movq 0x38(%rbx), %rax
movq 0x8(%rax), %rsi
callq 0x2f988
testq %rax, %rax
je 0x36c11
movq %rax, %r14
movq %rbx, %rdi
movq %rax, %rsi
xorl %edx, %edx
callq 0x2eec6
testl %eax, %eax
jne 0x36c0b
movq 0x38(%rbx), %rax
movq 0x10(%rax), %r15
movq %r14, %rdi
callq 0x2f227
movq 0x8(%r15), %rcx
movslq -0x8(%rcx), %rsi
addq %rax, %rsi
movq %rbx, %rdi
callq 0x36590
testl %eax, %eax
je 0x36ca5
popq %rbx
popq %r14
popq %r15
retq
movq 0x38(%rbx), %rax
movq 0x10(%rax), %rdi
callq 0x2ef4c
movq 0x38(%rbx), %rcx
movq %rax, 0x10(%rcx)
movq 0x8(%rbx), %rdi
movq 0x38(%rbx), %rax
movq 0x8(%rax), %rsi
movq 0x10(%rax), %rdx
callq 0x2fa09
movq 0x38(%rbx), %rax
movq 0x10(%rax), %rdi
callq 0x2eacc
movq 0x38(%rbx), %rax
movq 0x10(%rax), %rdi
callq 0x2f227
movq %rax, %r14
movq 0x8(%rbx), %rdi
movq 0x38(%rbx), %rax
movq 0x8(%rax), %rsi
callq 0x2fbc0
movq 0x8(%rbx), %rax
movq 0x38(%rbx), %rcx
movq 0x8(%rcx), %rdx
movl 0x30(%rax), %ecx
leaq 0x53604(%rip), %rsi     # 0x8a283
pushq $0x8
popq %rdi
callq 0x5b488
leaq 0x9031a(%rip), %rax     # 0xc6fa8
incq 0x560(%rax)
movq %rbx, %rdi
movq %r14, %rsi
popq %rbx
popq %r14
popq %r15
jmp 0x2c794
movq 0x8(%rbx), %rdi
movq 0x38(%rbx), %rax
movq 0x8(%rax), %rsi
movq %r14, %rdx
callq 0x2fcc5
movq %rax, %r14
movq 0x8(%rax), %rdi
movq 0x8(%r15), %rsi
movslq -0x8(%rsi), %rdx
callq 0x2736d
movq %rax, 0x8(%r14)
movslq -0x8(%rax), %r14
jmp 0x36c58
// File: /workspace/github_c_makefile_star2_O2/nilyang[P]redis-tdd-annotation/src/t_string.c
// Function: strlenCommand
void strlenCommand(redisClient *c) {
    robj *o;

    // 取出值对象，并进行类型检查
    if ((o = lookupKeyReadOrReply(c,c->argv[1],shared.czero)) == NULL ||
        checkType(c,o,REDIS_STRING)) return;

    // 返回字符串值的长度
    addReplyLongLong(c,stringObjectLen(o));
}

// Assembly:
pushq %r14
pushq %rbx
pushq %rax
movq %rdi, %rbx
movq 0x38(%rdi), %rax
movq 0x8(%rax), %rsi
leaq 0x90b13(%rip), %rax     # 0xc7800
movq 0x20(%rax), %rdx
callq 0x2f9a9
testq %rax, %rax
je 0x36d0f
movq %rax, %r14
movq %rbx, %rdi
movq %rax, %rsi
xorl %edx, %edx
callq 0x2eec6
testl %eax, %eax
je 0x36d17
addq $0x8, %rsp
popq %rbx
popq %r14
retq
movq %r14, %rdi
callq 0x2f227
movq %rbx, %rdi
movq %rax, %rsi
addq $0x8, %rsp
popq %rbx
popq %r14
jmp 0x2c794
nopl (%rax)
// File: /workspace/github_c_makefile_star2_O2/nilyang[P]redis-tdd-annotation/src/t_list.c
// Function: listTypeTryConversion
void listTypeTryConversion(robj *subject, robj *value) {

    // 确保 subject 为 ZIPLIST 编码
    if (subject->encoding != REDIS_ENCODING_ZIPLIST) return;

    if (sdsEncodedObject(value) &&
        // 看字符串是否过长
        sdslen(value->ptr) > server.list_max_ziplist_value)
            // 将编码转换为双端链表
            listTypeConvert(subject,REDIS_ENCODING_LINKEDLIST);
}

// Assembly:
movl $0xf0, %eax
andl (%rdi), %eax
cmpl $0x50, %eax
jne 0x36d69
movl (%rsi), %eax
shrl $0x4, %eax
testb $0x7, %al
jne 0x36d69
movq 0x8(%rsi), %rax
movslq -0x8(%rax), %rax
leaq 0x90250(%rip), %rcx     # 0xc6fa8
cmpq %rax, 0x770(%rcx)
jae 0x36d69
pushq $0x4
popq %rsi
jmp 0x36d6a
retq
// File: /workspace/github_c_makefile_star2_O2/nilyang[P]redis-tdd-annotation/src/t_list.c
// Function: listTypeConvert
void listTypeConvert(robj *subject, int enc) {

    listTypeIterator *li;

    listTypeEntry entry;

    redisAssertWithInfo(NULL,subject,subject->type == REDIS_LIST);

    // 转换成双端链表
    if (enc == REDIS_ENCODING_LINKEDLIST) {

        list *l = listCreate();

        listSetFreeMethod(l,decrRefCountVoid);

        /* listTypeGet returns a robj with incremented refcount */
        // 遍历 ziplist ，并将里面的值全部添加到双端链表中
        li = listTypeInitIterator(subject,0,REDIS_TAIL);
        while (listTypeNext(li,&entry)) listAddNodeTail(l,listTypeGet(&entry));
        listTypeReleaseIterator(li);

        // 更新编码
        subject->encoding = REDIS_ENCODING_LINKEDLIST;

        // 释放原来的 ziplist
        zfree(subject->ptr);

        // 更新对象值指针
        subject->ptr = l;

    } else {
        redisPanic("Unsupported list conversion");
    }
}

// Assembly:
pushq %r15
pushq %r14
pushq %r12
pushq %rbx
subq $0x18, %rsp
movq %rdi, %rbx
movl (%rdi), %eax
andl $0xf, %eax
cmpl $0x1, %eax
jne 0x36e06
cmpl $0x4, %esi
jne 0x36e26
callq 0x1fd8c
movq %rax, %r14
leaq -0x819c(%rip), %rax     # 0x2ec02
movq %rax, 0x18(%r14)
pushq $0x1
popq %rdx
movq %rbx, %rdi
xorl %esi, %esi
callq 0x37058
movq %rax, %r15
movq %rsp, %r12
movq %r15, %rdi
movq %r12, %rsi
callq 0x370e4
testl %eax, %eax
je 0x36dd9
movq %r12, %rdi
callq 0x37195
movq %r14, %rdi
movq %rax, %rsi
callq 0x1fe4c
jmp 0x36db5
movq %r15, %rdi
callq 0x283cd
movl $0xffffff0f, %eax       # imm = 0xFFFFFF0F
andl (%rbx), %eax
orl $0x40, %eax
movl %eax, (%rbx)
movq 0x8(%rbx), %rdi
callq 0x283cd
movq %r14, 0x8(%rbx)
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
retq
leaq 0x581cc(%rip), %rdx     # 0x8efd9
leaq 0x5815e(%rip), %rcx     # 0x8ef72
xorl %edi, %edi
movq %rbx, %rsi
movl $0x1c8, %r8d            # imm = 0x1C8
callq 0x4980c
jmp 0x36e3e
leaq 0x581c8(%rip), %rdi     # 0x8eff5
leaq 0x5813e(%rip), %rsi     # 0x8ef72
movl $0x1e1, %edx            # imm = 0x1E1
callq 0x490e8
pushq $0x1
popq %rdi
callq 0x1f3b0
// File: /workspace/github_c_makefile_star2_O2/nilyang[P]redis-tdd-annotation/src/t_list.c
// Function: listTypePush
void listTypePush(robj *subject, robj *value, int where) {

    /* Check if we need to convert the ziplist */
    // 是否需要转换编码？
    listTypeTryConversion(subject,value);

    if (subject->encoding == REDIS_ENCODING_ZIPLIST &&
        ziplistLen(subject->ptr) >= server.list_max_ziplist_entries)
            listTypeConvert(subject,REDIS_ENCODING_LINKEDLIST);

    // ZIPLIST
    if (subject->encoding == REDIS_ENCODING_ZIPLIST) {
        int pos = (where == REDIS_HEAD) ? ZIPLIST_HEAD : ZIPLIST_TAIL;
        // 取出对象的值，因为 ZIPLIST 只能保存字符串或整数
        value = getDecodedObject(value);
        subject->ptr = ziplistPush(subject->ptr,value->ptr,sdslen(value->ptr),pos);
        decrRefCount(value);

    // 双端链表
    } else if (subject->encoding == REDIS_ENCODING_LINKEDLIST) {
        if (where == REDIS_HEAD) {
            listAddNodeHead(subject->ptr,value);
        } else {
            listAddNodeTail(subject->ptr,value);
        }
        incrRefCount(value);

    // 未知编码
    } else {
        redisPanic("Unknown list encoding");
    }
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %rbx
pushq %rax
movl %edx, %ebp
movq %rsi, %rbx
movq %rdi, %r14
callq 0x36d34
movl $0xf0, %eax
andl (%r14), %eax
cmpl $0x50, %eax
jne 0x36e8d
movq 0x8(%r14), %rdi
callq 0x2b465
movl %eax, %eax
leaq 0x9012f(%rip), %rcx     # 0xc6fa8
cmpq %rax, 0x768(%rcx)
ja 0x36e8d
pushq $0x4
popq %rsi
movq %r14, %rdi
callq 0x36d6a
movl (%r14), %eax
shrl $0x4, %eax
andl $0xf, %eax
cmpl $0x4, %eax
je 0x36edd
cmpl $0x5, %eax
jne 0x36f06
xorl %r15d, %r15d
testl %ebp, %ebp
setne %r15b
movq %rbx, %rdi
callq 0x2f087
movq %rax, %rbx
movq 0x8(%r14), %rdi
movq 0x8(%rax), %rsi
movl -0x8(%rsi), %edx
movl %r15d, %ecx
callq 0x2a889
movq %rax, 0x8(%r14)
movq %rbx, %rdi
addq $0x8, %rsp
popq %rbx
popq %r14
popq %r15
popq %rbp
jmp 0x2ee1f
movq 0x8(%r14), %rdi
movq %rbx, %rsi
testl %ebp, %ebp
je 0x36eef
callq 0x1fe4c
jmp 0x36ef4
callq 0x1fdf5
movq %rbx, %rdi
addq $0x8, %rsp
popq %rbx
popq %r14
popq %r15
popq %rbp
jmp 0x2eacc
leaq 0x57b97(%rip), %rdi     # 0x8eaa4
leaq 0x5805e(%rip), %rsi     # 0x8ef72
pushq $0x69
popq %rdx
callq 0x490e8
pushq $0x1
popq %rdi
callq 0x1f3b0
// File: /workspace/github_c_makefile_star2_O2/nilyang[P]redis-tdd-annotation/src/t_list.c
// Function: listTypePop
robj *listTypePop(robj *subject, int where) {

    robj *value = NULL;

    // ZIPLIST
    if (subject->encoding == REDIS_ENCODING_ZIPLIST) {
        unsigned char *p;
        unsigned char *vstr;
        unsigned int vlen;
        long long vlong;

        // 决定弹出元素的位置
        int pos = (where == REDIS_HEAD) ? 0 : -1;

        p = ziplistIndex(subject->ptr,pos);
        if (ziplistGet(p,&vstr,&vlen,&vlong)) {
            // 为被弹出元素创建对象
            if (vstr) {
                value = createStringObject((char*)vstr,vlen);
            } else {
                value = createStringObjectFromLongLong(vlong);
            }
            /* We only need to delete an element when it exists */
            // 从 ziplist 中删除被弹出元素
            subject->ptr = ziplistDelete(subject->ptr,&p);
        }

    // 双端链表
    } else if (subject->encoding == REDIS_ENCODING_LINKEDLIST) {

        list *list = subject->ptr;

        listNode *ln;

        if (where == REDIS_HEAD) {
            ln = listFirst(list);
        } else {
            ln = listLast(list);
        }

        // 删除被弹出节点
        if (ln != NULL) {
            value = listNodeValue(ln);
            incrRefCount(value);
            listDelNode(list,ln);
        }

    // 未知编码
    } else {
        redisPanic("Unknown list encoding");
    }

    // 返回节点对象
    return value;
}

// Assembly:
pushq %r15
pushq %r14
pushq %rbx
subq $0x20, %rsp
movq %rdi, %rbx
movl (%rdi), %eax
shrl $0x4, %eax
andl $0xf, %eax
cmpl $0x4, %eax
je 0x36f90
cmpl $0x5, %eax
jne 0x36fee
xorl %r14d, %r14d
negl %esi
movl $0x0, %esi
sbbl %esi, %esi
movq 0x8(%rbx), %rdi
callq 0x2abfb
movq %rax, 0x18(%rsp)
leaq 0x10(%rsp), %rsi
leaq 0x4(%rsp), %rdx
leaq 0x8(%rsp), %rcx
movq %rax, %rdi
callq 0x2aea9
testl %eax, %eax
je 0x36fe1
movq 0x10(%rsp), %rdi
testq %rdi, %rdi
je 0x36fc2
movl 0x4(%rsp), %esi
callq 0x2ea81
jmp 0x36fcc
movq 0x8(%rbx), %rbx
xorl %eax, %eax
testl %esi, %esi
setne %al
movq (%rbx,%rax,8), %r15
testq %r15, %r15
je 0x36fbd
movq 0x10(%r15), %r14
movq %r14, %rdi
callq 0x2eacc
movq %rbx, %rdi
movq %r15, %rsi
callq 0x1ff28
jmp 0x36fe1
xorl %r14d, %r14d
jmp 0x36fe1
movq 0x8(%rsp), %rdi
callq 0x2ea90
movq %rax, %r14
movq 0x8(%rbx), %rdi
leaq 0x18(%rsp), %rsi
callq 0x2afb7
movq %rax, 0x8(%rbx)
movq %r14, %rax
addq $0x20, %rsp
popq %rbx
popq %r14
popq %r15
retq
leaq 0x57aaf(%rip), %rdi     # 0x8eaa4
leaq 0x57f76(%rip), %rsi     # 0x8ef72
movl $0xa7, %edx
callq 0x490e8
pushq $0x1
popq %rdi
callq 0x1f3b0
// File: /workspace/github_c_makefile_star2_O2/nilyang[P]redis-tdd-annotation/src/t_list.c
// Function: listTypeLength
unsigned long listTypeLength(robj *subject) {

    // ZIPLIST
    if (subject->encoding == REDIS_ENCODING_ZIPLIST) {
        return ziplistLen(subject->ptr);

    // 双端链表
    } else if (subject->encoding == REDIS_ENCODING_LINKEDLIST) {
        return listLength((list*)subject->ptr);

    // 未知编码
    } else {
        redisPanic("Unknown list encoding");
    }
}

// Assembly:
pushq %rax
movl (%rdi), %eax
shrl $0x4, %eax
andl $0xf, %eax
cmpl $0x4, %eax
je 0x3702e
cmpl $0x5, %eax
jne 0x37038
movq 0x8(%rdi), %rdi
callq 0x2b465
movl %eax, %eax
jmp 0x37036
movq 0x8(%rdi), %rax
movq 0x28(%rax), %rax
popq %rcx
retq
leaq 0x57a65(%rip), %rdi     # 0x8eaa4
leaq 0x57f2c(%rip), %rsi     # 0x8ef72
movl $0xbd, %edx
callq 0x490e8
pushq $0x1
popq %rdi
callq 0x1f3b0
// File: /workspace/github_c_makefile_star2_O2/nilyang[P]redis-tdd-annotation/src/t_list.c
// Function: listTypeInitIterator
listTypeIterator *listTypeInitIterator(robj *subject, long index, unsigned char direction) {

    listTypeIterator *li = zmalloc(sizeof(listTypeIterator));

    li->subject = subject;

    li->encoding = subject->encoding;

    li->direction = direction;

    // ZIPLIST
    if (li->encoding == REDIS_ENCODING_ZIPLIST) {
        li->zi = ziplistIndex(subject->ptr,index);

    // 双端链表
    } else if (li->encoding == REDIS_ENCODING_LINKEDLIST) {
        li->ln = listIndex(subject->ptr,index);

    // 未知编码
    } else {
        redisPanic("Unknown list encoding");
    }

    return li;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %rbx
pushq %rax
movl %edx, %ebp
movq %rsi, %r14
movq %rdi, %r15
pushq $0x20
popq %rdi
callq 0x2828d
movq %rax, %rbx
movq %r15, (%rax)
movb (%r15), %al
shrb $0x4, %al
movb %al, 0x8(%rbx)
movb %bpl, 0x9(%rbx)
cmpb $0x4, %al
je 0x3709e
movzbl %al, %eax
cmpl $0x5, %eax
jne 0x370bf
movq 0x8(%r15), %rdi
movl %r14d, %esi
callq 0x2abfb
pushq $0x10
jmp 0x370ac
movq 0x8(%r15), %rdi
movq %r14, %rsi
callq 0x200c3
pushq $0x18
popq %rcx
movq %rax, (%rbx,%rcx)
movq %rbx, %rax
addq $0x8, %rsp
popq %rbx
popq %r14
popq %r15
popq %rbp
retq
leaq 0x579de(%rip), %rdi     # 0x8eaa4
leaq 0x57ea5(%rip), %rsi     # 0x8ef72
movl $0xdf, %edx
callq 0x490e8
pushq $0x1
popq %rdi
callq 0x1f3b0
// File: /workspace/github_c_makefile_star2_O2/nilyang[P]redis-tdd-annotation/src/t_list.c
// Function: listTypeNext
int listTypeNext(listTypeIterator *li, listTypeEntry *entry) {
    /* Protect from converting when iterating */
    redisAssert(li->subject->encoding == li->encoding);

    entry->li = li;

    // 迭代 ZIPLIST
    if (li->encoding == REDIS_ENCODING_ZIPLIST) {

        // 记录当前节点到 entry
        entry->zi = li->zi;

        // 移动迭代器的指针
        if (entry->zi != NULL) {
            if (li->direction == REDIS_TAIL)
                li->zi = ziplistNext(li->subject->ptr,li->zi);
            else
                li->zi = ziplistPrev(li->subject->ptr,li->zi);
            return 1;
        }

    // 迭代双端链表
    } else if (li->encoding == REDIS_ENCODING_LINKEDLIST) {

        // 记录当前节点到 entry
        entry->ln = li->ln;

        // 移动迭代器的指针
        if (entry->ln != NULL) {
            if (li->direction == REDIS_TAIL)
                li->ln = li->ln->next;
            else
                li->ln = li->ln->prev;
            return 1;
        }

    // 未知编码
    } else {
        redisPanic("Unknown list encoding");
    }

    // 列表元素已经全部迭代完
    return 0;
}

// Assembly:
pushq %rbx
movq (%rdi), %rcx
movl (%rcx), %edx
shrl $0x4, %edx
andl $0xf, %edx
movzbl 0x8(%rdi), %eax
cmpl %eax, %edx
jne 0x3715b
movq %rdi, %rbx
movq %rdi, (%rsi)
cmpl $0x4, %eax
je 0x37129
cmpl $0x5, %eax
jne 0x37175
movq 0x10(%rbx), %rax
movq %rax, 0x8(%rsi)
testq %rax, %rax
je 0x37149
cmpb $0x1, 0x9(%rbx)
movq 0x8(%rcx), %rdi
movq %rax, %rsi
jne 0x3714d
callq 0x2ae0d
jmp 0x37152
movq 0x18(%rbx), %rax
movq %rax, 0x10(%rsi)
testq %rax, %rax
je 0x37149
xorl %ecx, %ecx
cmpb $0x1, 0x9(%rbx)
sete %cl
movq (%rax,%rcx,8), %rax
movq %rax, 0x18(%rbx)
jmp 0x37156
xorl %eax, %eax
jmp 0x37159
callq 0x2ae33
movq %rax, 0x10(%rbx)
pushq $0x1
popq %rax
popq %rbx
retq
leaq 0x57e19(%rip), %rdi     # 0x8ef7b
leaq 0x57e09(%rip), %rsi     # 0x8ef72
movl $0xf7, %edx
callq 0x4906b
jmp 0x3718d
leaq 0x57928(%rip), %rdi     # 0x8eaa4
leaq 0x57def(%rip), %rsi     # 0x8ef72
movl $0x11b, %edx            # imm = 0x11B
callq 0x490e8
pushq $0x1
popq %rdi
callq 0x1f3b0
// File: /workspace/github_c_makefile_star2_O2/nilyang[P]redis-tdd-annotation/src/t_list.c
// Function: listTypeGet
robj *listTypeGet(listTypeEntry *entry) {

    listTypeIterator *li = entry->li;

    robj *value = NULL;

    // 根据索引，从 ZIPLIST 中取出节点的值
    if (li->encoding == REDIS_ENCODING_ZIPLIST) {
        unsigned char *vstr;
        unsigned int vlen;
        long long vlong;
        redisAssert(entry->zi != NULL);
        if (ziplistGet(entry->zi,&vstr,&vlen,&vlong)) {
            if (vstr) {
                value = createStringObject((char*)vstr,vlen);
            } else {
                value = createStringObjectFromLongLong(vlong);
            }
        }

    // 从双端链表中取出节点的值
    } else if (li->encoding == REDIS_ENCODING_LINKEDLIST) {
        redisAssert(entry->ln != NULL);
        value = listNodeValue(entry->ln);
        incrRefCount(value);

    } else {
        redisPanic("Unknown list encoding");
    }

    return value;
}

// Assembly:
pushq %rbx
subq $0x20, %rsp
movq (%rdi), %rax
movzbl 0x8(%rax), %eax
cmpl $0x4, %eax
je 0x371e5
cmpl $0x5, %eax
jne 0x37216
movq 0x8(%rdi), %rdi
testq %rdi, %rdi
je 0x37245
leaq 0x18(%rsp), %rsi
leaq 0xc(%rsp), %rdx
leaq 0x10(%rsp), %rcx
callq 0x2aea9
testl %eax, %eax
je 0x371fc
movq 0x18(%rsp), %rdi
testq %rdi, %rdi
je 0x37200
movl 0xc(%rsp), %esi
callq 0x2ea81
jmp 0x3720a
movq 0x10(%rdi), %rax
testq %rax, %rax
je 0x37230
movq 0x10(%rax), %rbx
movq %rbx, %rdi
callq 0x2eacc
jmp 0x3720d
xorl %ebx, %ebx
jmp 0x3720d
movq 0x10(%rsp), %rdi
callq 0x2ea90
movq %rax, %rbx
movq %rbx, %rax
addq $0x20, %rsp
popq %rbx
retq
leaq 0x57887(%rip), %rdi     # 0x8eaa4
leaq 0x57d4e(%rip), %rsi     # 0x8ef72
movl $0x143, %edx            # imm = 0x143
callq 0x490e8
jmp 0x3725d
leaq 0x57d7c(%rip), %rdi     # 0x8efb3
leaq 0x57d34(%rip), %rsi     # 0x8ef72
movl $0x13e, %edx            # imm = 0x13E
jmp 0x37258
leaq 0x57d55(%rip), %rdi     # 0x8efa1
leaq 0x57d1f(%rip), %rsi     # 0x8ef72
movl $0x133, %edx            # imm = 0x133
callq 0x4906b
pushq $0x1
popq %rdi
callq 0x1f3b0
// File: /workspace/github_c_makefile_star2_O2/nilyang[P]redis-tdd-annotation/src/t_list.c
// Function: listTypeInsert
void listTypeInsert(listTypeEntry *entry, robj *value, int where) {

    robj *subject = entry->li->subject;

    // 插入到 ZIPLIST
    if (entry->li->encoding == REDIS_ENCODING_ZIPLIST) {

        // 返回对象未编码的值
        value = getDecodedObject(value);

        if (where == REDIS_TAIL) {
            unsigned char *next = ziplistNext(subject->ptr,entry->zi);

            /* When we insert after the current element, but the current element
             * is the tail of the list, we need to do a push. */
            if (next == NULL) {
                // next 是表尾节点，push 新节点到表尾
                subject->ptr = ziplistPush(subject->ptr,value->ptr,sdslen(value->ptr),REDIS_TAIL);
            } else {
                // 插入到到节点之后
                subject->ptr = ziplistInsert(subject->ptr,next,value->ptr,sdslen(value->ptr));
            }
        } else {
            subject->ptr = ziplistInsert(subject->ptr,entry->zi,value->ptr,sdslen(value->ptr));
        }
        decrRefCount(value);

    // 插入到双端链表
    } else if (entry->li->encoding == REDIS_ENCODING_LINKEDLIST) {

        if (where == REDIS_TAIL) {
            listInsertNode(subject->ptr,entry->ln,value,AL_START_TAIL);
        } else {
            listInsertNode(subject->ptr,entry->ln,value,AL_START_HEAD);
        }

        incrRefCount(value);

    } else {
        redisPanic("Unknown list encoding");
    }
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %rbx
pushq %rax
movl %edx, %ebp
movq %rsi, %rbx
movq %rdi, %r14
movq (%rdi), %rax
movq (%rax), %r15
movzbl 0x8(%rax), %eax
cmpl $0x4, %eax
je 0x372be
cmpl $0x5, %eax
jne 0x3731b
movq %rbx, %rdi
callq 0x2f087
movq %rax, %rbx
movq 0x8(%r15), %rdi
movq 0x8(%r14), %rsi
cmpl $0x1, %ebp
jne 0x372e8
callq 0x2ae0d
movq 0x8(%r15), %rdi
movq 0x8(%rbx), %rdx
movl -0x8(%rdx), %ecx
testq %rax, %rax
je 0x3730a
movq %rax, %rsi
jmp 0x372ef
xorl %ecx, %ecx
cmpl $0x1, %ebp
sete %cl
movq 0x8(%r15), %rdi
movq 0x10(%r14), %rsi
movq %rbx, %rdx
callq 0x1feaa
movq %rbx, %rdi
addq $0x8, %rsp
popq %rbx
popq %r14
popq %r15
popq %rbp
jmp 0x2eacc
movq 0x8(%rbx), %rdx
movl -0x8(%rdx), %ecx
callq 0x2afb2
movq %rax, 0x8(%r15)
movq %rbx, %rdi
addq $0x8, %rsp
popq %rbx
popq %r14
popq %r15
popq %rbp
jmp 0x2ee1f
pushq $0x1
popq %rax
movq %rdx, %rsi
movl %ecx, %edx
movl %eax, %ecx
callq 0x2a889
jmp 0x372f4
leaq 0x57782(%rip), %rdi     # 0x8eaa4
leaq 0x57c49(%rip), %rsi     # 0x8ef72
movl $0x179, %edx            # imm = 0x179
callq 0x490e8
pushq $0x1
popq %rdi
callq 0x1f3b0
// File: /workspace/github_c_makefile_star2_O2/nilyang[P]redis-tdd-annotation/src/t_list.c
// Function: listTypeEqual
int listTypeEqual(listTypeEntry *entry, robj *o) {

    listTypeIterator *li = entry->li;

    if (li->encoding == REDIS_ENCODING_ZIPLIST) {
        redisAssertWithInfo(NULL,o,sdsEncodedObject(o));
        return ziplistCompare(entry->zi,o->ptr,sdslen(o->ptr));

    } else if (li->encoding == REDIS_ENCODING_LINKEDLIST) {
        return equalStringObjects(o,listNodeValue(entry->ln));

    } else {
        redisPanic("Unknown list encoding");
    }
}

// Assembly:
pushq %rax
movq (%rdi), %rax
movzbl 0x8(%rax), %eax
cmpl $0x4, %eax
je 0x37367
cmpl $0x5, %eax
jne 0x3737b
movl (%rsi), %eax
shrl $0x4, %eax
testb $0x7, %al
jne 0x37395
movq 0x8(%rdi), %rdi
movq 0x8(%rsi), %rsi
movl -0x8(%rsi), %edx
popq %rax
jmp 0x2b164
movq 0x10(%rdi), %rax
movq 0x10(%rax), %rax
movq %rsi, %rdi
movq %rax, %rsi
popq %rax
jmp 0x2f1f2
leaq 0x57722(%rip), %rdi     # 0x8eaa4
leaq 0x57be9(%rip), %rsi     # 0x8ef72
movl $0x18f, %edx            # imm = 0x18F
callq 0x490e8
jmp 0x373b0
leaq 0x57c29(%rip), %rdx     # 0x8efc5
leaq 0x57bcf(%rip), %rcx     # 0x8ef72
xorl %edi, %edi
movl $0x188, %r8d            # imm = 0x188
callq 0x4980c
pushq $0x1
popq %rdi
callq 0x1f3b0
// File: /workspace/github_c_makefile_star2_O2/nilyang[P]redis-tdd-annotation/src/t_list.c
// Function: listTypeDelete
void listTypeDelete(listTypeEntry *entry) {

    listTypeIterator *li = entry->li;

    // ZIPLIST
    if (li->encoding == REDIS_ENCODING_ZIPLIST) {

        unsigned char *p = entry->zi;

        li->subject->ptr = ziplistDelete(li->subject->ptr,&p);

        /* Update position of the iterator depending on the direction */
        // 删除节点之后，更新迭代器的指针
        if (li->direction == REDIS_TAIL)
            li->zi = p;
        else
            li->zi = ziplistPrev(li->subject->ptr,p);

    // 双端链表
    } else if (entry->li->encoding == REDIS_ENCODING_LINKEDLIST) {

        // 记录后置节点
        listNode *next;

        if (li->direction == REDIS_TAIL)
            next = entry->ln->next;
        else
            next = entry->ln->prev;

        // 删除当前节点
        listDelNode(li->subject->ptr,entry->ln);

        // 删除节点之后，更新迭代器的指针
        li->ln = next;

    } else {
        redisPanic("Unknown list encoding");
    }
}

// Assembly:
pushq %r14
pushq %rbx
pushq %rax
movq (%rdi), %r14
movzbl 0x8(%r14), %eax
cmpl $0x4, %eax
je 0x37409
cmpl $0x5, %eax
jne 0x37433
movq 0x8(%rdi), %rax
movq %rsp, %rbx
movq %rax, (%rbx)
movq (%r14), %rax
movq 0x8(%rax), %rdi
movq %rbx, %rsi
callq 0x2afb7
movq %rax, %rdi
movq (%r14), %rax
movq %rdi, 0x8(%rax)
cmpb $0x1, 0x9(%r14)
movq (%rbx), %rax
je 0x37403
movq %rax, %rsi
callq 0x2ae33
movq %rax, 0x10(%r14)
jmp 0x3742b
xorl %eax, %eax
cmpb $0x1, 0x9(%r14)
sete %al
movq 0x10(%rdi), %rsi
movq (%rsi,%rax,8), %rbx
movq (%r14), %rax
movq 0x8(%rax), %rdi
callq 0x1ff28
movq %rbx, 0x18(%r14)
addq $0x8, %rsp
popq %rbx
popq %r14
retq
leaq 0x5766a(%rip), %rdi     # 0x8eaa4
leaq 0x57b31(%rip), %rsi     # 0x8ef72
movl $0x1bb, %edx            # imm = 0x1BB
callq 0x490e8
pushq $0x1
popq %rdi
callq 0x1f3b0
// File: /workspace/github_c_makefile_star2_O2/nilyang[P]redis-tdd-annotation/src/t_list.c
// Function: pushGenericCommand
void pushGenericCommand(redisClient *c, int where) {

    int j, waiting = 0, pushed = 0;

    // 取出列表对象
    robj *lobj = lookupKeyWrite(c->db,c->argv[1]);

    // 如果列表对象不存在，那么可能有客户端在等待这个键的出现
    int may_have_waiting_clients = (lobj == NULL);

    if (lobj && lobj->type != REDIS_LIST) {
        addReply(c,shared.wrongtypeerr);
        return;
    }

    // 将列表状态设置为就绪
    if (may_have_waiting_clients) signalListAsReady(c,c->argv[1]);

    // 遍历所有输入值，并将它们添加到列表中
    for (j = 2; j < c->argc; j++) {

        // 编码值
        c->argv[j] = tryObjectEncoding(c->argv[j]);

        // 如果列表对象不存在，那么创建一个，并关联到数据库
        if (!lobj) {
            lobj = createZiplistObject();
            dbAdd(c->db,c->argv[1],lobj);
        }

        // 将值推入到列表
        listTypePush(lobj,c->argv[j],where);

        pushed++;
    }

    // 返回添加的节点数量
    addReplyLongLong(c, waiting + (lobj ? listTypeLength(lobj) : 0));

    // 如果至少有一个元素被成功推入，那么执行以下代码
    if (pushed) {
        char *event = (where == REDIS_HEAD) ? "lpush" : "rpush";

        // 发送键修改信号
        signalModifiedKey(c->db,c->argv[1]);

        // 发送事件通知
        notifyKeyspaceEvent(REDIS_NOTIFY_LIST,event,c->argv[1],c->db->id);
    }

    server.dirty += pushed;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %rbx
pushq %rax
movl %esi, %ebp
movq %rdi, %rbx
movq 0x8(%rdi), %rdi
movq 0x38(%rbx), %rax
movq 0x8(%rax), %rsi
callq 0x2f988
movq %rax, %r14
testq %rax, %rax
je 0x374a0
movl (%r14), %eax
andl $0xf, %eax
cmpl $0x1, %eax
je 0x374b0
leaq 0x90376(%rip), %rax     # 0xc7800
movq 0x70(%rax), %rsi
movq %rbx, %rdi
addq $0x8, %rsp
popq %rbx
popq %r14
popq %r15
popq %rbp
jmp 0x2c10d
movq 0x38(%rbx), %rax
movq 0x8(%rax), %rsi
movq %rbx, %rdi
callq 0x37589
xorl %r15d, %r15d
leaq 0x2(%r15), %rax
movslq 0x30(%rbx), %rcx
cmpq %rcx, %rax
jge 0x37510
movq 0x38(%rbx), %rax
movq 0x10(%rax,%r15,8), %rdi
callq 0x2ef4c
movq 0x38(%rbx), %rcx
movq %rax, 0x10(%rcx,%r15,8)
testq %r14, %r14
jne 0x374f8
callq 0x2ec07
movq %rax, %r14
movq 0x8(%rbx), %rdi
movq 0x38(%rbx), %rax
movq 0x8(%rax), %rsi
movq %r14, %rdx
callq 0x2fa09
movq 0x38(%rbx), %rax
movq 0x10(%rax,%r15,8), %rsi
movq %r14, %rdi
movl %ebp, %edx
callq 0x36e46
incq %r15
jmp 0x374b3
testq %r14, %r14
je 0x37522
movq %r14, %rdi
callq 0x3700e
movq %rax, %rsi
jmp 0x37524
xorl %esi, %esi
movq %rbx, %rdi
callq 0x2c794
testl %r15d, %r15d
je 0x37570
testl %ebp, %ebp
leaq 0x52dad(%rip), %rax     # 0x8a2e7
leaq 0x52d7c(%rip), %r14     # 0x8a2bd
cmoveq %rax, %r14
movq 0x8(%rbx), %rdi
movq 0x38(%rbx), %rax
movq 0x8(%rax), %rsi
callq 0x2fbc0
movq 0x8(%rbx), %rax
movq 0x38(%rbx), %rcx
movq 0x8(%rcx), %rdx
movl 0x30(%rax), %ecx
pushq $0x10
popq %rdi
movq %r14, %rsi
callq 0x5b488
leaq 0x8fa31(%rip), %rax     # 0xc6fa8
addq %r15, 0x560(%rax)
addq $0x8, %rsp
popq %rbx
popq %r14
popq %r15
popq %rbp
retq
// File: /workspace/github_c_makefile_star2_O2/nilyang[P]redis-tdd-annotation/src/t_list.c
// Function: signalListAsReady
void signalListAsReady(redisClient *c, robj *key) {
    readyList *rl;

    /* No clients blocking for this key? No need to queue it. */
    // 没有客户端被这个键阻塞，直接返回
    if (dictFind(c->db->blocking_keys,key) == NULL) return;

    /* Key was already signaled? No need to queue it again. */
    // 这个键已经被添加到 ready_keys 中了，直接返回
    if (dictFind(c->db->ready_keys,key) != NULL) return;

    /* Ok, we need to queue this key into server.ready_keys. */
    // 创建一个 readyList 结构，保存键和数据库
    // 然后将 readyList 添加到 server.ready_keys 中
    rl = zmalloc(sizeof(*rl));
    rl->key = key;
    rl->db = c->db;
    incrRefCount(key);
    listAddNodeTail(server.ready_keys,rl);

    /* We also add the key in the db->ready_keys dictionary in order
     * to avoid adding it multiple times into a list with a simple O(1)
     * check. 
     *
     * 将 key 添加到 c->db->ready_keys 集合中，防止重复添加
     */
    incrRefCount(key);
    redisAssert(dictAdd(c->db->ready_keys,key,NULL) == DICT_OK);
}

// Assembly:
pushq %r15
pushq %r14
pushq %rbx
movq %rsi, %rbx
movq %rdi, %r14
movq 0x8(%rdi), %rax
movq 0x10(%rax), %rdi
callq 0x21b64
testq %rax, %rax
je 0x3760d
movq 0x8(%r14), %rax
movq 0x18(%rax), %rdi
movq %rbx, %rsi
callq 0x21b64
testq %rax, %rax
jne 0x3760d
pushq $0x10
popq %rdi
callq 0x2828d
movq %rax, %r15
movq %rbx, 0x8(%rax)
movq 0x8(%r14), %rax
movq %rax, (%r15)
movq %rbx, %rdi
callq 0x2eacc
leaq 0x8f9c8(%rip), %rax     # 0xc6fa8
movq 0x740(%rax), %rdi
movq %r15, %rsi
callq 0x1fe4c
movq %rbx, %rdi
callq 0x2eacc
movq 0x8(%r14), %rax
movq 0x18(%rax), %rdi
movq %rbx, %rsi
xorl %edx, %edx
callq 0x21956
testl %eax, %eax
jne 0x37613
popq %rbx
popq %r14
popq %r15
retq
leaq 0x57a5b(%rip), %rdi     # 0x8f075
leaq 0x57951(%rip), %rsi     # 0x8ef72
movl $0x4f5, %edx            # imm = 0x4F5
callq 0x4906b
pushq $0x1
popq %rdi
callq 0x1f3b0
// File: /workspace/github_c_makefile_star2_O2/nilyang[P]redis-tdd-annotation/src/t_list.c
// Function: linsertCommand
void linsertCommand(redisClient *c) {

    // 编码 refval 对象
    c->argv[4] = tryObjectEncoding(c->argv[4]);

    if (strcasecmp(c->argv[2]->ptr,"after") == 0) {
        pushxGenericCommand(c,c->argv[3],c->argv[4],REDIS_TAIL);

    } else if (strcasecmp(c->argv[2]->ptr,"before") == 0) {
        pushxGenericCommand(c,c->argv[3],c->argv[4],REDIS_HEAD);

    } else {
        addReply(c,shared.syntaxerr);
    }
}

// Assembly:
pushq %r15
pushq %r14
pushq %rbx
movq %rdi, %rbx
movq 0x38(%rdi), %rax
movq 0x20(%rax), %rdi
callq 0x2ef4c
movq 0x38(%rbx), %rcx
movq %rax, 0x20(%rcx)
movq 0x38(%rbx), %r15
movq 0x10(%r15), %rax
movq 0x8(%rax), %r14
leaq 0x577a2(%rip), %rsi     # 0x8f013
movq %r14, %rdi
callq 0x1f2e0
testl %eax, %eax
je 0x378ab
leaq 0x57795(%rip), %rsi     # 0x8f019
movq %r14, %rdi
callq 0x1f2e0
testl %eax, %eax
je 0x378bb
leaq 0x8ff69(%rip), %rax     # 0xc7800
movq 0x80(%rax), %rsi
movq %rbx, %rdi
popq %rbx
popq %r14
popq %r15
jmp 0x2c10d
movq 0x18(%r15), %rsi
movq 0x20(%r15), %rdx
pushq $0x1
popq %rcx
movq %rbx, %rdi
jmp 0x378c8
movq 0x18(%r15), %rsi
movq 0x20(%r15), %rdx
movq %rbx, %rdi
xorl %ecx, %ecx
popq %rbx
popq %r14
popq %r15
jmp 0x37642
// File: /workspace/github_c_makefile_star2_O2/nilyang[P]redis-tdd-annotation/src/t_list.c
// Function: lindexCommand
void lindexCommand(redisClient *c) {

    robj *o = lookupKeyReadOrReply(c,c->argv[1],shared.nullbulk);

    if (o == NULL || checkType(c,o,REDIS_LIST)) return;
    long index;
    robj *value = NULL;

    // 取出整数值对象 index
    if ((getLongFromObjectOrReply(c, c->argv[2], &index, NULL) != REDIS_OK))
        return;

    // 根据索引，遍历 ziplist ，直到指定位置
    if (o->encoding == REDIS_ENCODING_ZIPLIST) {
        unsigned char *p;
        unsigned char *vstr;
        unsigned int vlen;
        long long vlong;

        p = ziplistIndex(o->ptr,index);

        if (ziplistGet(p,&vstr,&vlen,&vlong)) {
            if (vstr) {
                value = createStringObject((char*)vstr,vlen);
            } else {
                value = createStringObjectFromLongLong(vlong);
            }
            addReplyBulk(c,value);
            decrRefCount(value);
        } else {
            addReply(c,shared.nullbulk);
        }

    // 根据索引，遍历双端链表，直到指定位置
    } else if (o->encoding == REDIS_ENCODING_LINKEDLIST) {

        listNode *ln = listIndex(o->ptr,index);

        if (ln != NULL) {
            value = listNodeValue(ln);
            addReplyBulk(c,value);
        } else {
            addReply(c,shared.nullbulk);
        }
    } else {
        redisPanic("Unknown list encoding");
    }
}

// Assembly:
pushq %r15
pushq %r14
pushq %rbx
subq $0x20, %rsp
movq %rdi, %rbx
movq 0x38(%rdi), %rax
movq 0x8(%rax), %rsi
leaq 0x8feb8(%rip), %r15     # 0xc7800
movq 0x50(%r15), %rdx
callq 0x2f9a9
testq %rax, %rax
je 0x37986
movq %rax, %r14
pushq $0x1
popq %rdx
movq %rbx, %rdi
movq %rax, %rsi
callq 0x2eec6
testl %eax, %eax
jne 0x37986
movq 0x38(%rbx), %rax
movq 0x10(%rax), %rsi
leaq 0x8(%rsp), %rdx
movq %rbx, %rdi
xorl %ecx, %ecx
callq 0x2f672
testl %eax, %eax
je 0x37990
addq $0x20, %rsp
popq %rbx
popq %r14
popq %r15
retq
movl (%r14), %eax
shrl $0x4, %eax
andl $0xf, %eax
cmpl $0x4, %eax
je 0x379e4
cmpl $0x5, %eax
jne 0x37a3b
movq 0x8(%r14), %rdi
movl 0x8(%rsp), %esi
callq 0x2abfb
leaq 0x18(%rsp), %rsi
leaq 0x4(%rsp), %rdx
leaq 0x10(%rsp), %rcx
movq %rax, %rdi
callq 0x2aea9
testl %eax, %eax
je 0x37a05
movq 0x18(%rsp), %rdi
testq %rdi, %rdi
je 0x37a16
movl 0x4(%rsp), %esi
callq 0x2ea81
jmp 0x37a20
movq 0x8(%r14), %rdi
movq 0x8(%rsp), %rsi
callq 0x200c3
testq %rax, %rax
je 0x37a05
movq 0x10(%rax), %rsi
movq %rbx, %rdi
callq 0x2c84a
jmp 0x37986
movq 0x50(%r15), %rsi
movq %rbx, %rdi
callq 0x2c10d
jmp 0x37986
movq 0x10(%rsp), %rdi
callq 0x2ea90
movq %rax, %r14
movq %rbx, %rdi
movq %rax, %rsi
callq 0x2c84a
movq %r14, %rdi
callq 0x2ee1f
jmp 0x37986
leaq 0x57062(%rip), %rdi     # 0x8eaa4
leaq 0x57529(%rip), %rsi     # 0x8ef72
movl $0x2ba, %edx            # imm = 0x2BA
callq 0x490e8
pushq $0x1
popq %rdi
callq 0x1f3b0
// File: /workspace/github_c_makefile_star2_O2/nilyang[P]redis-tdd-annotation/src/t_list.c
// Function: popGenericCommand
void popGenericCommand(redisClient *c, int where) {

    // 取出列表对象
    robj *o = lookupKeyWriteOrReply(c,c->argv[1],shared.nullbulk);

    if (o == NULL || checkType(c,o,REDIS_LIST)) return;

    // 弹出列表元素
    robj *value = listTypePop(o,where);

    // 根据弹出元素是否为空，决定后续动作
    if (value == NULL) {
        addReply(c,shared.nullbulk);
    } else {
        char *event = (where == REDIS_HEAD) ? "lpop" : "rpop";

        addReplyBulk(c,value);
        decrRefCount(value);
        notifyKeyspaceEvent(REDIS_NOTIFY_LIST,event,c->argv[1],c->db->id);
        if (listTypeLength(o) == 0) {
            notifyKeyspaceEvent(REDIS_NOTIFY_GENERIC,"del",
                                c->argv[1],c->db->id);
            dbDelete(c->db,c->argv[1]);
        }
        signalModifiedKey(c->db,c->argv[1]);
        server.dirty++;
    }
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r12
pushq %rbx
movl %esi, %ebp
movq %rdi, %rbx
movq 0x38(%rdi), %rax
movq 0x8(%rax), %rsi
leaq 0x8fbda(%rip), %r12     # 0xc7800
movq 0x50(%r12), %rdx
callq 0x2f9d9
testq %rax, %rax
je 0x37d04
movq %rax, %r14
pushq $0x1
popq %rdx
movq %rbx, %rdi
movq %rax, %rsi
callq 0x2eec6
testl %eax, %eax
jne 0x37d04
movq %r14, %rdi
movl %ebp, %esi
callq 0x36f24
testq %rax, %rax
je 0x37d0d
movq %rax, %r15
testl %ebp, %ebp
leaq 0x52681(%rip), %rax     # 0x8a2f2
leaq 0x52662(%rip), %r12     # 0x8a2da
cmoveq %rax, %r12
movq %rbx, %rdi
movq %r15, %rsi
callq 0x2c84a
movq %r15, %rdi
callq 0x2ee1f
movq 0x8(%rbx), %rax
movq 0x38(%rbx), %rcx
movq 0x8(%rcx), %rdx
movl 0x30(%rax), %ecx
pushq $0x10
popq %rdi
movq %r12, %rsi
callq 0x5b488
movq %r14, %rdi
callq 0x3700e
testq %rax, %rax
jne 0x37ce5
movq 0x8(%rbx), %rax
movq 0x38(%rbx), %rcx
movq 0x8(%rcx), %rdx
movl 0x30(%rax), %ecx
leaq 0x527d1(%rip), %rsi     # 0x8a49d
pushq $0x4
popq %rdi
callq 0x5b488
movq 0x8(%rbx), %rdi
movq 0x38(%rbx), %rax
movq 0x8(%rax), %rsi
callq 0x2fc3b
movq 0x8(%rbx), %rdi
movq 0x38(%rbx), %rax
movq 0x8(%rax), %rsi
callq 0x2fbc0
leaq 0x8f2ab(%rip), %rax     # 0xc6fa8
incq 0x560(%rax)
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
retq
movq 0x50(%r12), %rsi
movq %rbx, %rdi
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
jmp 0x2c10d
// File: /workspace/github_c_makefile_star2_O2/nilyang[P]redis-tdd-annotation/src/t_list.c
// Function: rpoplpushHandlePush
void rpoplpushHandlePush(redisClient *c, robj *dstkey, robj *dstobj, robj *value) {
    /* Create the list if the key does not exist */
    // 如果目标列表不存在，那么创建一个
    if (!dstobj) {
        dstobj = createZiplistObject();
        dbAdd(c->db,dstkey,dstobj);
        signalListAsReady(c,dstkey);
    }

    signalModifiedKey(c->db,dstkey);

    // 将值推入目标列表中
    listTypePush(dstobj,value,REDIS_HEAD);

    notifyKeyspaceEvent(REDIS_NOTIFY_LIST,"lpush",dstkey,c->db->id);
    /* Always send the pushed value to the client. */
    addReplyBulk(c,value);
}

// Assembly:
pushq %r15
pushq %r14
pushq %r12
pushq %rbx
pushq %rax
movq %rcx, %rbx
movq %rdx, %r12
movq %rsi, %r15
movq %rdi, %r14
testq %rdx, %rdx
jne 0x382ff
callq 0x2ec07
movq %rax, %r12
movq 0x8(%r14), %rdi
movq %r15, %rsi
movq %rax, %rdx
callq 0x2fa09
movq %r14, %rdi
movq %r15, %rsi
callq 0x37589
movq 0x8(%r14), %rdi
movq %r15, %rsi
callq 0x2fbc0
movq %r12, %rdi
movq %rbx, %rsi
xorl %edx, %edx
callq 0x36e46
movq 0x8(%r14), %rax
movl 0x30(%rax), %ecx
leaq 0x51fc1(%rip), %rsi     # 0x8a2e7
pushq $0x10
popq %rdi
movq %r15, %rdx
callq 0x5b488
movq %r14, %rdi
movq %rbx, %rsi
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
jmp 0x2c84a
// File: /workspace/github_c_makefile_star2_O2/nilyang[P]redis-tdd-annotation/src/t_list.c
// Function: blockForKeys
void blockForKeys(redisClient *c, robj **keys, int numkeys, mstime_t timeout, robj *target) {
    dictEntry *de;
    list *l;
    int j;

    // 设置阻塞状态的超时和目标选项
    c->bpop.timeout = timeout;

    // target 在执行 RPOPLPUSH 命令时使用
    c->bpop.target = target;

    if (target != NULL) incrRefCount(target);

    // 关联阻塞客户端和键的相关信息
    for (j = 0; j < numkeys; j++) {

        /* If the key already exists in the dict ignore it. */
        // c->bpop.keys 是一个集合（值为 NULL 的字典）
        // 它记录所有造成客户端阻塞的键
        // 以下语句在键不存在于集合的时候，将它添加到集合
        if (dictAdd(c->bpop.keys,keys[j],NULL) != DICT_OK) continue;

        incrRefCount(keys[j]);

        /* And in the other "side", to map keys -> clients */
        // c->db->blocking_keys 字典的键为造成客户端阻塞的键
        // 而值则是一个链表，链表中包含了所有被阻塞的客户端
        // 以下程序将阻塞键和被阻塞客户端关联起来
        de = dictFind(c->db->blocking_keys,keys[j]);
        if (de == NULL) {
            // 链表不存在，新创建一个，并将它关联到字典中
            int retval;

            /* For every key we take a list of clients blocked for it */
            l = listCreate();
            retval = dictAdd(c->db->blocking_keys,keys[j],l);
            incrRefCount(keys[j]);
            redisAssertWithInfo(c,keys[j],retval == DICT_OK);
        } else {
            l = dictGetVal(de);
        }
        // 将客户端填接到被阻塞客户端的链表中
        listAddNodeTail(l,c);
    }
    blockClient(c,REDIS_BLOCKED_LIST);
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
pushq %rax
movl %edx, %r15d
movq %rsi, %r14
movq %rdi, %rbx
movq %rcx, 0x120(%rdi)
movq %r8, 0x130(%rdi)
testq %r8, %r8
je 0x384bd
movq %r8, %rdi
callq 0x2eacc
xorl %r13d, %r13d
testl %r15d, %r15d
cmovlel %r13d, %r15d
cmpq %r13, %r15
je 0x38542
movq 0x128(%rbx), %rdi
movq (%r14,%r13,8), %rsi
xorl %edx, %edx
callq 0x21956
testl %eax, %eax
jne 0x3853d
movq (%r14,%r13,8), %rdi
callq 0x2eacc
movq 0x8(%rbx), %rax
movq 0x10(%rax), %rdi
movq (%r14,%r13,8), %rsi
callq 0x21b64
testq %rax, %rax
je 0x38507
movq 0x8(%rax), %r12
jmp 0x38532
callq 0x1fd8c
movq %rax, %r12
movq 0x8(%rbx), %rax
movq 0x10(%rax), %rdi
movq (%r14,%r13,8), %rsi
movq %r12, %rdx
callq 0x21956
movl %eax, %ebp
movq (%r14,%r13,8), %rdi
callq 0x2eacc
testl %ebp, %ebp
jne 0x3855b
movq %r12, %rdi
movq %rbx, %rsi
callq 0x1fe4c
incq %r13
jmp 0x384c7
pushq $0x1
popq %rsi
movq %rbx, %rdi
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x5b9be
movq (%r14,%r13,8), %rsi
leaq 0x562b4(%rip), %rdx     # 0x8e81a
leaq 0x56a05(%rip), %rcx     # 0x8ef72
movq %rbx, %rdi
movl $0x498, %r8d            # imm = 0x498
callq 0x4980c
pushq $0x1
popq %rdi
callq 0x1f3b0
// File: /workspace/github_c_makefile_star2_O2/nilyang[P]redis-tdd-annotation/src/t_list.c
// Function: unblockClientWaitingData
void unblockClientWaitingData(redisClient *c) {
    dictEntry *de;
    dictIterator *di;
    list *l;

    redisAssertWithInfo(c,NULL,dictSize(c->bpop.keys) != 0);

    // 遍历所有 key ，将它们从客户端 db->blocking_keys 的链表中移除
    di = dictGetIterator(c->bpop.keys);
    /* The client may wait for multiple keys, so unblock it for every key. */
    while((de = dictNext(di)) != NULL) {
        robj *key = dictGetKey(de);

        /* Remove this client from the list of clients waiting for this key. */
        // 获取所有因为 key 而被阻塞的客户端的链表
        l = dictFetchValue(c->db->blocking_keys,key);

        redisAssertWithInfo(c,key,l != NULL);

        // 将指定客户端从链表中删除
        listDelNode(l,listSearchKey(l,c));

        /* If the list is empty we need to remove it to avoid wasting memory */
        // 如果已经没有其他客户端阻塞在这个 key 上，那么删除这个链表
        if (listLength(l) == 0)
            dictDelete(c->db->blocking_keys,key);
    }
    dictReleaseIterator(di);

    /* Cleanup the client structure */
    // 清空 bpop.keys 集合（字典）
    dictEmpty(c->bpop.keys,NULL);
    if (c->bpop.target) {
        decrRefCount(c->bpop.target);
        c->bpop.target = NULL;
    }
}

// Assembly:
pushq %r15
pushq %r14
pushq %r12
pushq %rbx
pushq %rax
movq %rdi, %rbx
movq 0x128(%rdi), %rdi
movq 0x28(%rdi), %rax
addq 0x48(%rdi), %rax
je 0x38665
callq 0x21ef6
movq %rax, %r14
movq %r14, %rdi
callq 0x21f2f
testq %rax, %rax
je 0x38603
movq (%rax), %r15
movq 0x8(%rbx), %rax
movq 0x10(%rax), %rdi
movq %r15, %rsi
callq 0x21e57
testq %rax, %rax
je 0x3863e
movq %rax, %r12
movq %rax, %rdi
movq %rbx, %rsi
callq 0x20066
movq %r12, %rdi
movq %rax, %rsi
callq 0x1ff28
cmpq $0x0, 0x28(%r12)
jne 0x385ab
movq 0x8(%rbx), %rax
movq 0x10(%rax), %rdi
movq %r15, %rsi
callq 0x21c36
jmp 0x385ab
movq %r14, %rdi
callq 0x21fe6
movq 0x128(%rbx), %rdi
xorl %esi, %esi
callq 0x2231b
movq 0x130(%rbx), %rdi
testq %rdi, %rdi
je 0x38632
callq 0x2ee1f
andq $0x0, 0x130(%rbx)
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
retq
leaq 0x56a26(%rip), %rdx     # 0x8f06b
leaq 0x56926(%rip), %rcx     # 0x8ef72
movq %rbx, %rdi
movq %r15, %rsi
movl $0x4b5, %r8d            # imm = 0x4B5
callq 0x4980c
pushq $0x1
popq %rdi
callq 0x1f3b0
leaq 0x569e3(%rip), %rdx     # 0x8f04f
leaq 0x568ff(%rip), %rcx     # 0x8ef72
movq %rbx, %rdi
xorl %esi, %esi
movl $0x4a9, %r8d            # imm = 0x4A9
jmp 0x38658
// File: /workspace/github_c_makefile_star2_O2/nilyang[P]redis-tdd-annotation/src/t_list.c
// Function: brpoplpushCommand
void brpoplpushCommand(redisClient *c) {
    mstime_t timeout;

    // 取出 timeout 参数
    if (getTimeoutFromObjectOrReply(c,c->argv[3],&timeout,UNIT_SECONDS)
        != REDIS_OK) return;

    // 取出列表键
    robj *key = lookupKeyWrite(c->db, c->argv[1]);

    // 键为空，阻塞
    if (key == NULL) {
        if (c->flags & REDIS_MULTI) {
            /* Blocking against an empty list in a multi state
             * returns immediately. */
            addReply(c, shared.nullbulk);
        } else {
            /* The list is empty and the client blocks. */
            blockForKeys(c, c->argv + 1, 1, timeout, c->argv[2]);
        }

    // 键非空，执行 RPOPLPUSH
    } else {
        if (key->type != REDIS_LIST) {
            addReply(c, shared.wrongtypeerr);
        } else {
            /* The list exists and has elements, so
             * the regular rpoplpushCommand is executed. */
            redisAssertWithInfo(c,key,listTypeLength(key) > 0);

            rpoplpushCommand(c);
        }
    }
}

// Assembly:
pushq %r14
pushq %rbx
pushq %rax
movq %rdi, %rbx
movq 0x38(%rdi), %rax
movq 0x18(%rax), %rsi
movq %rsp, %rdx
xorl %ecx, %ecx
callq 0x5b94c
testl %eax, %eax
jne 0x38c42
movq 0x8(%rbx), %rdi
movq 0x38(%rbx), %rax
movq 0x8(%rax), %rsi
callq 0x2f988
testq %rax, %rax
je 0x38bfc
movq %rax, %r14
movl (%rax), %eax
andl $0xf, %eax
cmpl $0x1, %eax
jne 0x38c22
movq %r14, %rdi
callq 0x3700e
testq %rax, %rax
je 0x38c4a
movq %rbx, %rdi
callq 0x38347
jmp 0x38c42
testb $0x8, 0x90(%rbx)
jne 0x38c2f
movq 0x38(%rbx), %rsi
movq (%rsp), %rcx
movq 0x10(%rsi), %r8
addq $0x8, %rsi
pushq $0x1
popq %rdx
movq %rbx, %rdi
callq 0x3848e
jmp 0x38c42
leaq 0x8ebd7(%rip), %rax     # 0xc7800
movq 0x70(%rax), %rsi
jmp 0x38c3a
leaq 0x8ebca(%rip), %rax     # 0xc7800
movq 0x50(%rax), %rsi
movq %rbx, %rdi
callq 0x2c10d
addq $0x8, %rsp
popq %rbx
popq %r14
retq
leaq 0x56461(%rip), %rdx     # 0x8f0b2
leaq 0x5631a(%rip), %rcx     # 0x8ef72
movq %rbx, %rdi
movq %r14, %rsi
movl $0x64e, %r8d            # imm = 0x64E
callq 0x4980c
pushq $0x1
popq %rdi
callq 0x1f3b0
nopl (%rax)