// File: /workspace/github_c_makefile_star2_O3/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 0x37329
movq %rsi, %r14
movq %rdi, %rbx
leaq 0x61980(%rip), %rdx     # 0x98a00
movslq (%rdx,%rcx,4), %rcx
addq %rdx, %rcx
jmpq *%rcx
movq %rbx, %rdi
movq %r14, %rsi
callq 0x36bad
jmp 0x37226
shrl $0x4, %eax
andl $0xf, %eax
cmpl $0x2, %eax
je 0x3718b
cmpl $0x5, %eax
je 0x3717d
leaq 0x61a57(%rip), %rdi     # 0x98b0f
leaq 0x619d9(%rip), %rsi     # 0x98a98
movl $0x359, %edx            # imm = 0x359
jmp 0x37366
shrl $0x4, %eax
andl $0xf, %eax
cmpl $0x6, %eax
je 0x3720e
cmpl $0x2, %eax
jne 0x3733e
movq 0x8(%r14), %r14
movq %r14, %rdi
callq 0x22a71
movq %rax, %r15
movl 0x48(%r14), %esi
addl 0x28(%r14), %esi
movq %rbx, %rdi
callq 0x363a7
movl $0xffffffff, %r14d      # imm = 0xFFFFFFFF
cmpl $-0x1, %eax
je 0x3730a
movl %eax, %ebp
movq %r15, %rdi
callq 0x22acf
testq %rax, %rax
je 0x3731c
movq (%rax), %rsi
movq %rbx, %rdi
callq 0x36bad
addl %eax, %ebp
cmpl $-0x1, %eax
jne 0x37111
jmp 0x3730a
shrl $0x4, %eax
andl $0xf, %eax
cmpl $0x7, %eax
je 0x37239
cmpl $0x5, %eax
je 0x3717d
leaq 0x6025f(%rip), %rdi     # 0x973b3
leaq 0x6193d(%rip), %rsi     # 0x98a98
movl $0x336, %edx            # imm = 0x336
jmp 0x37366
shrl $0x4, %eax
andl $0xf, %eax
cmpl $0x4, %eax
je 0x372b9
cmpl $0x5, %eax
jne 0x37353
movq 0x8(%r14), %rdi
callq 0x2cc64
jmp 0x37217
movq 0x8(%r14), %rdi
callq 0x22a71
movq %rax, %r15
movq 0x8(%r14), %rax
movl 0x48(%rax), %esi
addl 0x28(%rax), %esi
movq %rbx, %rdi
callq 0x363a7
movl $0xffffffff, %r14d      # imm = 0xFFFFFFFF
cmpl $-0x1, %eax
je 0x3730a
movl %eax, %ebp
movq %r15, %rdi
callq 0x22acf
testq %rax, %rax
je 0x3731c
movq (%rax), %rsi
movq 0x8(%rax), %r13
movq %rbx, %rdi
callq 0x36bad
cmpl $-0x1, %eax
je 0x3730a
movl %eax, %r12d
addl %ebp, %r12d
movq %rbx, %rdi
movq %r13, %rsi
callq 0x36bad
cmpl $-0x1, %eax
movl %eax, %ebp
movl $0x0, %ecx
cmovel %ecx, %ebp
addl %r12d, %ebp
cmpl $-0x1, %eax
jne 0x371ba
jmp 0x3730a
movq 0x8(%r14), %rdi
callq 0x4f4c3
movq 0x8(%r14), %rsi
movq %rbx, %rdi
movq %rax, %rdx
callq 0x36a60
cmpl $-0x1, %eax
je 0x37304
movl %eax, %ebp
movl %ebp, %r14d
jmp 0x3730a
movq 0x8(%r14), %r14
movq (%r14), %rdi
callq 0x22a71
movq %rax, %r15
movq (%r14), %rax
movl 0x48(%rax), %esi
addl 0x28(%rax), %esi
movq %rbx, %rdi
callq 0x363a7
movl $0xffffffff, %r14d      # imm = 0xFFFFFFFF
cmpl $-0x1, %eax
je 0x3730a
movl %eax, %ebp
movq %r15, %rdi
callq 0x22acf
testq %rax, %rax
je 0x3731c
movq (%rax), %rsi
movq 0x8(%rax), %r13
movq %rbx, %rdi
callq 0x36bad
cmpl $-0x1, %eax
je 0x3730a
movl %eax, %r12d
movsd (%r13), %xmm0
movq %rbx, %rdi
callq 0x36cff
xorl %ecx, %ecx
cmpl $-0x1, %eax
je 0x372a9
movl %eax, %ecx
addl %ebp, %r12d
addl %ecx, %r12d
movl %r12d, %ebp
cmpl $-0x1, %eax
jne 0x3726a
jmp 0x3730a
movq 0x8(%r14), %r15
movl 0x28(%r15), %esi
movq %rbx, %rdi
callq 0x363a7
cmpl $-0x1, %eax
je 0x37304
movl %eax, %ebp
leaq 0x8(%rsp), %r14
movq %r15, %rdi
movq %r14, %rsi
callq 0x20637
movq %r14, %rdi
callq 0x20654
testq %rax, %rax
je 0x37231
movq 0x10(%rax), %rsi
movq %rbx, %rdi
callq 0x36bad
addl %eax, %ebp
cmpl $-0x1, %eax
jne 0x372e0
movl $0xffffffff, %r14d      # imm = 0xFFFFFFFF
movl %r14d, %eax
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %r15, %rdi
callq 0x22b86
jmp 0x37231
leaq 0x600e3(%rip), %rdi     # 0x97413
leaq 0x61761(%rip), %rsi     # 0x98a98
movl $0x35d, %edx            # imm = 0x35D
jmp 0x37366
leaq 0x617b3(%rip), %rdi     # 0x98af8
leaq 0x6174c(%rip), %rsi     # 0x98a98
movl $0x312, %edx            # imm = 0x312
jmp 0x37366
leaq 0x61786(%rip), %rdi     # 0x98ae0
leaq 0x61737(%rip), %rsi     # 0x98a98
movl $0x2f5, %edx            # imm = 0x2F5
callq 0x4cae0
movl $0x1, %edi
callq 0x1f3b0