// File: /workspace/github_c_makefile_star2_O1/nilyang[P]redis-tdd-annotation/src/rdb.c
// Function: rdbSaveObject
int rdbSaveObject(rio *rdb, robj *o) {
    int n, nwritten = 0;

    // 保存字符串对象
    if (o->type == REDIS_STRING) {
        /* Save a string value */
        if ((n = rdbSaveStringObject(rdb,o)) == -1) return -1;
        nwritten += n;

    // 保存列表对象
    } else if (o->type == REDIS_LIST) {
        /* Save a list value */
        if (o->encoding == REDIS_ENCODING_ZIPLIST) {
            size_t l = ziplistBlobLen((unsigned char*)o->ptr);

            // 以字符串对象的形式保存整个 ZIPLIST 列表
            if ((n = rdbSaveRawString(rdb,o->ptr,l)) == -1) return -1;
            nwritten += n;
        } else if (o->encoding == REDIS_ENCODING_LINKEDLIST) {
            list *list = o->ptr;
            listIter li;
            listNode *ln;

            if ((n = rdbSaveLen(rdb,listLength(list))) == -1) return -1;
            nwritten += n;

            // 遍历所有列表项
            listRewind(list,&li);
            while((ln = listNext(&li))) {
                robj *eleobj = listNodeValue(ln);
                // 以字符串对象的形式保存列表项
                if ((n = rdbSaveStringObject(rdb,eleobj)) == -1) return -1;
                nwritten += n;
            }
        } else {
            redisPanic("Unknown list encoding");
        }

    // 保存集合对象
    } else if (o->type == REDIS_SET) {
        /* Save a set value */
        if (o->encoding == REDIS_ENCODING_HT) {
            dict *set = o->ptr;
            dictIterator *di = dictGetIterator(set);
            dictEntry *de;

            if ((n = rdbSaveLen(rdb,dictSize(set))) == -1) return -1;
            nwritten += n;

            // 遍历集合成员
            while((de = dictNext(di)) != NULL) {
                robj *eleobj = dictGetKey(de);
                // 以字符串对象的方式保存成员
                if ((n = rdbSaveStringObject(rdb,eleobj)) == -1) return -1;
                nwritten += n;
            }
            dictReleaseIterator(di);
        } else if (o->encoding == REDIS_ENCODING_INTSET) {
            size_t l = intsetBlobLen((intset*)o->ptr);

            // 以字符串对象的方式保存整个 INTSET 集合
            if ((n = rdbSaveRawString(rdb,o->ptr,l)) == -1) return -1;
            nwritten += n;
        } else {
            redisPanic("Unknown set encoding");
        }

    // 保存有序集对象
    } else if (o->type == REDIS_ZSET) {
        /* Save a sorted set value */
        if (o->encoding == REDIS_ENCODING_ZIPLIST) {
            size_t l = ziplistBlobLen((unsigned char*)o->ptr);

            // 以字符串对象的形式保存整个 ZIPLIST 有序集
            if ((n = rdbSaveRawString(rdb,o->ptr,l)) == -1) return -1;
            nwritten += n;
        } else if (o->encoding == REDIS_ENCODING_SKIPLIST) {
            zset *zs = o->ptr;
            dictIterator *di = dictGetIterator(zs->dict);
            dictEntry *de;

            if ((n = rdbSaveLen(rdb,dictSize(zs->dict))) == -1) return -1;
            nwritten += n;

            // 遍历有序集
            while((de = dictNext(di)) != NULL) {
                robj *eleobj = dictGetKey(de);
                double *score = dictGetVal(de);

                // 以字符串对象的形式保存集合成员
                if ((n = rdbSaveStringObject(rdb,eleobj)) == -1) return -1;
                nwritten += n;

                // 成员分值（一个双精度浮点数）会被转换成字符串
                // 然后保存到 rdb 中
                if ((n = rdbSaveDoubleValue(rdb,*score)) == -1) return -1;
                nwritten += n;
            }
            dictReleaseIterator(di);
        } else {
            redisPanic("Unknown sorted set encoding");
        }

    // 保存哈希表
    } else if (o->type == REDIS_HASH) {

        /* Save a hash value */
        if (o->encoding == REDIS_ENCODING_ZIPLIST) {
            size_t l = ziplistBlobLen((unsigned char*)o->ptr);

            // 以字符串对象的形式保存整个 ZIPLIST 哈希表
            if ((n = rdbSaveRawString(rdb,o->ptr,l)) == -1) return -1;
            nwritten += n;

        } else if (o->encoding == REDIS_ENCODING_HT) {
            dictIterator *di = dictGetIterator(o->ptr);
            dictEntry *de;

            if ((n = rdbSaveLen(rdb,dictSize((dict*)o->ptr))) == -1) return -1;
            nwritten += n;

            // 迭代字典
            while((de = dictNext(di)) != NULL) {
                robj *key = dictGetKey(de);
                robj *val = dictGetVal(de);

                // 键和值都以字符串对象的形式来保存
                if ((n = rdbSaveStringObject(rdb,key)) == -1) return -1;
                nwritten += n;
                if ((n = rdbSaveStringObject(rdb,val)) == -1) return -1;
                nwritten += n;
            }
            dictReleaseIterator(di);

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

    } else {
        redisPanic("Unknown object type");
    }

    return nwritten;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x18, %rsp
movl (%rsi), %eax
movl %eax, %ecx
andl $0xf, %ecx
cmpl $0x4, %ecx
ja 0x37123
movq %rsi, %r14
movq %rdi, %rbx
leaq 0x61b4c(%rip), %rdx     # 0x98990
movslq (%rdx,%rcx,4), %rcx
addq %rdx, %rcx
jmpq *%rcx
movq %rbx, %rdi
movq %r14, %rsi
callq 0x36923
movl %eax, %ebp
cmpl $-0x1, %eax
jne 0x37112
jmp 0x37002
shrl $0x4, %eax
andl $0xf, %eax
cmpl $0x2, %eax
je 0x36f5e
cmpl $0x5, %eax
je 0x36f50
leaq 0x61c2c(%rip), %rdi     # 0x98ab3
leaq 0x61bae(%rip), %rsi     # 0x98a3c
movl $0x359, %edx            # imm = 0x359
jmp 0x37160
shrl $0x4, %eax
andl $0xf, %eax
cmpl $0x6, %eax
je 0x36fdc
cmpl $0x2, %eax
jne 0x37138
movq 0x8(%r14), %r15
movq %r15, %rdi
callq 0x228b5
movq %rax, %r14
movl 0x48(%r15), %esi
addl 0x28(%r15), %esi
movq %rbx, %rdi
callq 0x35fd0
cmpl $-0x1, %eax
je 0x3708a
movl %eax, %ebp
movq %r14, %rdi
callq 0x22913
testq %rax, %rax
je 0x370e9
movq (%rax), %rsi
movq %rbx, %rdi
callq 0x36923
xorl %ecx, %ecx
cmpl $-0x1, %eax
movl %eax, %edx
cmovel %ecx, %edx
addl %edx, %ebp
cmpl $-0x1, %eax
jne 0x36eda
jmp 0x37109
shrl $0x4, %eax
andl $0xf, %eax
cmpl $0x7, %eax
je 0x3700c
cmpl $0x5, %eax
je 0x36f50
leaq 0x6042c(%rip), %rdi     # 0x97353
leaq 0x61b0e(%rip), %rsi     # 0x98a3c
movl $0x336, %edx            # imm = 0x336
jmp 0x37160
shrl $0x4, %eax
andl $0xf, %eax
cmpl $0x4, %eax
je 0x37090
cmpl $0x5, %eax
jne 0x3714d
movq 0x8(%r14), %rdi
callq 0x2c9f5
jmp 0x36fe5
movq 0x8(%r14), %rdi
callq 0x228b5
movq %rax, %r15
movq 0x8(%r14), %rax
movl 0x48(%rax), %esi
addl 0x28(%rax), %esi
movq %rbx, %rdi
callq 0x35fd0
cmpl $-0x1, %eax
je 0x3708a
movl %eax, %ebp
xorl %r13d, %r13d
movq %r15, %rdi
callq 0x22913
testq %rax, %rax
je 0x370ff
movq (%rax), %rsi
movq 0x8(%rax), %r12
movq %rbx, %rdi
callq 0x36923
cmpl $-0x1, %eax
je 0x36fd1
movl %eax, %r14d
addl %ebp, %r14d
movq %rbx, %rdi
movq %r12, %rsi
callq 0x36923
movl %eax, %ebp
cmpl $-0x1, %eax
setne %al
cmovel %r13d, %ebp
addl %r14d, %ebp
jmp 0x36fd3
xorl %eax, %eax
testb %al, %al
jne 0x36f8a
jmp 0x37086
movq 0x8(%r14), %rdi
callq 0x4fa12
movq 0x8(%r14), %rsi
movq %rbx, %rdi
movq %rax, %rdx
callq 0x36761
xorl %ebp, %ebp
cmpl $-0x1, %eax
cmovnel %eax, %ebp
jne 0x37112
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
jmp 0x37114
movq 0x8(%r14), %r15
movq (%r15), %rdi
callq 0x228b5
movq %rax, %r14
movq (%r15), %rax
movl 0x48(%rax), %esi
addl 0x28(%rax), %esi
movq %rbx, %rdi
callq 0x35fd0
cmpl $-0x1, %eax
je 0x3708a
movl %eax, %ebp
xorl %r12d, %r12d
movq %r14, %rdi
callq 0x22913
testq %rax, %rax
je 0x370e9
movq (%rax), %rsi
movq 0x8(%rax), %r13
movq %rbx, %rdi
callq 0x36923
cmpl $-0x1, %eax
je 0x37080
movl %eax, %r15d
addl %ebp, %r15d
movsd (%r13), %xmm0
movq %rbx, %rdi
callq 0x36aa3
movl %eax, %ebp
cmpl $-0x1, %eax
setne %al
cmovel %r12d, %ebp
addl %r15d, %ebp
jmp 0x37082
xorl %eax, %eax
testb %al, %al
jne 0x37036
xorl %ecx, %ecx
jmp 0x37109
xorl %ecx, %ecx
xorl %ebp, %ebp
jmp 0x37109
movq 0x8(%r14), %r15
movl 0x28(%r15), %esi
movq %rbx, %rdi
callq 0x35fd0
cmpl $-0x1, %eax
je 0x370ee
movl %eax, %ebp
leaq 0x8(%rsp), %r14
movq %r15, %rdi
movq %r14, %rsi
callq 0x205d2
xorl %r12d, %r12d
movq %r14, %rdi
callq 0x205ef
testq %rax, %rax
sete %r15b
je 0x370f3
movq 0x10(%rax), %rsi
movq %rbx, %rdi
callq 0x36923
cmpl $-0x1, %eax
movl %eax, %ecx
cmovel %r12d, %ecx
addl %ecx, %ebp
cmpl $-0x1, %eax
jne 0x370ba
jmp 0x370f3
movq %r14, %rdi
jmp 0x37102
xorl %r15d, %r15d
xorl %ebp, %ebp
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
testb %r15b, %r15b
jne 0x37112
jmp 0x37114
movq %r15, %rdi
callq 0x229b9
movb $0x1, %cl
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
testb %cl, %cl
je 0x37114
movl %ebp, %eax
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x60289(%rip), %rdi     # 0x973b3
leaq 0x6190b(%rip), %rsi     # 0x98a3c
movl $0x35d, %edx            # imm = 0x35D
jmp 0x37160
leaq 0x6195d(%rip), %rdi     # 0x98a9c
leaq 0x618f6(%rip), %rsi     # 0x98a3c
movl $0x312, %edx            # imm = 0x312
jmp 0x37160
leaq 0x61930(%rip), %rdi     # 0x98a84
leaq 0x618e1(%rip), %rsi     # 0x98a3c
movl $0x2f5, %edx            # imm = 0x2F5
callq 0x4d0e5
movl $0x1, %edi
callq 0x1f3b0