LLM4Binary/decompile-bench-makefile huggingface dataset:
// File: /workspace/github_c_makefile_star2_O2/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 0x38cc6
cmpl $0x2, %eax
jne 0x38d59
movq 0x8(%r14), %rdi
xorl %r14d, %r14d
movq %rbx, %rsi
xorl %edx, %edx
callq 0x21956
testl %eax, %eax
jne 0x38d00
jmp 0x38cf4
leaq 0x10(%rsp), %rsi
movq %rbx, %rdi
callq 0x2eeea
testl %eax, %eax
je 0x38d0b
pushq $0x2
popq %rsi
movq %r14, %rdi
callq 0x38d95
movq 0x8(%r14), %rdi
movq %rbx, %rsi
xorl %edx, %edx
callq 0x21956
testl %eax, %eax
jne 0x38d71
movq %rbx, %rdi
callq 0x2eacc
pushq $0x1
popq %r14
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 0x4b2a6
movq %rax, 0x8(%r14)
cmpb $0x0, (%rbx)
je 0x38d54
movq %rax, %rdi
callq 0x4b620
movl %eax, %eax
leaq 0x8e26a(%rip), %rcx     # 0xc6fa8
cmpq %rax, 0x778(%rcx)
jae 0x38cfc
pushq $0x2
popq %rsi
movq %r14, %rdi
callq 0x38d95
jmp 0x38cfc
xorl %r14d, %r14d
jmp 0x38d00
leaq 0x55d5c(%rip), %rdi     # 0x8eabc
leaq 0x5638f(%rip), %rsi     # 0x8f0f6
pushq $0x68
popq %rdx
callq 0x490e8
jmp 0x38d8d
leaq 0x56352(%rip), %rdx     # 0x8f0ca
leaq 0x56377(%rip), %rcx     # 0x8f0f6
pushq $0x61
popq %r8
xorl %edi, %edi
movq %rbx, %rsi
callq 0x4980c
pushq $0x1
popq %rdi
callq 0x1f3b0
// File: /workspace/github_c_makefile_star2_O2/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 0x38e70
cmpl $0x2, %esi
jne 0x38e8b
leaq 0x8dab2(%rip), %rdi     # 0xc6870
xorl %esi, %esi
callq 0x216f0
movq %rax, %r14
movq 0x8(%rbx), %rdi
callq 0x4b620
movl %eax, %esi
movq %r14, %rdi
callq 0x21751
movq %rbx, %rdi
callq 0x38fcc
movq %rax, %r15
leaq 0x8(%rsp), %r12
movq %r15, %rdi
xorl %esi, %esi
movq %r12, %rdx
callq 0x39051
cmpl $-0x1, %eax
je 0x38e41
movq 0x8(%rsp), %rdi
callq 0x2ea90
movq %rax, %r13
movq %r14, %rdi
movq %rax, %rsi
xorl %edx, %edx
callq 0x21956
testl %eax, %eax
je 0x38deb
leaq 0x5633a(%rip), %rdx     # 0x8f15c
leaq 0x562cd(%rip), %rcx     # 0x8f0f6
xorl %edi, %edi
movq %r13, %rsi
movl $0x18e, %r8d            # imm = 0x18E
callq 0x4980c
pushq $0x1
popq %rdi
callq 0x1f3b0
movq %r15, %rdi
callq 0x39035
movl $0xffffff0f, %eax       # imm = 0xFFFFFF0F
andl (%rbx), %eax
orl $0x20, %eax
movl %eax, (%rbx)
movq 0x8(%rbx), %rdi
callq 0x283cd
movq %r14, 0x8(%rbx)
addq $0x10, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
retq
leaq 0x5629e(%rip), %rdx     # 0x8f115
leaq 0x56278(%rip), %rcx     # 0x8f0f6
xorl %edi, %edi
movq %rbx, %rsi
movl $0x17d, %r8d            # imm = 0x17D
jmp 0x38e34
leaq 0x562ed(%rip), %rdi     # 0x8f17f
leaq 0x5625d(%rip), %rsi     # 0x8f0f6
movl $0x198, %edx            # imm = 0x198
callq 0x490e8
jmp 0x38e39
// File: /workspace/github_c_makefile_star2_O2/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 0x38eea
cmpl $0x2, %eax
jne 0x38f2d
movq 0x8(%rbx), %rdi
callq 0x21c36
testl %eax, %eax
jne 0x38efc
movq 0x8(%rbx), %rdi
callq 0x229c3
pushq $0x1
popq %rbp
testl %eax, %eax
je 0x38efe
movq 0x8(%rbx), %rdi
callq 0x2172d
jmp 0x38efe
movq %rsp, %rax
movq %rsi, %rdi
movq %rax, %rsi
callq 0x2eeea
testl %eax, %eax
je 0x38f09
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 0x4b50c
movq %rax, 0x8(%rbx)
cmpl $0x0, (%r14)
je 0x38efc
pushq $0x1
popq %rbp
jmp 0x38efe
leaq 0x55b88(%rip), %rdi     # 0x8eabc
leaq 0x561bb(%rip), %rsi     # 0x8f0f6
movl $0x8b, %edx
callq 0x490e8
pushq $0x1
popq %rdi
callq 0x1f3b0
// File: /workspace/github_c_makefile_star2_O2/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 0x38f7d
cmpl $0x2, %eax
jne 0x38fac
movq 0x8(%rbx), %rdi
callq 0x21b64
movq %rax, %rcx
xorl %eax, %eax
testq %rcx, %rcx
setne %al
jmp 0x38fa6
leaq 0x8(%rsp), %rax
movq %rsi, %rdi
movq %rax, %rsi
callq 0x2eeea
movl %eax, %ecx
xorl %eax, %eax
testl %ecx, %ecx
jne 0x38fa6
movq 0x8(%rbx), %rdi
movq 0x8(%rsp), %rsi
callq 0x4b5a5
movzbl %al, %eax
addq $0x10, %rsp
popq %rbx
retq
leaq 0x55b09(%rip), %rdi     # 0x8eabc
leaq 0x5613c(%rip), %rsi     # 0x8f0f6
movl $0xa4, %edx
callq 0x490e8
pushq $0x1
popq %rdi
callq 0x1f3b0
// File: /workspace/github_c_makefile_star2_O2/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
pushq $0x18
popq %rdi
callq 0x2828d
movq %rax, %rbx
movq %r14, (%rax)
movl (%r14), %eax
shrl $0x4, %eax
andl $0xf, %eax
movl %eax, 0x8(%rbx)
cmpl $0x6, %eax
je 0x39006
cmpl $0x2, %eax
jne 0x39015
movq 0x8(%r14), %rdi
callq 0x21ef6
movq %rax, 0x10(%rbx)
jmp 0x3900a
andl $0x0, 0xc(%rbx)
movq %rbx, %rax
addq $0x8, %rsp
popq %rbx
popq %r14
retq
leaq 0x55aa0(%rip), %rdi     # 0x8eabc
leaq 0x560d3(%rip), %rsi     # 0x8f0f6
movl $0xc6, %edx
callq 0x490e8
pushq $0x1
popq %rdi
callq 0x1f3b0
// File: /workspace/github_c_makefile_star2_O2/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 0x3907e
cmpl $0x2, %eax
jne 0x39097
movq %rsi, %r14
movq 0x10(%rbx), %rdi
callq 0x21f2f
testq %rax, %rax
je 0x3909c
movq (%rax), %rax
movq %rax, (%r14)
jmp 0x39097
movq (%rbx), %rax
movq 0x8(%rax), %rdi
movl 0xc(%rbx), %esi
leal 0x1(%rsi), %eax
movl %eax, 0xc(%rbx)
callq 0x4b608
testb %al, %al
je 0x3909c
movl 0x8(%rbx), %eax
jmp 0x3909f
pushq $-0x1
popq %rax
addq $0x8, %rsp
popq %rbx
popq %r14
retq
// File: /workspace/github_c_makefile_star2_O2/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 0x39051
cmpl $-0x1, %eax
je 0x390e5
cmpl $0x2, %eax
je 0x390d7
cmpl $0x6, %eax
jne 0x390f0
movq 0x8(%rsp), %rdi
callq 0x2ea90
movq %rax, %rbx
jmp 0x390e7
movq (%rsp), %rbx
movq %rbx, %rdi
callq 0x2eacc
jmp 0x390e7
xorl %ebx, %ebx
movq %rbx, %rax
addq $0x10, %rsp
popq %rbx
retq
leaq 0x56007(%rip), %rdi     # 0x8f0fe
leaq 0x55ff8(%rip), %rsi     # 0x8f0f6
movl $0x12f, %edx            # imm = 0x12F
callq 0x490e8
pushq $0x1
popq %rdi
callq 0x1f3b0
// File: /workspace/github_c_makefile_star2_O2/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 0x3913e
cmpl $0x2, %eax
jne 0x3915b
movq %rsi, %r14
movq 0x8(%rbx), %rdi
callq 0x22047
movq (%rax), %rax
movq %rax, (%r14)
jmp 0x3914d
movq %rdx, %r15
movq 0x8(%rbx), %rdi
callq 0x4b5cf
movq %rax, (%r15)
movl (%rbx), %eax
shrl $0x4, %eax
andl $0xf, %eax
popq %rbx
popq %r14
popq %r15
retq
leaq 0x5595a(%rip), %rdi     # 0x8eabc
leaq 0x55f8d(%rip), %rsi     # 0x8f0f6
movl $0x158, %edx            # imm = 0x158
callq 0x490e8
pushq $0x1
popq %rdi
callq 0x1f3b0
// File: /workspace/github_c_makefile_star2_O2/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 0x3919c
cmpl $0x2, %eax
jne 0x391a9
movq 0x8(%rdi), %rcx
movq 0x48(%rcx), %rax
addq 0x28(%rcx), %rax
jmp 0x391a7
movq 0x8(%rdi), %rdi
callq 0x4b620
movl %eax, %eax
popq %rcx
retq
leaq 0x5590c(%rip), %rdi     # 0x8eabc
leaq 0x55f3f(%rip), %rsi     # 0x8f0f6
movl $0x16a, %edx            # imm = 0x16A
callq 0x490e8
pushq $0x1
popq %rdi
callq 0x1f3b0
// File: /workspace/github_c_makefile_star2_O2/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 0x2f988
testq %rax, %rax
je 0x39213
movq %rax, %r14
movl (%rax), %eax
andl $0xf, %eax
cmpl $0x2, %eax
je 0x39237
leaq 0x8e603(%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 0x10(%rax), %rdi
callq 0x38c74
movq %rax, %r14
movq 0x8(%rbx), %rdi
movq 0x38(%rbx), %rax
movq 0x8(%rax), %rsi
movq %r14, %rdx
callq 0x2fa09
xorl %ebp, %ebp
pushq $0x2
popq %r15
movslq 0x30(%rbx), %rax
cmpq %rax, %r15
jge 0x39272
movq 0x38(%rbx), %rax
movq (%rax,%r15,8), %rdi
callq 0x2ef4c
movq 0x38(%rbx), %rcx
movq %rax, (%rcx,%r15,8)
movq 0x38(%rbx), %rax
movq (%rax,%r15,8), %rsi
movq %r14, %rdi
callq 0x38c8c
addl %eax, %ebp
incq %r15
jmp 0x3923d
testl %ebp, %ebp
je 0x392a5
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 0x5107d(%rip), %rsi     # 0x8a31a
pushq $0x20
popq %rdi
callq 0x5b488
movl %ebp, %esi
leaq 0x8dcfa(%rip), %rax     # 0xc6fa8
addq %rsi, 0x560(%rax)
movq %rbx, %rdi
addq $0x8, %rsp
popq %rbx
popq %r14
popq %r15
popq %rbp
jmp 0x2c794
// File: /workspace/github_c_makefile_star2_O2/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 0x8e51f(%rip), %rax     # 0xc7800
movq 0x20(%rax), %rdx
callq 0x2f9d9
testq %rax, %rax
je 0x39304
movq %rax, %r14
pushq $0x2
popq %rdx
movq %rbx, %rdi
movq %rax, %rsi
callq 0x2eec6
testl %eax, %eax
je 0x3930d
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
retq
xorl %ebp, %ebp
pushq $0x2
popq %r15
movslq 0x30(%rbx), %r12
cmpq %r12, %r15
jge 0x39355
movq 0x38(%rbx), %rax
movq (%rax,%r15,8), %rsi
movq %r14, %rdi
callq 0x38ea5
testl %eax, %eax
je 0x3933f
incl %ebp
movq %r14, %rdi
callq 0x3917b
testq %rax, %rax
je 0x39344
incq %r15
jmp 0x39313
movq 0x8(%rbx), %rdi
movq 0x38(%rbx), %rax
movq 0x8(%rax), %rsi
callq 0x2fc3b
testl %ebp, %ebp
je 0x393be
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 0x50f9f(%rip), %rsi     # 0x8a31f
pushq $0x20
popq %rdi
callq 0x5b488
cmpq %r12, %r15
jge 0x393ab
movq 0x8(%rbx), %rax
movq 0x38(%rbx), %rcx
movq 0x8(%rcx), %rdx
movl 0x30(%rax), %ecx
leaq 0x510fa(%rip), %rsi     # 0x8a49d
pushq $0x4
popq %rdi
callq 0x5b488
movslq %ebp, %rsi
leaq 0x8dbf3(%rip), %rax     # 0xc6fa8
addq %rsi, 0x560(%rax)
jmp 0x393c0
xorl %esi, %esi
movq %rbx, %rdi
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
jmp 0x2c794
// File: /workspace/github_c_makefile_star2_O2/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 0x8e25e(%rip), %r15     # 0xc7800
movq 0x20(%r15), %rdx
callq 0x2f9a9
testq %rax, %rax
je 0x395c5
movq %rax, %r14
pushq $0x2
popq %rdx
movq %rbx, %rdi
movq %rax, %rsi
callq 0x2eec6
testl %eax, %eax
je 0x395cb
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 0x38(%rbx), %rax
movq 0x10(%rax), %rsi
movq %r14, %rdi
callq 0x38f4d
xorl %ecx, %ecx
testl %eax, %eax
setne %cl
movq 0x20(%r15,%rcx,8), %rsi
movq %rbx, %rdi
popq %rbx
popq %r14
popq %r15
jmp 0x2c10d
// File: /workspace/github_c_makefile_star2_O2/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 0x8e1e1(%rip), %rax     # 0xc7800
movq 0x20(%rax), %rdx
callq 0x2f9a9
testq %rax, %rax
je 0x39642
movq %rax, %r14
pushq $0x2
popq %rdx
movq %rbx, %rdi
movq %rax, %rsi
callq 0x2eec6
testl %eax, %eax
je 0x3964a
addq $0x8, %rsp
popq %rbx
popq %r14
retq
movq %r14, %rdi
callq 0x3917b
movq %rbx, %rdi
movq %rax, %rsi
addq $0x8, %rsp
popq %rbx
popq %r14
jmp 0x2c794
// File: /workspace/github_c_makefile_star2_O2/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 0x8e17f(%rip), %rax     # 0xc7800
movq 0x50(%rax), %rdx
callq 0x2f9d9
testq %rax, %rax
je 0x397c0
movq %rax, %r14
pushq $0x2
popq %rdx
movq %rbx, %rdi
movq %rax, %rsi
callq 0x2eec6
testl %eax, %eax
jne 0x397c0
leaq 0x10(%rsp), %rsi
leaq 0x8(%rsp), %rdx
movq %r14, %rdi
callq 0x39110
cmpl $0x6, %eax
jne 0x396e7
movq 0x8(%rsp), %r12
movq %r12, %rdi
callq 0x2ea90
movq %rax, %r15
movq 0x8(%r14), %rdi
movq %r12, %rsi
xorl %edx, %edx
callq 0x4b50c
movq %rax, 0x8(%r14)
jmp 0x396ff
movq 0x10(%rsp), %r15
movq %r15, %rdi
callq 0x2eacc
movq %r14, %rdi
movq %r15, %rsi
callq 0x38ea5
movq 0x8(%rbx), %rax
movq 0x38(%rbx), %rcx
movq 0x8(%rcx), %rdx
movl 0x30(%rax), %ecx
leaq 0x50c1f(%rip), %rsi     # 0x8a334
pushq $0x20
popq %rdi
callq 0x5b488
leaq 0x55a78(%rip), %rdi     # 0x8f19c
pushq $0x4
popq %rsi
callq 0x2ea81
movq %rax, %r12
movq 0x38(%rbx), %rax
movq 0x8(%rax), %rcx
pushq $0x3
popq %rsi
movq %rbx, %rdi
movq %r12, %rdx
movq %r15, %r8
xorl %eax, %eax
callq 0x2dd2e
movq %r15, %rdi
callq 0x2ee1f
movq %r12, %rdi
callq 0x2ee1f
movq %rbx, %rdi
movq %r15, %rsi
callq 0x2c84a
movq %r14, %rdi
callq 0x3917b
testq %rax, %rax
jne 0x397a1
movq 0x8(%rbx), %rdi
movq 0x38(%rbx), %rax
movq 0x8(%rax), %rsi
callq 0x2fc3b
movq 0x8(%rbx), %rax
movq 0x38(%rbx), %rcx
movq 0x8(%rcx), %rdx
movl 0x30(%rax), %ecx
leaq 0x50d04(%rip), %rsi     # 0x8a49d
pushq $0x4
popq %rdi
callq 0x5b488
movq 0x8(%rbx), %rdi
movq 0x38(%rbx), %rax
movq 0x8(%rax), %rsi
callq 0x2fbc0
leaq 0x8d7ef(%rip), %rax     # 0xc6fa8
incq 0x560(%rax)
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
retq
// File: /workspace/github_c_makefile_star2_O2/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 0x39eaf
movq %rbx, %rdi
addq $0x18, %rsp
popq %rbx
popq %r14
jmp 0x397cc
jle 0x39ece
leaq 0x8d948(%rip), %rax     # 0xc7800
movq 0x80(%rax), %rsi
movq %rbx, %rdi
addq $0x18, %rsp
popq %rbx
popq %r14
jmp 0x2c10d
movq 0x38(%rbx), %rax
movq 0x8(%rax), %rsi
leaq 0x8d923(%rip), %rax     # 0xc7800
movq 0x50(%rax), %rdx
movq %rbx, %rdi
callq 0x2f9a9
testq %rax, %rax
je 0x39f03
movq %rax, %r14
pushq $0x2
popq %rdx
movq %rbx, %rdi
movq %rax, %rsi
callq 0x2eec6
testl %eax, %eax
je 0x39f0b
addq $0x18, %rsp
popq %rbx
popq %r14
retq
leaq 0x10(%rsp), %rsi
leaq 0x8(%rsp), %rdx
movq %r14, %rdi
callq 0x39110
cmpl $0x6, %eax
jne 0x39f36
movq 0x8(%rsp), %rsi
movq %rbx, %rdi
addq $0x18, %rsp
popq %rbx
popq %r14
jmp 0x2c8bb
movq 0x10(%rsp), %rsi
movq %rbx, %rdi
addq $0x18, %rsp
popq %rbx
popq %r14
jmp 0x2c84a
// File: /workspace/github_c_makefile_star2_O2/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 0x302a1
cmpl $-0x1, %eax
je 0x3a47d
movq 0x38(%rbx), %rax
movq 0x8(%rax), %rsi
leaq 0x8d3bb(%rip), %rax     # 0xc7800
movq 0x148(%rax), %rdx
movq %rbx, %rdi
callq 0x2f9a9
testq %rax, %rax
je 0x3a47d
movq %rax, %r14
pushq $0x2
popq %rdx
movq %rbx, %rdi
movq %rax, %rsi
callq 0x2eec6
testl %eax, %eax
jne 0x3a47d
movq (%rsp), %rdx
movq %rbx, %rdi
movq %r14, %rsi
callq 0x30317
addq $0x8, %rsp
popq %rbx
popq %r14
retq
nopl (%rax)
// File: /workspace/github_c_makefile_star2_O2/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, %rbx
movq (%rdi), %r12
movslq 0x18(%rdi), %r15
movsd %xmm0, 0x8(%rsp)
testq %r15, %r15
jle 0x3a864
decq %r15
movq %r15, %r13
shlq $0x4, %r13
movq %r12, %rax
movq %rax, %r12
movq 0x18(%rax,%r13), %rax
testq %rax, %rax
je 0x3a85d
movsd 0x8(%rax), %xmm1
ucomisd %xmm1, %xmm0
ja 0x3a81b
ucomisd %xmm0, %xmm1
jne 0x3a85d
jp 0x3a85d
movq (%rax), %rdi
movq %r14, %rsi
callq 0x2f1e2
movsd 0x8(%rsp), %xmm0
testl %eax, %eax
jns 0x3a85d
leaq (%r12,%r13), %rax
addq $0x18, %rax
movq (%rax), %rax
jmp 0x3a81b
movq %r12, 0x10(%rsp,%r15,8)
jmp 0x3a809
movq 0x18(%r12), %r15
xorl %ebp, %ebp
testq %r15, %r15
je 0x3a8a8
movsd 0x8(%r15), %xmm1
ucomisd %xmm0, %xmm1
jne 0x3a8a8
jp 0x3a8a8
movq (%r15), %rdi
movq %r14, %rsi
callq 0x2f1f2
testl %eax, %eax
je 0x3a8a8
leaq 0x10(%rsp), %rdx
movq %rbx, %rdi
movq %r15, %rsi
callq 0x3a760
movq %r15, %rdi
callq 0x3a510
pushq $0x1
popq %rbp
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_O2/nilyang[P]redis-tdd-annotation/src/t_zset.c
// Function: zslFirstInRange
zskiplistNode *zslFirstInRange(zskiplist *zsl, zrangespec *range) {
    zskiplistNode *x;
    int i;

    /* If everything is out of range, return early. */
    if (!zslIsInRange(zsl,range)) return NULL;

    // 遍历跳跃表，查找符合范围 min 项的节点
    // T_wrost = O(N), T_avg = O(log N)
    x = zsl->header;
    for (i = zsl->level-1; i >= 0; i--) {
        /* Go forward while *OUT* of range. */
        while (x->level[i].forward &&
            !zslValueGteMin(x->level[i].forward->score,range))
                x = x->level[i].forward;
    }

    /* This is an inner range, so the next node cannot be NULL. */
    x = x->level[0].forward;
    redisAssert(x != NULL);

    /* Check if score <= max. */
    // 检查节点是否符合范围的 max 项
    // T = O(1)
    if (!zslValueLteMax(x->score,range)) return NULL;
    return x;
}

// Assembly:
pushq %r14
pushq %rbx
pushq %rax
movq %rsi, %rbx
movq %rdi, %r14
callq 0x3a8bc
testl %eax, %eax
je 0x3a9b7
movq (%r14), %rcx
movslq 0x18(%r14), %rax
testq %rax, %rax
jle 0x3a989
decq %rax
movq %rax, %rsi
shlq $0x4, %rsi
movq %rcx, %rdx
movq 0x18(%rcx,%rsi), %rcx
testq %rcx, %rcx
je 0x3a984
movsd 0x8(%rcx), %xmm0
xorl %edi, %edi
xorl %r8d, %r8d
ucomisd (%rbx), %xmm0
setbe %dil
setb %r8b
cmpl $0x0, 0x10(%rbx)
cmovel %r8d, %edi
testb %dil, %dil
jne 0x3a954
movq %rdx, %rcx
jmp 0x3a945
movq 0x18(%rcx), %rcx
testq %rcx, %rcx
je 0x3a9c1
movsd 0x8(%rbx), %xmm0
xorl %edx, %edx
xorl %eax, %eax
ucomisd 0x8(%rcx), %xmm0
setbe %dl
setb %al
cmpl $0x0, 0x14(%rbx)
cmovel %eax, %edx
xorl %eax, %eax
testb %dl, %dl
cmoveq %rcx, %rax
jmp 0x3a9b9
xorl %eax, %eax
addq $0x8, %rsp
popq %rbx
popq %r14
retq
leaq 0x54804(%rip), %rdi     # 0x8f1cc
leaq 0x547f4(%rip), %rsi     # 0x8f1c3
movl $0x1da, %edx            # imm = 0x1DA
callq 0x4906b
pushq $0x1
popq %rdi
callq 0x1f3b0
// File: /workspace/github_c_makefile_star2_O2/nilyang[P]redis-tdd-annotation/src/t_zset.c
// Function: zslLastInRange
zskiplistNode *zslLastInRange(zskiplist *zsl, zrangespec *range) {
    zskiplistNode *x;
    int i;

    /* If everything is out of range, return early. */
    // 先确保跳跃表中至少有一个节点符合 range 指定的范围，
    // 否则直接失败
    // T = O(1)
    if (!zslIsInRange(zsl,range)) return NULL;

    // 遍历跳跃表，查找符合范围 max 项的节点
    // T_wrost = O(N), T_avg = O(log N)
    x = zsl->header;
    for (i = zsl->level-1; i >= 0; i--) {
        /* Go forward while *IN* range. */
        while (x->level[i].forward &&
            zslValueLteMax(x->level[i].forward->score,range))
                x = x->level[i].forward;
    }

    /* This is an inner range, so this node cannot be NULL. */
    redisAssert(x != NULL);

    /* Check if score >= min. */
    // 检查节点是否符合范围的 min 项
    // T = O(1)
    if (!zslValueGteMin(x->score,range)) return NULL;

    // 返回节点
    return x;
}

// Assembly:
pushq %r14
pushq %rbx
pushq %rax
movq %rsi, %rbx
movq %rdi, %r14
callq 0x3a8bc
testl %eax, %eax
je 0x3aa69
movq (%r14), %rcx
movslq 0x18(%r14), %rax
testq %rax, %rax
jle 0x3aa40
decq %rax
movq %rax, %rsi
shlq $0x4, %rsi
movq %rcx, %rdx
movq 0x18(%rcx,%rsi), %rcx
testq %rcx, %rcx
je 0x3aa3b
movsd 0x8(%rbx), %xmm0
xorl %edi, %edi
xorl %r8d, %r8d
ucomisd 0x8(%rcx), %xmm0
setbe %dil
setb %r8b
cmpl $0x0, 0x14(%rbx)
cmovel %r8d, %edi
testb %dil, %dil
je 0x3aa0a
movq %rdx, %rcx
jmp 0x3a9fb
testq %rcx, %rcx
je 0x3aa73
movsd 0x8(%rcx), %xmm0
xorl %edx, %edx
xorl %eax, %eax
ucomisd (%rbx), %xmm0
setbe %dl
setb %al
cmpl $0x0, 0x10(%rbx)
cmovel %eax, %edx
xorl %eax, %eax
testb %dl, %dl
cmoveq %rcx, %rax
jmp 0x3aa6b
xorl %eax, %eax
addq $0x8, %rsp
popq %rbx
popq %r14
retq
leaq 0x54752(%rip), %rdi     # 0x8f1cc
leaq 0x54742(%rip), %rsi     # 0x8f1c3
movl $0x201, %edx            # imm = 0x201
callq 0x4906b
pushq $0x1
popq %rdi
callq 0x1f3b0
// File: /workspace/github_c_makefile_star2_O2/nilyang[P]redis-tdd-annotation/src/t_zset.c
// Function: zslParseLexRangeItem
int zslParseLexRangeItem(robj *item, robj **dest, int *ex) {
    char *c = item->ptr;

    switch(c[0]) {
    case '+':
        if (c[1] != '\0') return REDIS_ERR;
        *ex = 0;
        *dest = shared.maxstring;
        incrRefCount(shared.maxstring);
        return REDIS_OK;
    case '-':
        if (c[1] != '\0') return REDIS_ERR;
        *ex = 0;
        *dest = shared.minstring;
        incrRefCount(shared.minstring);
        return REDIS_OK;
    case '(':
        *ex = 1;
        *dest = createStringObject(c+1,sdslen(c)-1);
        return REDIS_OK;
    case '[':
        *ex = 0;
        *dest = createStringObject(c+1,sdslen(c)-1);
        return REDIS_OK;
    default:
        return REDIS_ERR;
    }
}

// Assembly:
pushq %rbx
movq %rsi, %rbx
movq 0x8(%rdi), %rdi
movzbl (%rdi), %ecx
cmpl $0x28, %ecx
je 0x3ae77
cmpl $0x5b, %ecx
je 0x3ae51
pushq $-0x1
popq %rax
cmpl $0x2d, %ecx
je 0x3ae56
cmpl $0x2b, %ecx
jne 0x3ae91
cmpb $0x0, 0x1(%rdi)
jne 0x3ae91
andl $0x0, (%rdx)
leaq 0x8c9b8(%rip), %rax     # 0xc7800
movq 0x158(%rax), %rdi
jmp 0x3ae6d
andl $0x0, (%rdx)
jmp 0x3ae7d
cmpb $0x0, 0x1(%rdi)
jne 0x3ae91
andl $0x0, (%rdx)
leaq 0x8c99a(%rip), %rax     # 0xc7800
movq 0x150(%rax), %rdi
movq %rdi, (%rbx)
callq 0x2eacc
jmp 0x3ae8f
movl $0x1, (%rdx)
movslq -0x8(%rdi), %rsi
incq %rdi
decq %rsi
callq 0x2ea81
movq %rax, (%rbx)
xorl %eax, %eax
popq %rbx
retq
// File: /workspace/github_c_makefile_star2_O2/nilyang[P]redis-tdd-annotation/src/t_zset.c
// Function: zzlGetScore
double zzlGetScore(unsigned char *sptr) {
    unsigned char *vstr;
    unsigned int vlen;
    long long vlong;
    char buf[128];
    double score;

    redisAssert(sptr != NULL);
    // 取出节点值
    redisAssert(ziplistGet(sptr,&vstr,&vlen,&vlong));

    if (vstr) {
        // 字符串转 double
        memcpy(buf,vstr,vlen);
        buf[vlen] = '\0';
        score = strtod(buf,NULL);
    } else {
        // double 值
        score = vlong;
    }

    return score;
}

// Assembly:
pushq %r14
pushq %rbx
subq $0xa8, %rsp
testq %rdi, %rdi
je 0x3b106
leaq 0x18(%rsp), %rsi
leaq 0xc(%rsp), %rdx
leaq 0x10(%rsp), %rcx
callq 0x2aea9
testl %eax, %eax
je 0x3b11b
movq 0x18(%rsp), %rsi
testq %rsi, %rsi
je 0x3b0f4
movl 0xc(%rsp), %ebx
leaq 0x20(%rsp), %r14
movq %r14, %rdi
movq %rbx, %rdx
callq 0x1fbd0
movb $0x0, 0x20(%rsp,%rbx)
movq %r14, %rdi
xorl %esi, %esi
callq 0x1fc40
jmp 0x3b0fb
cvtsi2sdq 0x10(%rsp), %xmm0
addq $0xa8, %rsp
popq %rbx
popq %r14
retq
leaq 0x543fc(%rip), %rdi     # 0x8f509
leaq 0x540af(%rip), %rsi     # 0x8f1c3
movl $0x3e5, %edx            # imm = 0x3E5
jmp 0x3b12e
leaq 0x540b4(%rip), %rdi     # 0x8f1d6
leaq 0x5409a(%rip), %rsi     # 0x8f1c3
movl $0x3e7, %edx            # imm = 0x3E7
callq 0x4906b
pushq $0x1
popq %rdi
callq 0x1f3b0
// File: /workspace/github_c_makefile_star2_O2/nilyang[P]redis-tdd-annotation/src/t_zset.c
// Function: ziplistGetObject
robj *ziplistGetObject(unsigned char *sptr) {
    unsigned char *vstr;
    unsigned int vlen;
    long long vlong;

    redisAssert(sptr != NULL);
    redisAssert(ziplistGet(sptr,&vstr,&vlen,&vlong));

    if (vstr) {
        return createStringObject((char*)vstr,vlen);
    } else {
        return createStringObjectFromLongLong(vlong);
    }
}

// Assembly:
subq $0x18, %rsp
testq %rdi, %rdi
je 0x3b180
leaq 0x10(%rsp), %rsi
leaq 0x4(%rsp), %rdx
leaq 0x8(%rsp), %rcx
callq 0x2aea9
testl %eax, %eax
je 0x3b195
movq 0x10(%rsp), %rdi
testq %rdi, %rdi
je 0x3b171
movl 0x4(%rsp), %esi
callq 0x2ea81
jmp 0x3b17b
movq 0x8(%rsp), %rdi
callq 0x2ea90
addq $0x18, %rsp
retq
leaq 0x54382(%rip), %rdi     # 0x8f509
leaq 0x54035(%rip), %rsi     # 0x8f1c3
movl $0x3fe, %edx            # imm = 0x3FE
jmp 0x3b1a8
leaq 0x5403a(%rip), %rdi     # 0x8f1d6
leaq 0x54020(%rip), %rsi     # 0x8f1c3
movl $0x3ff, %edx            # imm = 0x3FF
callq 0x4906b
pushq $0x1
popq %rdi
callq 0x1f3b0
// File: /workspace/github_c_makefile_star2_O2/nilyang[P]redis-tdd-annotation/src/t_zset.c
// Function: zzlNext
void zzlNext(unsigned char *zl, unsigned char **eptr, unsigned char **sptr) {
    unsigned char *_eptr, *_sptr;

    redisAssert(*eptr != NULL && *sptr != NULL);

    // 指向下个成员
    _eptr = ziplistNext(zl,*sptr);
    if (_eptr != NULL) {
        // 指向下个分值
        _sptr = ziplistNext(zl,_eptr);
        redisAssert(_sptr != NULL);
    } else {
        /* No next entry. */
        _sptr = NULL;
    }

    *eptr = _eptr;
    *sptr = _sptr;
}

// Assembly:
pushq %r15
pushq %r14
pushq %r12
pushq %rbx
pushq %rax
cmpq $0x0, (%rsi)
je 0x3b2c1
movq %rdx, %rbx
movq %rsi, %r14
movq (%rdx), %rsi
testq %rsi, %rsi
je 0x3b2c1
movq %rdi, %r12
callq 0x2ae0d
movq %rax, %r15
testq %rax, %rax
je 0x3b2ad
movq %r12, %rdi
movq %r15, %rsi
callq 0x2ae0d
testq %rax, %rax
jne 0x3b2af
leaq 0x53f9e(%rip), %rdi     # 0x8f23d
leaq 0x53f1d(%rip), %rsi     # 0x8f1c3
movl $0x43e, %edx            # imm = 0x43E
jmp 0x3b2d4
xorl %eax, %eax
movq %r15, (%r14)
movq %rax, (%rbx)
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
retq
leaq 0x53f56(%rip), %rdi     # 0x8f21e
leaq 0x53ef4(%rip), %rsi     # 0x8f1c3
movl $0x437, %edx            # imm = 0x437
callq 0x4906b
pushq $0x1
popq %rdi
callq 0x1f3b0
// File: /workspace/github_c_makefile_star2_O2/nilyang[P]redis-tdd-annotation/src/t_zset.c
// Function: zzlFirstInRange
unsigned char *zzlFirstInRange(unsigned char *zl, zrangespec *range) {
    // 从表头开始遍历
    unsigned char *eptr = ziplistIndex(zl,0), *sptr;
    double score;

    /* If everything is out of range, return early. */
    if (!zzlIsInRange(zl,range)) return NULL;

    // 分值在 ziplist 中是从小到大排列的
    // 从表头向表尾遍历
    while (eptr != NULL) {
        sptr = ziplistNext(zl,eptr);
        redisAssert(sptr != NULL);

        score = zzlGetScore(sptr);
        if (zslValueGteMin(score,range)) {
            /* Check if score <= max. */
            // 遇上第一个符合范围的分值，
            // 返回它的节点指针
            if (zslValueLteMax(score,range))
                return eptr;
            return NULL;
        }

        /* Move to next element. */
        eptr = ziplistNext(zl,sptr);
    }

    return NULL;
}

// Assembly:
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
movq %rsi, %rbx
movq %rdi, %r12
xorl %r14d, %r14d
xorl %esi, %esi
callq 0x2abfb
movq %rax, %r15
movq %r12, %rdi
movq %rbx, %rsi
callq 0x3b366
testl %eax, %eax
je 0x3b4b6
xorl %r14d, %r14d
testq %r15, %r15
je 0x3b4b6
movq %r12, %rdi
movq %r15, %rsi
callq 0x2ae0d
testq %rax, %rax
je 0x3b4c3
movq %rax, %r13
movq %rax, %rdi
callq 0x3b09e
xorl %eax, %eax
xorl %ecx, %ecx
ucomisd (%rbx), %xmm0
setbe %al
setb %cl
cmpl $0x0, 0x10(%rbx)
cmovel %ecx, %eax
testb %al, %al
je 0x3b491
movq %r12, %rdi
movq %r13, %rsi
callq 0x2ae0d
movq %rax, %r15
jmp 0x3b448
movsd 0x8(%rbx), %xmm1
xorl %eax, %eax
xorl %ecx, %ecx
ucomisd %xmm0, %xmm1
setbe %al
setb %cl
cmpl $0x0, 0x14(%rbx)
cmovel %ecx, %eax
xorl %ecx, %ecx
testb %al, %al
cmovneq %rcx, %r15
movq %r15, %r14
movq %r14, %rax
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
retq
leaq 0x5403f(%rip), %rdi     # 0x8f509
leaq 0x53cf2(%rip), %rsi     # 0x8f1c3
movl $0x498, %edx            # imm = 0x498
callq 0x4906b
pushq $0x1
popq %rdi
callq 0x1f3b0
// File: /workspace/github_c_makefile_star2_O2/nilyang[P]redis-tdd-annotation/src/t_zset.c
// Function: zzlLastInRange
unsigned char *zzlLastInRange(unsigned char *zl, zrangespec *range) {
    // 从表尾开始遍历
    unsigned char *eptr = ziplistIndex(zl,-2), *sptr;
    double score;

    /* If everything is out of range, return early. */
    if (!zzlIsInRange(zl,range)) return NULL;

    // 在有序的 ziplist 里从表尾到表头遍历
    while (eptr != NULL) {
        sptr = ziplistNext(zl,eptr);
        redisAssert(sptr != NULL);

        // 获取节点的 score 值
        score = zzlGetScore(sptr);
        if (zslValueLteMax(score,range)) {
            /* Check if score >= min. */
            if (zslValueGteMin(score,range))
                return eptr;
            return NULL;
        }

        /* Move to previous element by moving to the score of previous element.
         * When this returns NULL, we know there also is no element. */
        sptr = ziplistPrev(zl,eptr);
        if (sptr != NULL)
            redisAssert((eptr = ziplistPrev(zl,sptr)) != NULL);
        else
            eptr = NULL;
    }

    return NULL;
}

// Assembly:
pushq %r15
pushq %r14
pushq %r12
pushq %rbx
pushq %rax
movq %rsi, %rbx
movq %rdi, %r15
pushq $-0x2
popq %rsi
callq 0x2abfb
movq %rax, %r14
movq %r15, %rdi
movq %rbx, %rsi
callq 0x3b366
xorl %r12d, %r12d
testl %eax, %eax
je 0x3b5b3
testq %r14, %r14
je 0x3b5b3
movq %r15, %rdi
movq %r14, %rsi
callq 0x2ae0d
testq %rax, %rax
je 0x3b5c2
movq %rax, %rdi
callq 0x3b09e
movsd 0x8(%rbx), %xmm1
xorl %eax, %eax
xorl %ecx, %ecx
ucomisd %xmm0, %xmm1
setbe %al
setb %cl
cmpl $0x0, 0x14(%rbx)
cmovel %ecx, %eax
testb %al, %al
je 0x3b593
movq %r15, %rdi
movq %r14, %rsi
callq 0x2ae33
movl $0x0, %r14d
testq %rax, %rax
je 0x3b512
movq %r15, %rdi
movq %rax, %rsi
callq 0x2ae33
movq %rax, %r14
testq %rax, %rax
jne 0x3b512
leaq 0x53cde(%rip), %rdi     # 0x8f263
leaq 0x53c37(%rip), %rsi     # 0x8f1c3
movl $0x4cd, %edx            # imm = 0x4CD
jmp 0x3b5d5
xorl %eax, %eax
xorl %ecx, %ecx
ucomisd (%rbx), %xmm0
setbe %al
setb %cl
cmpl $0x0, 0x10(%rbx)
cmovel %ecx, %eax
xorl %ecx, %ecx
testb %al, %al
cmovneq %rcx, %r14
movq %r14, %r12
movq %r12, %rax
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
retq
leaq 0x53f40(%rip), %rdi     # 0x8f509
leaq 0x53bf3(%rip), %rsi     # 0x8f1c3
movl $0x4be, %edx            # imm = 0x4BE
callq 0x4906b
pushq $0x1
popq %rdi
callq 0x1f3b0
// File: /workspace/github_c_makefile_star2_O2/nilyang[P]redis-tdd-annotation/src/t_zset.c
// Function: zzlInsertAt
unsigned char *zzlInsertAt(unsigned char *zl, unsigned char *eptr, robj *ele, double score) {
    unsigned char *sptr;
    char scorebuf[128];
    int scorelen;
    size_t offset;

    // 计算分值的字节长度
    redisAssertWithInfo(NULL,ele,sdsEncodedObject(ele));
    scorelen = d2string(scorebuf,sizeof(scorebuf),score);

    // 插入到表尾，或者空表
    if (eptr == NULL) {
        // | member-1 | score-1 | member-2 | score-2 | ... | member-N | score-N |
        // 先推入元素
        zl = ziplistPush(zl,ele->ptr,sdslen(ele->ptr),ZIPLIST_TAIL);
        // 后推入分值
        zl = ziplistPush(zl,(unsigned char*)scorebuf,scorelen,ZIPLIST_TAIL);

    // 插入到某个节点的前面
    } else {
        /* Keep offset relative to zl, as it might be re-allocated. */
        // 插入成员
        offset = eptr-zl;
        zl = ziplistInsert(zl,eptr,ele->ptr,sdslen(ele->ptr));
        eptr = zl+offset;

        /* Insert score after the element. */
        // 将分值插入在成员之后
        redisAssertWithInfo(NULL,ele,(sptr = ziplistNext(zl,eptr)) != NULL);
        zl = ziplistInsert(zl,sptr,(unsigned char*)scorebuf,scorelen);
    }

    return zl;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r12
pushq %rbx
subq $0x80, %rsp
movq %rdx, %rbx
movl (%rdx), %eax
shrl $0x4, %eax
testb $0x7, %al
jne 0x3b9c3
movq %rsi, %r15
movq %rdi, %r14
movq %rsp, %rdi
movl $0x80, %esi
callq 0x2e6e0
movl %eax, %ebp
testq %r15, %r15
je 0x3b975
movq %r15, %r12
subq %r14, %r12
movq 0x8(%rbx), %rdx
movl -0x8(%rdx), %ecx
movq %r14, %rdi
movq %r15, %rsi
callq 0x2afb2
movq %rax, %r14
addq %rax, %r12
movq %rax, %rdi
movq %r12, %rsi
callq 0x2ae0d
testq %rax, %rax
je 0x3b9a8
movq %rsp, %rdx
movq %r14, %rdi
movq %rax, %rsi
movl %ebp, %ecx
callq 0x2afb2
jmp 0x3b998
movq 0x8(%rbx), %rsi
movl -0x8(%rsi), %edx
pushq $0x1
popq %rbx
movq %r14, %rdi
movl %ebx, %ecx
callq 0x2a889
movq %rsp, %rsi
movq %rax, %rdi
movl %ebp, %edx
movl %ebx, %ecx
callq 0x2a889
addq $0x80, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
retq
leaq 0x538f0(%rip), %rdx     # 0x8f29f
leaq 0x5380d(%rip), %rcx     # 0x8f1c3
xorl %edi, %edi
movq %rbx, %rsi
movl $0x588, %r8d            # imm = 0x588
jmp 0x3b9dc
leaq 0x538bf(%rip), %rdx     # 0x8f289
leaq 0x537f2(%rip), %rcx     # 0x8f1c3
xorl %edi, %edi
movq %rbx, %rsi
movl $0x573, %r8d            # imm = 0x573
callq 0x4980c
pushq $0x1
popq %rdi
callq 0x1f3b0
// File: /workspace/github_c_makefile_star2_O2/nilyang[P]redis-tdd-annotation/src/t_zset.c
// Function: zzlInsert
unsigned char *zzlInsert(unsigned char *zl, robj *ele, double score) {

    // 指向 ziplist 第一个节点（也即是有序集的 member 域）
    unsigned char *eptr = ziplistIndex(zl,0), *sptr;
    double s;

    // 解码值
    ele = getDecodedObject(ele);

    // 遍历整个 ziplist
    while (eptr != NULL) {

        // 取出分值
        sptr = ziplistNext(zl,eptr);
        redisAssertWithInfo(NULL,ele,sptr != NULL);
        s = zzlGetScore(sptr);

        if (s > score) {
            /* First element with score larger than score for element to be
             * inserted. This means we should take its spot in the list to
             * maintain ordering. */
            // 遇到第一个 score 值比输入 score 大的节点
            // 将新节点插入在这个节点的前面，
            // 让节点在 ziplist 里根据 score 从小到大排列
            zl = zzlInsertAt(zl,eptr,ele,score);
            break;
        } else if (s == score) {
            /* Ensure lexicographical ordering for elements. */
            // 如果输入 score 和节点的 score 相同
            // 那么根据 member 的字符串位置来决定新节点的插入位置
            if (zzlCompareElements(eptr,ele->ptr,sdslen(ele->ptr)) > 0) {
                zl = zzlInsertAt(zl,eptr,ele,score);
                break;
            }
        }

        /* Move to next element. */
        // 输入 score 比节点的 score 值要大
        // 移动到下一个节点
        eptr = ziplistNext(zl,sptr);
    }

    /* Push on tail of list when it was not yet inserted. */
    if (eptr == NULL)
        zl = zzlInsertAt(zl,NULL,ele,score);

    decrRefCount(ele);
    return zl;
}

// Assembly:
pushq %r15
pushq %r14
pushq %r12
pushq %rbx
pushq %rax
movsd %xmm0, (%rsp)
movq %rsi, %rbx
movq %rdi, %r14
xorl %esi, %esi
callq 0x2abfb
movq %rax, %r15
movq %rbx, %rdi
callq 0x2f087
movq %rax, %rbx
testq %r15, %r15
je 0x3ba67
movq %r14, %rdi
movq %r15, %rsi
callq 0x2ae0d
testq %rax, %rax
je 0x3ba93
movq %rax, %r12
movq %rax, %rdi
callq 0x3b09e
ucomisd (%rsp), %xmm0
ja 0x3ba5f
jne 0x3ba4f
jp 0x3ba4f
movq 0x8(%rbx), %rsi
movl -0x8(%rsi), %edx
movq %r15, %rdi
callq 0x3b1b5
testl %eax, %eax
jg 0x3ba5f
movq %r14, %rdi
movq %r12, %rsi
callq 0x2ae0d
movq %rax, %r15
jmp 0x3ba11
movq %r14, %rdi
movq %r15, %rsi
jmp 0x3ba6c
movq %r14, %rdi
xorl %esi, %esi
movq %rbx, %rdx
movsd (%rsp), %xmm0
callq 0x3b8fc
movq %rax, %r14
movq %rbx, %rdi
callq 0x2ee1f
movq %r14, %rax
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
retq
leaq 0x53a6f(%rip), %rdx     # 0x8f509
leaq 0x53722(%rip), %rcx     # 0x8f1c3
xorl %edi, %edi
movq %rbx, %rsi
movl $0x5a7, %r8d            # imm = 0x5A7
callq 0x4980c
pushq $0x1
popq %rdi
callq 0x1f3b0
// File: /workspace/github_c_makefile_star2_O2/nilyang[P]redis-tdd-annotation/src/t_zset.c
// Function: zsetLength
unsigned int zsetLength(robj *zobj) {

    int length = -1;

    if (zobj->encoding == REDIS_ENCODING_ZIPLIST) {
        length = zzlLength(zobj->ptr);

    } else if (zobj->encoding == REDIS_ENCODING_SKIPLIST) {
        length = ((zset*)zobj->ptr)->zsl->length;

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

    return length;
}

// Assembly:
movl (%rdi), %eax
shrl $0x4, %eax
andl $0xf, %eax
cmpl $0x7, %eax
je 0x3bc39
cmpl $0x5, %eax
jne 0x3bc45
movq 0x8(%rdi), %rdi
jmp 0x3b252
movq 0x8(%rdi), %rax
movq 0x8(%rax), %rax
movl 0x10(%rax), %eax
retq
pushq %rax
leaq 0x5175a(%rip), %rdi     # 0x8d3a7
leaq 0x5356f(%rip), %rsi     # 0x8f1c3
movl $0x632, %edx            # imm = 0x632
callq 0x490e8
pushq $0x1
popq %rdi
callq 0x1f3b0