LLM4Binary/decompile-bench-makefile huggingface dataset:
// File: /workspace/github_c_makefile_star2_O1/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 0x9059d(%rip), %r15     # 0xca800
movq 0x50(%r15), %rdx
callq 0x31475
testq %rax, %rax
je 0x3a2a3
movq %rax, %r14
movq %rbx, %rdi
movq %rax, %rsi
movl $0x1, %edx
callq 0x308e7
testl %eax, %eax
jne 0x3a2a3
movq 0x38(%rbx), %rax
movq 0x10(%rax), %rsi
leaq 0x8(%rsp), %rdx
movq %rbx, %rdi
xorl %ecx, %ecx
callq 0x310df
testl %eax, %eax
je 0x3a2ad
addq $0x20, %rsp
popq %rbx
popq %r14
popq %r15
retq
movl (%r14), %eax
shrl $0x4, %eax
andl $0xf, %eax
cmpl $0x4, %eax
je 0x3a301
cmpl $0x5, %eax
jne 0x3a358
movq 0x8(%r14), %rdi
movl 0x8(%rsp), %esi
callq 0x2bff5
leaq 0x18(%rsp), %rsi
leaq 0x4(%rsp), %rdx
leaq 0x10(%rsp), %rcx
movq %rax, %rdi
callq 0x2c351
testl %eax, %eax
je 0x3a322
movq 0x18(%rsp), %rdi
testq %rdi, %rdi
je 0x3a333
movl 0x4(%rsp), %esi
callq 0x303b7
jmp 0x3a33d
movq 0x8(%r14), %rdi
movq 0x8(%rsp), %rsi
callq 0x20750
testq %rax, %rax
je 0x3a322
movq 0x10(%rax), %rsi
movq %rbx, %rdi
callq 0x2df74
jmp 0x3a2a3
movq 0x50(%r15), %rsi
movq %rbx, %rdi
callq 0x2d6f0
jmp 0x3a2a3
movq 0x10(%rsp), %rdi
callq 0x303c6
movq %rax, %r14
movq %rbx, %rdi
movq %rax, %rsi
callq 0x2df74
movq %r14, %rdi
callq 0x30834
jmp 0x3a2a3
leaq 0x5e725(%rip), %rdi     # 0x98a84
leaq 0x5ebff(%rip), %rsi     # 0x98f65
movl $0x2ba, %edx            # imm = 0x2BA
callq 0x4d0e5
movl $0x1, %edi
callq 0x1f3b0
// File: /workspace/github_c_makefile_star2_O1/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 0x902b5(%rip), %r12     # 0xca800
movq 0x50(%r12), %rdx
callq 0x314a5
testq %rax, %rax
je 0x3a62f
movq %rax, %r14
movq %rbx, %rdi
movq %rax, %rsi
movl $0x1, %edx
callq 0x308e7
testl %eax, %eax
jne 0x3a62f
movq %r14, %rdi
movl %ebp, %esi
callq 0x397fd
testq %rax, %rax
je 0x3a638
movq %rax, %r15
testl %ebp, %ebp
leaq 0x59d4a(%rip), %rax     # 0x942e2
leaq 0x59d2b(%rip), %r12     # 0x942ca
cmoveq %rax, %r12
movq %rbx, %rdi
movq %r15, %rsi
callq 0x2df74
movq %r15, %rdi
callq 0x30834
movq 0x8(%rbx), %rax
movq 0x38(%rbx), %rcx
movq 0x8(%rcx), %rdx
movl 0x30(%rax), %ecx
movl $0x10, %edi
movq %r12, %rsi
callq 0x608b5
movq %r14, %rdi
callq 0x398e9
testq %rax, %rax
jne 0x3a610
movq 0x8(%rbx), %rax
movq 0x38(%rbx), %rcx
movq 0x8(%rcx), %rdx
movl 0x30(%rax), %ecx
leaq 0x59e98(%rip), %rsi     # 0x9448d
movl $0x4, %edi
callq 0x608b5
movq 0x8(%rbx), %rdi
movq 0x38(%rbx), %rax
movq 0x8(%rax), %rsi
callq 0x3174b
movq 0x8(%rbx), %rdi
movq 0x38(%rbx), %rax
movq 0x8(%rax), %rsi
callq 0x316b7
leaq 0x8f980(%rip), %rax     # 0xc9fa8
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 0x2d6f0
// File: /workspace/github_c_makefile_star2_O1/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 0x3ac7b
callq 0x30591
movq %rax, %r12
movq 0x8(%r14), %rdi
movq %r15, %rsi
movq %rax, %rdx
callq 0x314ef
movq %r14, %rdi
movq %r15, %rsi
callq 0x39e90
movq 0x8(%r14), %rdi
movq %r15, %rsi
callq 0x316b7
movq %r12, %rdi
movq %rbx, %rsi
xorl %edx, %edx
callq 0x39719
movq 0x8(%r14), %rax
movl 0x30(%rax), %ecx
leaq 0x59635(%rip), %rsi     # 0x942d7
movl $0x10, %edi
movq %r15, %rdx
callq 0x608b5
movq %r14, %rdi
movq %rbx, %rsi
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
jmp 0x2df74
// File: /workspace/github_c_makefile_star2_O1/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, %ebp
movq %rsi, %r14
movq %rdi, %rbx
movq %rcx, 0x120(%rdi)
movq %r8, 0x130(%rdi)
testq %r8, %r8
je 0x3ae44
movq %r8, %rdi
callq 0x3041b
testl %ebp, %ebp
jle 0x3aec7
movl %ebp, %r12d
xorl %r13d, %r13d
movq 0x128(%rbx), %rdi
movq (%r14,%r13,8), %rsi
xorl %edx, %edx
callq 0x222b6
testl %eax, %eax
jne 0x3aebf
movq (%r14,%r13,8), %rdi
callq 0x3041b
movq 0x8(%rbx), %rax
movq 0x10(%rax), %rdi
movq (%r14,%r13,8), %rsi
callq 0x224dc
testq %rax, %rax
je 0x3ae89
movq 0x8(%rax), %r15
jmp 0x3aeb4
callq 0x2038c
movq %rax, %r15
movq 0x8(%rbx), %rax
movq 0x10(%rax), %rdi
movq (%r14,%r13,8), %rsi
movq %r15, %rdx
callq 0x222b6
movl %eax, %ebp
movq (%r14,%r13,8), %rdi
callq 0x3041b
testl %ebp, %ebp
jne 0x3aee2
movq %r15, %rdi
movq %rbx, %rsi
callq 0x2045f
incq %r13
cmpq %r13, %r12
jne 0x3ae4e
movq %rbx, %rdi
movl $0x1, %esi
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x60dec
movq (%r14,%r13,8), %rsi
leaq 0x5d8f9(%rip), %rdx     # 0x987e6
leaq 0x5e071(%rip), %rcx     # 0x98f65
movq %rbx, %rdi
movl $0x498, %r8d            # imm = 0x498
callq 0x4d872
movl $0x1, %edi
callq 0x1f3b0
// File: /workspace/github_c_makefile_star2_O1/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 0x3aff6
callq 0x228b5
movq %rax, %r14
movq %rax, %rdi
callq 0x22913
testq %rax, %rax
je 0x3af8f
movq (%rax), %r15
movq 0x8(%rbx), %rax
movq 0x10(%rax), %rdi
movq %r15, %rsi
callq 0x22813
testq %rax, %rax
je 0x3afcd
movq %rax, %r12
movq %rax, %rdi
movq %rbx, %rsi
callq 0x206d5
movq %r12, %rdi
movq %rax, %rsi
callq 0x20544
cmpq $0x0, 0x28(%r12)
jne 0x3af8a
movq 0x8(%rbx), %rax
movq 0x10(%rax), %rdi
movq %r15, %rsi
callq 0x225d3
movq %r14, %rdi
jmp 0x3af37
movq %r14, %rdi
callq 0x229b9
movq 0x128(%rbx), %rdi
xorl %esi, %esi
callq 0x22d54
movq 0x130(%rbx), %rdi
testq %rdi, %rdi
je 0x3afc1
callq 0x30834
movq $0x0, 0x130(%rbx)
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
retq
leaq 0x5e08a(%rip), %rdx     # 0x9905e
leaq 0x5df8a(%rip), %rcx     # 0x98f65
movq %rbx, %rdi
movq %r15, %rsi
movl $0x4b5, %r8d            # imm = 0x4B5
callq 0x4d872
movl $0x1, %edi
callq 0x1f3b0
leaq 0x5e045(%rip), %rdx     # 0x99042
leaq 0x5df61(%rip), %rcx     # 0x98f65
movq %rbx, %rdi
xorl %esi, %esi
movl $0x4a9, %r8d            # imm = 0x4A9
jmp 0x3afe7
// File: /workspace/github_c_makefile_star2_O1/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 0x60d78
testl %eax, %eax
jne 0x3b628
movq 0x8(%rbx), %rdi
movq 0x38(%rbx), %rax
movq 0x8(%rax), %rsi
callq 0x31454
testq %rax, %rax
je 0x3b5e0
movq %rax, %r14
movl (%rax), %eax
andl $0xf, %eax
cmpl $0x1, %eax
jne 0x3b608
movq %r14, %rdi
callq 0x398e9
testq %rax, %rax
je 0x3b630
movq %rbx, %rdi
callq 0x3acc5
jmp 0x3b628
testb $0x8, 0x90(%rbx)
jne 0x3b615
movq 0x38(%rbx), %rsi
movq (%rsp), %rcx
movq 0x10(%rsi), %r8
addq $0x8, %rsi
movq %rbx, %rdi
movl $0x1, %edx
callq 0x3ae16
jmp 0x3b628
leaq 0x8f1f1(%rip), %rax     # 0xca800
movq 0x70(%rax), %rsi
jmp 0x3b620
leaq 0x8f1e4(%rip), %rax     # 0xca800
movq 0x50(%rax), %rsi
movq %rbx, %rdi
callq 0x2d6f0
addq $0x8, %rsp
popq %rbx
popq %r14
retq
leaq 0x5da6e(%rip), %rdx     # 0x990a5
leaq 0x5d927(%rip), %rcx     # 0x98f65
movq %rbx, %rdi
movq %r14, %rsi
movl $0x64e, %r8d            # imm = 0x64E
callq 0x4d872
movl $0x1, %edi
callq 0x1f3b0
nopl (%rax)
// File: /workspace/github_c_makefile_star2_O1/nilyang[P]redis-tdd-annotation/src/t_set.c
// Function: setTypeAdd
int setTypeAdd(robj *subject, robj *value) {
    long long llval;

    // 字典
    if (subject->encoding == REDIS_ENCODING_HT) {
        // 将 value 作为键， NULL 作为值，将元素添加到字典中
        if (dictAdd(subject->ptr,value,NULL) == DICT_OK) {
            incrRefCount(value);
            return 1;
        }

    // intset
    } else if (subject->encoding == REDIS_ENCODING_INTSET) {
        
        // 如果对象的值可以编码为整数的话，那么将对象的值添加到 intset 中
        if (isObjectRepresentableAsLongLong(value,&llval) == REDIS_OK) {
            uint8_t success = 0;
            subject->ptr = intsetAdd(subject->ptr,llval,&success);
            if (success) {
                /* Convert to regular set when the intset contains
                 * too many entries. */
                // 添加成功
                // 检查集合在添加新元素之后是否需要转换为字典
                if (intsetLen(subject->ptr) > server.set_max_intset_entries)
                    setTypeConvert(subject,REDIS_ENCODING_HT);
                return 1;
            }

        // 如果对象的值不能编码为整数，那么将集合从 intset 编码转换为 HT 编码
        // 然后再执行添加操作
        } else {
            /* Failed to get integer from object, convert to regular set. */
            setTypeConvert(subject,REDIS_ENCODING_HT);

            /* The set *was* an intset and this value is not integer
             * encodable, so dictAdd should always work. */
            redisAssertWithInfo(NULL,value,dictAdd(subject->ptr,value,NULL) == DICT_OK);
            incrRefCount(value);
            return 1;
        }

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

    // 添加失败，元素已经存在
    return 0;
}

// Assembly:
pushq %r14
pushq %rbx
subq $0x18, %rsp
movq %rsi, %rbx
movq %rdi, %r14
movl (%rdi), %eax
shrl $0x4, %eax
andl $0xf, %eax
cmpl $0x6, %eax
je 0x3b6ae
cmpl $0x2, %eax
jne 0x3b74b
movq 0x8(%r14), %rdi
xorl %r14d, %r14d
movq %rbx, %rsi
xorl %edx, %edx
callq 0x222b6
testl %eax, %eax
jne 0x3b6f0
jmp 0x3b6e2
leaq 0x10(%rsp), %rsi
movq %rbx, %rdi
callq 0x3090d
testl %eax, %eax
je 0x3b6fb
movq %r14, %rdi
movl $0x2, %esi
callq 0x3b78d
movq 0x8(%r14), %rdi
movq %rbx, %rsi
xorl %edx, %edx
callq 0x222b6
testl %eax, %eax
jne 0x3b765
movq %rbx, %rdi
callq 0x3041b
movl $0x1, %r14d
movl %r14d, %eax
addq $0x18, %rsp
popq %rbx
popq %r14
retq
leaq 0xf(%rsp), %rbx
movb $0x0, (%rbx)
movq 0x8(%r14), %rdi
movq 0x10(%rsp), %rsi
movq %rbx, %rdx
callq 0x4f5d4
movq %rax, 0x8(%r14)
cmpb $0x0, (%rbx)
je 0x3b746
movq %rax, %rdi
callq 0x4fa0e
movl %eax, %eax
leaq 0x8e87a(%rip), %rcx     # 0xc9fa8
cmpq %rax, 0x778(%rcx)
jae 0x3b6ea
movq %r14, %rdi
movl $0x2, %esi
callq 0x3b78d
jmp 0x3b6ea
xorl %r14d, %r14d
jmp 0x3b6f0
leaq 0x5d34a(%rip), %rdi     # 0x98a9c
leaq 0x5d990(%rip), %rsi     # 0x990e9
movl $0x68, %edx
callq 0x4d0e5
jmp 0x3b783
leaq 0x5d951(%rip), %rdx     # 0x990bd
leaq 0x5d976(%rip), %rcx     # 0x990e9
xorl %edi, %edi
movq %rbx, %rsi
movl $0x61, %r8d
callq 0x4d872
movl $0x1, %edi
callq 0x1f3b0
// File: /workspace/github_c_makefile_star2_O1/nilyang[P]redis-tdd-annotation/src/t_set.c
// Function: setTypeConvert
void setTypeConvert(robj *setobj, int enc) {

    setTypeIterator *si;

    // 确认类型和编码正确
    redisAssertWithInfo(NULL,setobj,setobj->type == REDIS_SET &&
                             setobj->encoding == REDIS_ENCODING_INTSET);

    if (enc == REDIS_ENCODING_HT) {
        int64_t intele;
        // 创建新字典
        dict *d = dictCreate(&setDictType,NULL);
        robj *element;

        /* Presize the dict to avoid rehashing */
        // 预先扩展空间
        dictExpand(d,intsetLen(setobj->ptr));

        /* To add the elements we extract integers and create redis objects */
        // 遍历集合，并将元素添加到字典中
        si = setTypeInitIterator(setobj);
        while (setTypeNext(si,NULL,&intele) != -1) {
            element = createStringObjectFromLongLong(intele);
            redisAssertWithInfo(NULL,element,dictAdd(d,element,NULL) == DICT_OK);
        }
        setTypeReleaseIterator(si);

        // 更新集合的编码
        setobj->encoding = REDIS_ENCODING_HT;
        zfree(setobj->ptr);
        // 更新集合的值对象
        setobj->ptr = d;
    } else {
        redisPanic("Unsupported set conversion");
    }
}

// Assembly:
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x10, %rsp
movq %rdi, %rbx
cmpb $0x62, (%rdi)
jne 0x3b86a
cmpl $0x2, %esi
jne 0x3b885
leaq 0x8e0ba(%rip), %rdi     # 0xc9870
xorl %esi, %esi
callq 0x21f97
movq %rax, %r14
movq 0x8(%rbx), %rdi
callq 0x4fa0e
movl %eax, %esi
movq %r14, %rdi
callq 0x21ffe
movq %rbx, %rdi
callq 0x3b9ce
movq %rax, %r15
leaq 0x8(%rsp), %r12
movq %r15, %rdi
xorl %esi, %esi
movq %r12, %rdx
callq 0x3ba5a
cmpl $-0x1, %eax
je 0x3b83b
movq 0x8(%rsp), %rdi
callq 0x303c6
movq %rax, %r13
movq %r14, %rdi
movq %rax, %rsi
xorl %edx, %edx
callq 0x222b6
testl %eax, %eax
je 0x3b7e3
leaq 0x5d935(%rip), %rdx     # 0x9914f
leaq 0x5d8c8(%rip), %rcx     # 0x990e9
xorl %edi, %edi
movq %r13, %rsi
movl $0x18e, %r8d            # imm = 0x18E
callq 0x4d872
movl $0x1, %edi
callq 0x1f3b0
movq %r15, %rdi
callq 0x3ba3e
movl $0xffffff0f, %eax       # imm = 0xFFFFFF0F
andl (%rbx), %eax
orl $0x20, %eax
movl %eax, (%rbx)
movq 0x8(%rbx), %rdi
callq 0x2984b
movq %r14, 0x8(%rbx)
addq $0x10, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
retq
leaq 0x5d897(%rip), %rdx     # 0x99108
leaq 0x5d871(%rip), %rcx     # 0x990e9
xorl %edi, %edi
movq %rbx, %rsi
movl $0x17d, %r8d            # imm = 0x17D
jmp 0x3b82c
leaq 0x5d8e6(%rip), %rdi     # 0x99172
leaq 0x5d856(%rip), %rsi     # 0x990e9
movl $0x198, %edx            # imm = 0x198
callq 0x4d0e5
jmp 0x3b831
// File: /workspace/github_c_makefile_star2_O1/nilyang[P]redis-tdd-annotation/src/t_set.c
// Function: setTypeRemove
int setTypeRemove(robj *setobj, robj *value) {
    long long llval;

    // HT
    if (setobj->encoding == REDIS_ENCODING_HT) {
        // 从字典中删除键（集合元素）
        if (dictDelete(setobj->ptr,value) == DICT_OK) {
            // 看是否有必要在删除之后缩小字典的大小
            if (htNeedsResize(setobj->ptr)) dictResize(setobj->ptr);
            return 1;
        }

    // INTSET
    } else if (setobj->encoding == REDIS_ENCODING_INTSET) {
        // 如果对象的值可以编码为整数的话，那么尝试从 intset 中移除元素
        if (isObjectRepresentableAsLongLong(value,&llval) == REDIS_OK) {
            int success;
            setobj->ptr = intsetRemove(setobj->ptr,llval,&success);
            if (success) return 1;
        }

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

    // 删除失败
    return 0;
}

// Assembly:
pushq %rbp
pushq %r14
pushq %rbx
subq $0x10, %rsp
movq %rdi, %rbx
movl (%rdi), %eax
shrl $0x4, %eax
andl $0xf, %eax
cmpl $0x6, %eax
je 0x3b8e6
cmpl $0x2, %eax
jne 0x3b92b
movq 0x8(%rbx), %rdi
callq 0x225d3
testl %eax, %eax
jne 0x3b8f8
movq 0x8(%rbx), %rdi
callq 0x2347e
movl $0x1, %ebp
testl %eax, %eax
je 0x3b8fa
movq 0x8(%rbx), %rdi
callq 0x21fd6
jmp 0x3b8fa
movq %rsp, %rax
movq %rsi, %rdi
movq %rax, %rsi
callq 0x3090d
testl %eax, %eax
je 0x3b905
xorl %ebp, %ebp
movl %ebp, %eax
addq $0x10, %rsp
popq %rbx
popq %r14
popq %rbp
retq
movq 0x8(%rbx), %rdi
movq (%rsp), %rsi
leaq 0xc(%rsp), %r14
movq %r14, %rdx
callq 0x4f894
movq %rax, 0x8(%rbx)
cmpl $0x0, (%r14)
movl $0x1, %ebp
jne 0x3b8fa
jmp 0x3b8f8
leaq 0x5d16a(%rip), %rdi     # 0x98a9c
leaq 0x5d7b0(%rip), %rsi     # 0x990e9
movl $0x8b, %edx
callq 0x4d0e5
movl $0x1, %edi
callq 0x1f3b0
// File: /workspace/github_c_makefile_star2_O1/nilyang[P]redis-tdd-annotation/src/t_set.c
// Function: setTypeIsMember
int setTypeIsMember(robj *subject, robj *value) {
    long long llval;

    // HT
    if (subject->encoding == REDIS_ENCODING_HT) {
        return dictFind((dict*)subject->ptr,value) != NULL;

    // INTSET
    } else if (subject->encoding == REDIS_ENCODING_INTSET) {
        if (isObjectRepresentableAsLongLong(value,&llval) == REDIS_OK) {
            return intsetFind((intset*)subject->ptr,llval);
        }

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

    // 查找失败
    return 0;
}

// Assembly:
pushq %rbx
subq $0x10, %rsp
movq %rdi, %rbx
movl (%rdi), %eax
shrl $0x4, %eax
andl $0xf, %eax
cmpl $0x6, %eax
je 0x3b97d
cmpl $0x2, %eax
jne 0x3b9ac
movq 0x8(%rbx), %rdi
callq 0x224dc
movq %rax, %rcx
xorl %eax, %eax
testq %rcx, %rcx
setne %al
jmp 0x3b9a6
leaq 0x8(%rsp), %rax
movq %rsi, %rdi
movq %rax, %rsi
callq 0x3090d
movl %eax, %ecx
xorl %eax, %eax
testl %ecx, %ecx
jne 0x3b9a6
movq 0x8(%rbx), %rdi
movq 0x8(%rsp), %rsi
callq 0x4f97c
movzbl %al, %eax
addq $0x10, %rsp
popq %rbx
retq
leaq 0x5d0e9(%rip), %rdi     # 0x98a9c
leaq 0x5d72f(%rip), %rsi     # 0x990e9
movl $0xa4, %edx
callq 0x4d0e5
movl $0x1, %edi
callq 0x1f3b0
// File: /workspace/github_c_makefile_star2_O1/nilyang[P]redis-tdd-annotation/src/t_set.c
// Function: setTypeInitIterator
setTypeIterator *setTypeInitIterator(robj *subject) {

    setTypeIterator *si = zmalloc(sizeof(setTypeIterator));
    
    // 指向被迭代的对象
    si->subject = subject;

    // 记录对象的编码
    si->encoding = subject->encoding;

    // HT
    if (si->encoding == REDIS_ENCODING_HT) {
        // 字典迭代器
        si->di = dictGetIterator(subject->ptr);

    // INTSET
    } else if (si->encoding == REDIS_ENCODING_INTSET) {
        // 索引
        si->ii = 0;

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

    // 返回迭代器
    return si;
}

// Assembly:
pushq %r14
pushq %rbx
pushq %rax
movq %rdi, %r14
movl $0x18, %edi
callq 0x29709
movq %rax, %rbx
movq %r14, (%rax)
movl (%r14), %eax
shrl $0x4, %eax
andl $0xf, %eax
movl %eax, 0x8(%rbx)
cmpl $0x6, %eax
je 0x3ba0a
cmpl $0x2, %eax
jne 0x3ba1c
movq 0x8(%r14), %rdi
callq 0x228b5
movq %rax, 0x10(%rbx)
jmp 0x3ba11
movl $0x0, 0xc(%rbx)
movq %rbx, %rax
addq $0x8, %rsp
popq %rbx
popq %r14
retq
leaq 0x5d079(%rip), %rdi     # 0x98a9c
leaq 0x5d6bf(%rip), %rsi     # 0x990e9
movl $0xc6, %edx
callq 0x4d0e5
movl $0x1, %edi
callq 0x1f3b0
// File: /workspace/github_c_makefile_star2_O1/nilyang[P]redis-tdd-annotation/src/t_set.c
// Function: setTypeNext
int setTypeNext(setTypeIterator *si, robj **objele, int64_t *llele) {

    // 从字典中取出对象
    if (si->encoding == REDIS_ENCODING_HT) {

        // 更新迭代器
        dictEntry *de = dictNext(si->di);

        // 字典已迭代完
        if (de == NULL) return -1;

        // 返回节点的键（集合的元素）
        *objele = dictGetKey(de);

    // 从 intset 中取出元素
    } else if (si->encoding == REDIS_ENCODING_INTSET) {
        if (!intsetGet(si->subject->ptr,si->ii++,llele))
            return -1;
    }

    // 返回编码
    return si->encoding;
}

// Assembly:
pushq %r14
pushq %rbx
pushq %rax
movq %rdi, %rbx
movl 0x8(%rdi), %eax
cmpl $0x6, %eax
je 0x3ba87
cmpl $0x2, %eax
jne 0x3baa0
movq %rsi, %r14
movq 0x10(%rbx), %rdi
callq 0x22913
testq %rax, %rax
je 0x3baa5
movq (%rax), %rax
movq %rax, (%r14)
jmp 0x3baa0
movq (%rbx), %rax
movq 0x8(%rax), %rdi
movl 0xc(%rbx), %esi
leal 0x1(%rsi), %eax
movl %eax, 0xc(%rbx)
callq 0x4f9dc
testb %al, %al
je 0x3baa5
movl 0x8(%rbx), %eax
jmp 0x3baaa
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
addq $0x8, %rsp
popq %rbx
popq %r14
retq
// File: /workspace/github_c_makefile_star2_O1/nilyang[P]redis-tdd-annotation/src/t_set.c
// Function: setTypeNextObject
robj *setTypeNextObject(setTypeIterator *si) {
    int64_t intele;
    robj *objele;
    int encoding;

    // 取出元素
    encoding = setTypeNext(si,&objele,&intele);
    // 总是为元素创建对象
    switch(encoding) {
        // 已为空
        case -1:    return NULL;
        // INTSET 返回一个整数值，需要为这个值创建对象
        case REDIS_ENCODING_INTSET:
            return createStringObjectFromLongLong(intele);
        // HT 本身已经返回对象了，只需执行 incrRefCount()
        case REDIS_ENCODING_HT:
            incrRefCount(objele);
            return objele;
        default:
            redisPanic("Unsupported encoding");
    }

    return NULL; /* just to suppress warnings */
}

// Assembly:
pushq %rbx
subq $0x10, %rsp
movq %rsp, %rsi
leaq 0x8(%rsp), %rdx
callq 0x3ba5a
cmpl $-0x1, %eax
je 0x3baf0
cmpl $0x2, %eax
je 0x3bae2
cmpl $0x6, %eax
jne 0x3bafb
movq 0x8(%rsp), %rdi
callq 0x303c6
movq %rax, %rbx
jmp 0x3baf2
movq (%rsp), %rbx
movq %rbx, %rdi
callq 0x3041b
jmp 0x3baf2
xorl %ebx, %ebx
movq %rbx, %rax
addq $0x10, %rsp
popq %rbx
retq
leaq 0x5d5ef(%rip), %rdi     # 0x990f1
leaq 0x5d5e0(%rip), %rsi     # 0x990e9
movl $0x12f, %edx            # imm = 0x12F
callq 0x4d0e5
movl $0x1, %edi
callq 0x1f3b0
// File: /workspace/github_c_makefile_star2_O1/nilyang[P]redis-tdd-annotation/src/t_set.c
// Function: setTypeRandomElement
int setTypeRandomElement(robj *setobj, robj **objele, int64_t *llele) {

    if (setobj->encoding == REDIS_ENCODING_HT) {
        dictEntry *de = dictGetRandomKey(setobj->ptr);
        *objele = dictGetKey(de);

    } else if (setobj->encoding == REDIS_ENCODING_INTSET) {
        *llele = intsetRandom(setobj->ptr);

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

    return setobj->encoding;
}

// Assembly:
pushq %r15
pushq %r14
pushq %rbx
movq %rdi, %rbx
movl (%rdi), %eax
shrl $0x4, %eax
andl $0xf, %eax
cmpl $0x6, %eax
je 0x3bb4b
cmpl $0x2, %eax
jne 0x3bb68
movq %rsi, %r14
movq 0x8(%rbx), %rdi
callq 0x22a1c
movq (%rax), %rax
movq %rax, (%r14)
jmp 0x3bb5a
movq %rdx, %r15
movq 0x8(%rbx), %rdi
callq 0x4f9a8
movq %rax, (%r15)
movl (%rbx), %eax
shrl $0x4, %eax
andl $0xf, %eax
popq %rbx
popq %r14
popq %r15
retq
leaq 0x5cf2d(%rip), %rdi     # 0x98a9c
leaq 0x5d573(%rip), %rsi     # 0x990e9
movl $0x158, %edx            # imm = 0x158
callq 0x4d0e5
movl $0x1, %edi
callq 0x1f3b0
// File: /workspace/github_c_makefile_star2_O1/nilyang[P]redis-tdd-annotation/src/t_set.c
// Function: setTypeSize
unsigned long setTypeSize(robj *subject) {

    if (subject->encoding == REDIS_ENCODING_HT) {
        return dictSize((dict*)subject->ptr);

    } else if (subject->encoding == REDIS_ENCODING_INTSET) {
        return intsetLen((intset*)subject->ptr);

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

// Assembly:
pushq %rax
movl (%rdi), %eax
shrl $0x4, %eax
andl $0xf, %eax
cmpl $0x6, %eax
je 0x3bbab
cmpl $0x2, %eax
jne 0x3bbb8
movq 0x8(%rdi), %rcx
movq 0x48(%rcx), %rax
addq 0x28(%rcx), %rax
jmp 0x3bbb6
movq 0x8(%rdi), %rdi
callq 0x4fa0e
movl %eax, %eax
popq %rcx
retq
leaq 0x5cedd(%rip), %rdi     # 0x98a9c
leaq 0x5d523(%rip), %rsi     # 0x990e9
movl $0x16a, %edx            # imm = 0x16A
callq 0x4d0e5
movl $0x1, %edi
callq 0x1f3b0
// File: /workspace/github_c_makefile_star2_O1/nilyang[P]redis-tdd-annotation/src/t_set.c
// Function: saddCommand
void saddCommand(redisClient *c) {
    robj *set;
    int j, added = 0;

    // 取出集合对象
    set = lookupKeyWrite(c->db,c->argv[1]);

    // 对象不存在，创建一个新的，并将它关联到数据库
    if (set == NULL) {
        set = setTypeCreate(c->argv[2]);
        dbAdd(c->db,c->argv[1],set);

    // 对象存在，检查类型
    } else {
        if (set->type != REDIS_SET) {
            addReply(c,shared.wrongtypeerr);
            return;
        }
    }

    // 将所有输入元素添加到集合中
    for (j = 2; j < c->argc; j++) {
        c->argv[j] = tryObjectEncoding(c->argv[j]);
        // 只有元素未存在于集合时，才算一次成功添加
        if (setTypeAdd(set,c->argv[j])) added++;
    }

    // 如果有至少一个元素被成功添加，那么执行以下程序
    if (added) {
        // 发送键修改信号
        signalModifiedKey(c->db,c->argv[1]);
        // 发送事件通知
        notifyKeyspaceEvent(REDIS_NOTIFY_SET,"sadd",c->argv[1],c->db->id);
    }

    // 将数据库设为脏
    server.dirty += added;

    // 返回添加元素的数量
    addReplyLongLong(c,added);
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %rbx
pushq %rax
movq %rdi, %rbx
movq 0x8(%rdi), %rdi
movq 0x38(%rbx), %rax
movq 0x8(%rax), %rsi
callq 0x31454
testq %rax, %rax
je 0x3bc24
movq %rax, %r14
movl (%rax), %eax
andl $0xf, %eax
cmpl $0x2, %eax
je 0x3bc48
leaq 0x8ebf2(%rip), %rax     # 0xca800
movq 0x70(%rax), %rsi
movq %rbx, %rdi
addq $0x8, %rsp
popq %rbx
popq %r14
popq %r15
popq %rbp
jmp 0x2d6f0
movq 0x38(%rbx), %rax
movq 0x10(%rax), %rdi
callq 0x3b65c
movq %rax, %r14
movq 0x8(%rbx), %rdi
movq 0x38(%rbx), %rax
movq 0x8(%rax), %rsi
movq %r14, %rdx
callq 0x314ef
xorl %ebp, %ebp
cmpl $0x3, 0x30(%rbx)
jl 0x3bc8b
xorl %ebp, %ebp
movl $0x2, %r15d
movq 0x38(%rbx), %rax
movq (%rax,%r15,8), %rdi
callq 0x30971
movq 0x38(%rbx), %rcx
movq %rax, (%rcx,%r15,8)
movq 0x38(%rbx), %rax
movq (%rax,%r15,8), %rsi
movq %r14, %rdi
callq 0x3b674
addl %eax, %ebp
incq %r15
movslq 0x30(%rbx), %rax
cmpq %rax, %r15
jl 0x3bc58
testl %ebp, %ebp
je 0x3bcc0
movq 0x8(%rbx), %rdi
movq 0x38(%rbx), %rax
movq 0x8(%rax), %rsi
callq 0x316b7
movq 0x8(%rbx), %rax
movq 0x38(%rbx), %rcx
movq 0x8(%rcx), %rdx
movl 0x30(%rax), %ecx
leaq 0x58654(%rip), %rsi     # 0x9430a
movl $0x20, %edi
callq 0x608b5
movslq %ebp, %rsi
leaq 0x8e2de(%rip), %rax     # 0xc9fa8
addq %rsi, 0x560(%rax)
movq %rbx, %rdi
addq $0x8, %rsp
popq %rbx
popq %r14
popq %r15
popq %rbp
jmp 0x2dea3
// File: /workspace/github_c_makefile_star2_O1/nilyang[P]redis-tdd-annotation/src/t_set.c
// Function: sremCommand
void sremCommand(redisClient *c) {
    robj *set;
    int j, deleted = 0, keyremoved = 0;

    // 取出集合对象
    if ((set = lookupKeyWriteOrReply(c,c->argv[1],shared.czero)) == NULL ||
        checkType(c,set,REDIS_SET)) return;

    // 删除输入的所有元素
    for (j = 2; j < c->argc; j++) {
        
        // 只有元素在集合中时，才算一次成功删除
        if (setTypeRemove(set,c->argv[j])) {
            deleted++;
            // 如果集合已经为空，那么删除集合对象
            if (setTypeSize(set) == 0) {
                dbDelete(c->db,c->argv[1]);
                keyremoved = 1;
                break;
            }
        }
    }

    // 如果有至少一个元素被成功删除，那么执行以下程序
    if (deleted) {
        // 发送键修改信号
        signalModifiedKey(c->db,c->argv[1]);
        // 发送事件通知
        notifyKeyspaceEvent(REDIS_NOTIFY_SET,"srem",c->argv[1],c->db->id);
        // 发送事件通知
        if (keyremoved)
            notifyKeyspaceEvent(REDIS_NOTIFY_GENERIC,"del",c->argv[1],
                                c->db->id);
        // 将数据库设为脏
        server.dirty += deleted;
    }
    
    // 将被成功删除元素的数量作为回复
    addReplyLongLong(c,deleted);
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r12
pushq %rbx
movq %rdi, %rbx
movq 0x38(%rdi), %rax
movq 0x8(%rax), %rsi
leaq 0x8eb03(%rip), %rax     # 0xca800
movq 0x20(%rax), %rdx
callq 0x314a5
testq %rax, %rax
je 0x3bd22
movq %rax, %r14
movq %rbx, %rdi
movq %rax, %rsi
movl $0x2, %edx
callq 0x308e7
testl %eax, %eax
je 0x3bd2b
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
retq
xorl %r15d, %r15d
cmpl $0x3, 0x30(%rbx)
setge %bpl
jl 0x3bd88
xorl %r15d, %r15d
movl $0x2, %r12d
movq 0x38(%rbx), %rax
movq (%rax,%r12,8), %rsi
movq %r14, %rdi
callq 0x3b89f
testl %eax, %eax
je 0x3bd65
incl %r15d
movq %r14, %rdi
callq 0x3bb8a
testq %rax, %rax
je 0x3bd77
incq %r12
movslq 0x30(%rbx), %rax
cmpq %rax, %r12
setl %bpl
jl 0x3bd41
jmp 0x3bd88
movq 0x8(%rbx), %rdi
movq 0x38(%rbx), %rax
movq 0x8(%rax), %rsi
callq 0x3174b
movslq %r15d, %r14
testl %r15d, %r15d
je 0x3bdf5
movq 0x8(%rbx), %rdi
movq 0x38(%rbx), %rax
movq 0x8(%rax), %rsi
callq 0x316b7
movq 0x8(%rbx), %rax
movq 0x38(%rbx), %rcx
movq 0x8(%rcx), %rdx
movl 0x30(%rax), %ecx
leaq 0x58558(%rip), %rsi     # 0x9430f
movl $0x20, %edi
callq 0x608b5
testb $0x1, %bpl
je 0x3bde7
movq 0x8(%rbx), %rax
movq 0x38(%rbx), %rcx
movq 0x8(%rcx), %rdx
movl 0x30(%rax), %ecx
leaq 0x586b0(%rip), %rsi     # 0x9448d
movl $0x4, %edi
callq 0x608b5
leaq 0x8e1ba(%rip), %rax     # 0xc9fa8
addq %r14, 0x560(%rax)
movq %rbx, %rdi
movq %r14, %rsi
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
jmp 0x2dea3
// File: /workspace/github_c_makefile_star2_O1/nilyang[P]redis-tdd-annotation/src/t_set.c
// Function: sismemberCommand
void sismemberCommand(redisClient *c) {
    robj *set;

    // 取出集合对象
    if ((set = lookupKeyReadOrReply(c,c->argv[1],shared.czero)) == NULL ||
        checkType(c,set,REDIS_SET)) return;

    // 编码输入元素
    c->argv[2] = tryObjectEncoding(c->argv[2]);

    // 检查是否存在
    if (setTypeIsMember(set,c->argv[2]))
        addReply(c,shared.cone);
    else
        addReply(c,shared.czero);
}

// Assembly:
pushq %r15
pushq %r14
pushq %rbx
movq %rdi, %rbx
movq 0x38(%rdi), %rax
movq 0x8(%rax), %rsi
leaq 0x8e81c(%rip), %r15     # 0xca800
movq 0x20(%r15), %rdx
callq 0x31475
testq %rax, %rax
je 0x3c009
movq %rax, %r14
movq %rbx, %rdi
movq %rax, %rsi
movl $0x2, %edx
callq 0x308e7
testl %eax, %eax
je 0x3c00f
popq %rbx
popq %r14
popq %r15
retq
movq 0x38(%rbx), %rax
movq 0x10(%rax), %rdi
callq 0x30971
movq 0x38(%rbx), %rcx
movq %rax, 0x10(%rcx)
movq 0x38(%rbx), %rax
movq 0x10(%rax), %rsi
movq %r14, %rdi
callq 0x3b94d
xorl %ecx, %ecx
testl %eax, %eax
setne %cl
movq 0x20(%r15,%rcx,8), %rsi
movq %rbx, %rdi
popq %rbx
popq %r14
popq %r15
jmp 0x2d6f0
// File: /workspace/github_c_makefile_star2_O1/nilyang[P]redis-tdd-annotation/src/t_set.c
// Function: scardCommand
void scardCommand(redisClient *c) {
    robj *o;

    // 取出集合
    if ((o = lookupKeyReadOrReply(c,c->argv[1],shared.czero)) == NULL ||
        checkType(c,o,REDIS_SET)) return;

    // 返回集合的基数
    addReplyLongLong(c,setTypeSize(o));
}

// Assembly:
pushq %r14
pushq %rbx
pushq %rax
movq %rdi, %rbx
movq 0x38(%rdi), %rax
movq 0x8(%rax), %rsi
leaq 0x8e79d(%rip), %rax     # 0xca800
movq 0x20(%rax), %rdx
callq 0x31475
testq %rax, %rax
je 0x3c088
movq %rax, %r14
movq %rbx, %rdi
movq %rax, %rsi
movl $0x2, %edx
callq 0x308e7
testl %eax, %eax
je 0x3c090
addq $0x8, %rsp
popq %rbx
popq %r14
retq
movq %r14, %rdi
callq 0x3bb8a
movq %rbx, %rdi
movq %rax, %rsi
addq $0x8, %rsp
popq %rbx
popq %r14
jmp 0x2dea3
// File: /workspace/github_c_makefile_star2_O1/nilyang[P]redis-tdd-annotation/src/t_set.c
// Function: spopCommand
void spopCommand(redisClient *c) {
    robj *set, *ele, *aux;
    int64_t llele;
    int encoding;

    // 取出集合
    if ((set = lookupKeyWriteOrReply(c,c->argv[1],shared.nullbulk)) == NULL ||
        checkType(c,set,REDIS_SET)) return;

    // 从集合中随机取出一个元素
    encoding = setTypeRandomElement(set,&ele,&llele);

    // 将被取出元素从集合中删除
    if (encoding == REDIS_ENCODING_INTSET) {
        ele = createStringObjectFromLongLong(llele);
        set->ptr = intsetRemove(set->ptr,llele,NULL);
    } else {
        incrRefCount(ele);
        setTypeRemove(set,ele);
    }

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

    /* Replicate/AOF this command as an SREM operation */
    // 将这个命令当作 SREM 来传播，防止产生有害的随机性，导致数据不一致
    // （不同的服务器随机删除不同的元素）
    aux = createStringObject("SREM",4);
    rewriteClientCommandVector(c,3,aux,c->argv[1],ele);
    decrRefCount(ele);
    decrRefCount(aux);

    // 返回回复
    addReplyBulk(c,ele);

    // 如果集合已经为空，那么从数据库中删除它
    if (setTypeSize(set) == 0) {
        // 删除集合
        dbDelete(c->db,c->argv[1]);
        // 发送事件通知
        notifyKeyspaceEvent(REDIS_NOTIFY_GENERIC,"del",c->argv[1],c->db->id);
    }

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

    // 将数据库设为脏
    server.dirty++;
}

// Assembly:
pushq %r15
pushq %r14
pushq %r12
pushq %rbx
subq $0x18, %rsp
movq %rdi, %rbx
movq 0x38(%rdi), %rax
movq 0x8(%rax), %rsi
leaq 0x8e739(%rip), %rax     # 0xca800
movq 0x50(%rax), %rdx
callq 0x314a5
testq %rax, %rax
je 0x3c217
movq %rax, %r14
movq %rbx, %rdi
movq %rax, %rsi
movl $0x2, %edx
callq 0x308e7
testl %eax, %eax
jne 0x3c217
leaq 0x8(%rsp), %rsi
leaq 0x10(%rsp), %rdx
movq %r14, %rdi
callq 0x3bb1d
cmpl $0x6, %eax
jne 0x3c131
movq 0x10(%rsp), %r15
movq %r15, %rdi
callq 0x303c6
movq %rax, 0x8(%rsp)
movq 0x8(%r14), %rdi
movq %r15, %rsi
xorl %edx, %edx
callq 0x4f894
movq %rax, 0x8(%r14)
jmp 0x3c149
movq 0x8(%rsp), %r15
movq %r15, %rdi
callq 0x3041b
movq %r14, %rdi
movq %r15, %rsi
callq 0x3b89f
movq 0x8(%rbx), %rax
movq 0x38(%rbx), %rcx
movq 0x8(%rcx), %rdx
movl 0x30(%rax), %ecx
leaq 0x581c5(%rip), %rsi     # 0x94324
movl $0x20, %edi
callq 0x608b5
leaq 0x5d01f(%rip), %rdi     # 0x9918f
movl $0x4, %esi
callq 0x303b7
movq %rax, %r15
movq 0x38(%rbx), %rax
movq 0x8(%rax), %rcx
movq 0x8(%rsp), %r12
movq %rbx, %rdi
movl $0x3, %esi
movq %r15, %rdx
movq %r12, %r8
xorl %eax, %eax
callq 0x2f581
movq %r12, %rdi
callq 0x30834
movq %r15, %rdi
callq 0x30834
movq %rbx, %rdi
movq %r12, %rsi
callq 0x2df74
movq %r14, %rdi
callq 0x3bb8a
testq %rax, %rax
jne 0x3c1f8
movq 0x8(%rbx), %rdi
movq 0x38(%rbx), %rax
movq 0x8(%rax), %rsi
callq 0x3174b
movq 0x8(%rbx), %rax
movq 0x38(%rbx), %rcx
movq 0x8(%rcx), %rdx
movl 0x30(%rax), %ecx
leaq 0x5829f(%rip), %rsi     # 0x9448d
movl $0x4, %edi
callq 0x608b5
movq 0x8(%rbx), %rdi
movq 0x38(%rbx), %rax
movq 0x8(%rax), %rsi
callq 0x316b7
leaq 0x8dd98(%rip), %rax     # 0xc9fa8
incq 0x560(%rax)
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
retq
// File: /workspace/github_c_makefile_star2_O1/nilyang[P]redis-tdd-annotation/src/t_set.c
// Function: srandmemberCommand
void srandmemberCommand(redisClient *c) {
    robj *set, *ele;
    int64_t llele;
    int encoding;

    // 如果带有 count 参数，那么调用 srandmemberWithCountCommand 来处理
    if (c->argc == 3) {
        srandmemberWithCountCommand(c);
        return;

    // 参数错误
    } else if (c->argc > 3) {
        addReply(c,shared.syntaxerr);
        return;
    }

    // 随机取出单个元素就可以了

    // 取出集合对象
    if ((set = lookupKeyReadOrReply(c,c->argv[1],shared.nullbulk)) == NULL ||
        checkType(c,set,REDIS_SET)) return;

    // 随机取出一个元素
    encoding = setTypeRandomElement(set,&ele,&llele);
    // 回复
    if (encoding == REDIS_ENCODING_INTSET) {
        addReplyBulkLongLong(c,llele);
    } else {
        addReplyBulk(c,ele);
    }
}

// Assembly:
pushq %r14
pushq %rbx
subq $0x18, %rsp
movq %rdi, %rbx
movl 0x30(%rdi), %eax
cmpl $0x3, %eax
jne 0x3c971
movq %rbx, %rdi
addq $0x18, %rsp
popq %rbx
popq %r14
jmp 0x3c223
jle 0x3c990
leaq 0x8de86(%rip), %rax     # 0xca800
movq 0x80(%rax), %rsi
movq %rbx, %rdi
addq $0x18, %rsp
popq %rbx
popq %r14
jmp 0x2d6f0
movq 0x38(%rbx), %rax
movq 0x8(%rax), %rsi
leaq 0x8de61(%rip), %rax     # 0xca800
movq 0x50(%rax), %rdx
movq %rbx, %rdi
callq 0x31475
testq %rax, %rax
je 0x3c9c7
movq %rax, %r14
movq %rbx, %rdi
movq %rax, %rsi
movl $0x2, %edx
callq 0x308e7
testl %eax, %eax
je 0x3c9cf
addq $0x18, %rsp
popq %rbx
popq %r14
retq
leaq 0x10(%rsp), %rsi
leaq 0x8(%rsp), %rdx
movq %r14, %rdi
callq 0x3bb1d
cmpl $0x6, %eax
jne 0x3c9fa
movq 0x8(%rsp), %rsi
movq %rbx, %rdi
addq $0x18, %rsp
popq %rbx
popq %r14
jmp 0x2dfe7
movq 0x10(%rsp), %rsi
movq %rbx, %rdi
addq $0x18, %rsp
popq %rbx
popq %r14
jmp 0x2df74
// File: /workspace/github_c_makefile_star2_O1/nilyang[P]redis-tdd-annotation/src/t_set.c
// Function: sscanCommand
void sscanCommand(redisClient *c) {
    robj *set;
    unsigned long cursor;

    if (parseScanCursorOrReply(c,c->argv[2],&cursor) == REDIS_ERR) return;
    if ((set = lookupKeyReadOrReply(c,c->argv[1],shared.emptyscan)) == NULL ||
        checkType(c,set,REDIS_SET)) return;
    scanGenericCommand(c,set,cursor);
}

// Assembly:
pushq %r14
pushq %rbx
pushq %rax
movq %rdi, %rbx
movq 0x38(%rdi), %rax
movq 0x10(%rax), %rsi
movq %rsp, %rdx
callq 0x31e19
cmpl $-0x1, %eax
je 0x3cf88
movq 0x38(%rbx), %rax
movq 0x8(%rax), %rsi
leaq 0x8d8b2(%rip), %rax     # 0xca800
movq 0x148(%rax), %rdx
movq %rbx, %rdi
callq 0x31475
testq %rax, %rax
je 0x3cf88
movq %rax, %r14
movq %rbx, %rdi
movq %rax, %rsi
movl $0x2, %edx
callq 0x308e7
testl %eax, %eax
jne 0x3cf88
movq (%rsp), %rdx
movq %rbx, %rdi
movq %r14, %rsi
callq 0x31e96
addq $0x8, %rsp
popq %rbx
popq %r14
retq
// File: /workspace/github_c_makefile_star2_O1/nilyang[P]redis-tdd-annotation/src/t_zset.c
// Function: zslCreateNode
zskiplistNode *zslCreateNode(int level, double score, robj *obj) {
    
    // 分配空间
    zskiplistNode *zn = zmalloc(sizeof(*zn)+level*sizeof(struct zskiplistLevel));

    // 设置属性
    zn->score = score;
    zn->obj = obj;

    return zn;
}

// Assembly:
pushq %rbx
subq $0x10, %rsp
movq %rsi, %rbx
movsd %xmm0, 0x8(%rsp)
movslq %edi, %rdi
shlq $0x4, %rdi
addq $0x18, %rdi
callq 0x29709
movsd 0x8(%rsp), %xmm0
movsd %xmm0, 0x8(%rax)
movq %rbx, (%rax)
addq $0x10, %rsp
popq %rbx
retq
// File: /workspace/github_c_makefile_star2_O1/nilyang[P]redis-tdd-annotation/src/t_zset.c
// Function: zslFree
void zslFree(zskiplist *zsl) {

    zskiplistNode *node = zsl->header->level[0].forward, *next;

    // 释放表头
    zfree(zsl->header);

    // 释放表中所有节点
    // T = O(N)
    while(node) {

        next = node->level[0].forward;

        zslFreeNode(node);

        node = next;
    }
    
    // 释放跳跃表结构
    zfree(zsl);
}

// Assembly:
pushq %r15
pushq %r14
pushq %rbx
movq %rdi, %rbx
movq (%rdi), %rdi
movq 0x18(%rdi), %r14
callq 0x2984b
testq %r14, %r14
je 0x3d06b
movq (%r14), %rdi
movq 0x18(%r14), %r15
callq 0x30834
movq %r14, %rdi
callq 0x2984b
movq %r15, %r14
testq %r15, %r15
jne 0x3d04f
movq %rbx, %rdi
popq %rbx
popq %r14
popq %r15
jmp 0x2984b
// File: /workspace/github_c_makefile_star2_O1/nilyang[P]redis-tdd-annotation/src/t_zset.c
// Function: zslDeleteNode
void zslDeleteNode(zskiplist *zsl, zskiplistNode *x, zskiplistNode **update) {
    int i;

    // 更新所有和被删除节点 x 有关的节点的指针，解除它们之间的关系
    // T = O(1)
    for (i = 0; i < zsl->level; i++) {
        if (update[i]->level[i].forward == x) {
            update[i]->level[i].span += x->level[i].span - 1;
            update[i]->level[i].forward = x->level[i].forward;
        } else {
            update[i]->level[i].span -= 1;
        }
    }

    // 更新被删除节点 x 的前进和后退指针
    if (x->level[0].forward) {
        x->level[0].forward->backward = x->backward;
    } else {
        zsl->tail = x->backward;
    }

    // 更新跳跃表最大层数（只在被删除节点是跳跃表中最高的节点时才执行）
    // T = O(1)
    while(zsl->level > 1 && zsl->header->level[zsl->level-1].forward == NULL)
        zsl->level--;

    // 跳跃表节点计数器减一
    zsl->length--;
}

// Assembly:
movslq 0x18(%rdi), %rax
testq %rax, %rax
jle 0x3d32e
shlq $0x3, %rax
xorl %ecx, %ecx
movq (%rdx,%rcx), %r8
cmpq %rsi, 0x18(%r8,%rcx,2)
je 0x3d306
decl 0x20(%r8,%rcx,2)
jmp 0x3d325
movl 0x20(%rsi,%rcx,2), %r9d
movl 0x20(%r8,%rcx,2), %r10d
addl %r10d, %r9d
decl %r9d
movl %r9d, 0x20(%r8,%rcx,2)
movq 0x18(%rsi,%rcx,2), %r9
movq %r9, 0x18(%r8,%rcx,2)
addq $0x8, %rcx
cmpq %rcx, %rax
jne 0x3d2f4
movq 0x18(%rsi), %rax
leaq 0x8(%rdi), %rcx
leaq 0x10(%rax), %rdx
testq %rax, %rax
cmoveq %rcx, %rdx
movq 0x10(%rsi), %rax
movq %rax, (%rdx)
movslq 0x18(%rdi), %rax
cmpq $0x2, %rax
jl 0x3d383
movq (%rdi), %rcx
movq %rax, %rdx
shlq $0x4, %rdx
addq %rdx, %rcx
addq $0x8, %rcx
cmpq $0x0, (%rcx)
jne 0x3d383
leaq -0x1(%rax), %rdx
decl %eax
movl %eax, 0x18(%rdi)
leaq 0x1(%rdx), %rsi
addq $-0x10, %rcx
movq %rdx, %rax
cmpq $0x2, %rsi
jg 0x3d363
decq 0x10(%rdi)
retq
// File: /workspace/github_c_makefile_star2_O1/nilyang[P]redis-tdd-annotation/src/t_zset.c
// Function: zslDelete
int zslDelete(zskiplist *zsl, double score, robj *obj) {
    zskiplistNode *update[ZSKIPLIST_MAXLEVEL], *x;
    int i;

    // 遍历跳跃表，查找目标节点，并记录所有沿途节点
    // T_wrost = O(N^2), T_avg = O(N log N)
    x = zsl->header;
    for (i = zsl->level-1; i >= 0; i--) {

        // 遍历跳跃表的复杂度为 T_wrost = O(N), T_avg = O(log N)
        while (x->level[i].forward &&
            (x->level[i].forward->score < score ||
                // 比对分值
                (x->level[i].forward->score == score &&
                // 比对对象，T = O(N)
                compareStringObjects(x->level[i].forward->obj,obj) < 0)))

            // 沿着前进指针移动
            x = x->level[i].forward;

        // 记录沿途节点
        update[i] = x;
    }

    /* We may have multiple elements with the same score, what we need
     * is to find the element with both the right score and object. 
     *
     * 检查找到的元素 x ，只有在它的分值和对象都相同时，才将它删除。
     */
    x = x->level[0].forward;
    if (x && score == x->score && equalStringObjects(x->obj,obj)) {
        // T = O(1)
        zslDeleteNode(zsl, x, update);
        // T = O(1)
        zslFreeNode(x);
        return 1;
    } else {
        return 0; /* not found */
    }

    return 0; /* not found */
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x118, %rsp            # imm = 0x118
movq %rsi, %r14
movq (%rdi), %r15
movq %rdi, (%rsp)
movslq 0x18(%rdi), %r12
testq %r12, %r12
jle 0x3d417
movsd %xmm0, 0x8(%rsp)
movq %r12, %r13
decq %r12
movq %r12, %rbp
shlq $0x4, %rbp
movq 0x18(%r15,%rbp), %rax
testq %rax, %rax
je 0x3d40c
leaq (%r15,%rbp), %rbx
addq $0x18, %rbx
movsd 0x8(%rax), %xmm1
ucomisd %xmm1, %xmm0
ja 0x3d3f9
ucomisd %xmm0, %xmm1
jne 0x3d40c
jp 0x3d40c
movq (%rax), %rdi
movq %r14, %rsi
callq 0x30c21
movsd 0x8(%rsp), %xmm0
testl %eax, %eax
jns 0x3d40c
movq (%rbx), %r15
leaq (%r15,%rbp), %rbx
addq $0x18, %rbx
movq (%rbx), %rax
testq %rax, %rax
jne 0x3d3d1
movq %r15, 0x10(%rsp,%r12,8)
cmpq $0x1, %r13
jg 0x3d3b2
movq 0x18(%r15), %r15
xorl %ebp, %ebp
testq %r15, %r15
je 0x3d465
movsd 0x8(%r15), %xmm1
ucomisd %xmm0, %xmm1
jne 0x3d465
jp 0x3d465
movq (%r15), %rdi
movq %r14, %rsi
callq 0x30c35
testl %eax, %eax
je 0x3d465
leaq 0x10(%rsp), %rdx
movq (%rsp), %rdi
movq %r15, %rsi
callq 0x3d2e5
movq (%r15), %rdi
callq 0x30834
movq %r15, %rdi
callq 0x2984b
movl $0x1, %ebp
movl %ebp, %eax
addq $0x118, %rsp            # imm = 0x118
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
// File: /workspace/github_c_makefile_star2_O1/nilyang[P]redis-tdd-annotation/src/t_zset.c
// Function: zslIsInRange
int zslIsInRange(zskiplist *zsl, zrangespec *range) {
    zskiplistNode *x;

    /* Test for ranges that will always be empty. */
    // 先排除总为空的范围值
    if (range->min > range->max ||
            (range->min == range->max && (range->minex || range->maxex)))
        return 0;

    // 检查最大分值
    x = zsl->tail;
    if (x == NULL || !zslValueGteMin(x->score,range))
        return 0;

    // 检查最小分值
    x = zsl->header->level[0].forward;
    if (x == NULL || !zslValueLteMax(x->score,range))
        return 0;

    return 1;
}

// Assembly:
movsd (%rsi), %xmm1
movsd 0x8(%rsi), %xmm0
xorl %eax, %eax
ucomisd %xmm0, %xmm1
ja 0x3d494
jne 0x3d49b
jp 0x3d49b
cmpl $0x0, 0x10(%rsi)
je 0x3d495
retq
cmpl $0x0, 0x14(%rsi)
jne 0x3d494
movq 0x8(%rdi), %rcx
testq %rcx, %rcx
je 0x3d494
movsd 0x8(%rcx), %xmm2
xorl %ecx, %ecx
xorl %edx, %edx
ucomisd %xmm1, %xmm2
setbe %cl
setb %dl
cmpl $0x0, 0x10(%rsi)
cmovel %edx, %ecx
testb %cl, %cl
jne 0x3d494
movq (%rdi), %rcx
movq 0x18(%rcx), %rcx
testq %rcx, %rcx
je 0x3d494
xorl %eax, %eax
xorl %edx, %edx
ucomisd 0x8(%rcx), %xmm0
seta %al
setae %dl
cmpl $0x0, 0x14(%rsi)
cmovel %edx, %eax
movzbl %al, %eax
retq