// File: /workspace/github_c_makefile_star2_O2/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 0x34bee
movq %rsi, %r14
movq %rdi, %rbx
leaq 0x5a077(%rip), %rdx     # 0x8e9c4
movslq (%rdx,%rcx,4), %rcx
addq %rdx, %rcx
jmpq *%rcx
movq %rbx, %rdi
movq %r14, %rsi
callq 0x345d2
jmp 0x34aef
shrl $0x4, %eax
andl $0xf, %eax
cmpl $0x2, %eax
je 0x34a56
cmpl $0x5, %eax
je 0x34a48
leaq 0x5a14e(%rip), %rdi     # 0x8ead3
leaq 0x5a0d0(%rip), %rsi     # 0x8ea5c
movl $0x359, %edx            # imm = 0x359
jmp 0x34c2b
shrl $0x4, %eax
andl $0xf, %eax
cmpl $0x6, %eax
je 0x34ad7
cmpl $0x2, %eax
jne 0x34c03
movq 0x8(%r14), %r14
movq %r14, %rdi
callq 0x21ef6
movq %rax, %r15
movl 0x48(%r14), %esi
addl 0x28(%r14), %esi
movq %rbx, %rdi
callq 0x33fef
pushq $-0x1
popq %r14
cmpl $-0x1, %eax
je 0x34bcf
movl %eax, %ebp
movq %r15, %rdi
callq 0x21f2f
testq %rax, %rax
je 0x34be1
movq (%rax), %rsi
movq %rbx, %rdi
callq 0x345d2
addl %eax, %ebp
cmpl $-0x1, %eax
jne 0x349dc
jmp 0x34bcf
shrl $0x4, %eax
andl $0xf, %eax
cmpl $0x7, %eax
je 0x34b02
cmpl $0x5, %eax
je 0x34a48
leaq 0x58988(%rip), %rdi     # 0x8d3a7
leaq 0x5a036(%rip), %rsi     # 0x8ea5c
movl $0x336, %edx            # imm = 0x336
jmp 0x34c2b
shrl $0x4, %eax
andl $0xf, %eax
cmpl $0x4, %eax
je 0x34b80
cmpl $0x5, %eax
jne 0x34c18
movq 0x8(%r14), %rdi
callq 0x2b4ab
jmp 0x34ae0
movq 0x8(%r14), %rdi
callq 0x21ef6
movq %rax, %r15
movq 0x8(%r14), %rax
movl 0x48(%rax), %esi
addl 0x28(%rax), %esi
movq %rbx, %rdi
callq 0x33fef
pushq $-0x1
popq %r14
cmpl $-0x1, %eax
je 0x34bcf
movl %eax, %ebp
movq %r15, %rdi
callq 0x21f2f
testq %rax, %rax
je 0x34be1
movq (%rax), %rsi
movq 0x8(%rax), %r13
movq %rbx, %rdi
callq 0x345d2
cmpl $-0x1, %eax
je 0x34bcf
movl %eax, %r12d
addl %ebp, %r12d
movq %rbx, %rdi
movq %r13, %rsi
callq 0x345d2
cmpl $-0x1, %eax
movl %eax, %ebp
movl $0x0, %ecx
cmovel %ecx, %ebp
addl %r12d, %ebp
cmpl $-0x1, %eax
jne 0x34a83
jmp 0x34bcf
movq 0x8(%r14), %rdi
callq 0x4b624
movq 0x8(%r14), %rsi
movq %rbx, %rdi
movq %rax, %rdx
callq 0x3447a
cmpl $-0x1, %eax
je 0x34bcb
movl %eax, %ebp
movl %ebp, %r14d
jmp 0x34bcf
movq 0x8(%r14), %r14
movq (%r14), %rdi
callq 0x21ef6
movq %rax, %r15
movq (%r14), %rax
movl 0x48(%rax), %esi
addl 0x28(%rax), %esi
movq %rbx, %rdi
callq 0x33fef
pushq $-0x1
popq %r14
cmpl $-0x1, %eax
je 0x34bcf
movl %eax, %ebp
movq %r15, %rdi
callq 0x21f2f
testq %rax, %rax
je 0x34be1
movq (%rax), %rsi
movq 0x8(%rax), %r13
movq %rbx, %rdi
callq 0x345d2
cmpl $-0x1, %eax
je 0x34bcf
movl %eax, %r12d
movsd (%r13), %xmm0
movq %rbx, %rdi
callq 0x346de
xorl %ecx, %ecx
cmpl $-0x1, %eax
je 0x34b70
movl %eax, %ecx
addl %ebp, %r12d
addl %ecx, %r12d
movl %r12d, %ebp
cmpl $-0x1, %eax
jne 0x34b31
jmp 0x34bcf
movq 0x8(%r14), %r15
movl 0x28(%r15), %esi
movq %rbx, %rdi
callq 0x33fef
cmpl $-0x1, %eax
je 0x34bcb
movl %eax, %ebp
leaq 0x8(%rsp), %r14
movq %r15, %rdi
movq %r14, %rsi
callq 0x1ffac
movq %r14, %rdi
callq 0x1ffc6
testq %rax, %rax
je 0x34afa
movq 0x10(%rax), %rsi
movq %rbx, %rdi
callq 0x345d2
addl %eax, %ebp
cmpl $-0x1, %eax
jne 0x34ba7
pushq $-0x1
popq %r14
movl %r14d, %eax
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %r15, %rdi
callq 0x21fe6
jmp 0x34afa
leaq 0x58812(%rip), %rdi     # 0x8d407
leaq 0x59e60(%rip), %rsi     # 0x8ea5c
movl $0x35d, %edx            # imm = 0x35D
jmp 0x34c2b
leaq 0x59eb2(%rip), %rdi     # 0x8eabc
leaq 0x59e4b(%rip), %rsi     # 0x8ea5c
movl $0x312, %edx            # imm = 0x312
jmp 0x34c2b
leaq 0x59e85(%rip), %rdi     # 0x8eaa4
leaq 0x59e36(%rip), %rsi     # 0x8ea5c
movl $0x2f5, %edx            # imm = 0x2F5
callq 0x490e8
pushq $0x1
popq %rdi
callq 0x1f3b0