// File: /workspace/github_c_makefile_star2_O2/nilyang[P]redis-tdd-annotation/src/networking.c
// Function: addReply
void addReply(redisClient *c, robj *obj) {

    // 为客户端安装写处理器到事件循环
    if (prepareClientToWrite(c) != REDIS_OK) return;

    /* This is an important place where we can avoid copy-on-write
     * when there is a saving child running, avoiding touching the
     * refcount field of the object if it's not needed.
     *
     * 如果在使用子进程，那么尽可能地避免修改对象的 refcount 域。
     *
     * If the encoding is RAW and there is room in the static buffer
     * we'll be able to send the object to the client without
     * messing with its page. 
     *
     * 如果对象的编码为 RAW ，并且静态缓冲区中有空间
     * 那么就可以在不弄乱内存页的情况下，将对象发送给客户端。
     */
    if (sdsEncodedObject(obj)) {
        // 首先尝试复制内容到 c->buf 中，这样可以避免内存分配
        if (_addReplyToBuffer(c,obj->ptr,sdslen(obj->ptr)) != REDIS_OK)
            // 如果 c->buf 中的空间不够，就复制到 c->reply 链表中
            // 可能会引起内存分配
            _addReplyObjectToList(c,obj);
    } else if (obj->encoding == REDIS_ENCODING_INT) {
        /* Optimization: if there is room in the static buffer for 32 bytes
         * (more than the max chars a 64 bit integer can take as string) we
         * avoid decoding the object and go for the lower level approach. */
        // 优化，如果 c->buf 中有等于或多于 32 个字节的空间
        // 那么将整数直接以字符串的形式复制到 c->buf 中
        if (listLength(c->reply) == 0 && (sizeof(c->buf) - c->bufpos) >= 32) {
            char buf[32];
            int len;

            len = ll2string(buf,sizeof(buf),(long)obj->ptr);
            if (_addReplyToBuffer(c,buf,len) == REDIS_OK)
                return;
            /* else... continue with the normal code path, but should never
             * happen actually since we verified there is room. */
        }
        // 执行到这里，代表对象是整数，并且长度大于 32 位
        // 将它转换为字符串
        obj = getDecodedObject(obj);
        // 保存到缓存中
        if (_addReplyToBuffer(c,obj->ptr,sdslen(obj->ptr)) != REDIS_OK)
            _addReplyObjectToList(c,obj);
        decrRefCount(obj);
    } else {
        redisPanic("Wrong obj->encoding in addReply()");
    }
}

// Assembly:
pushq %r15
pushq %r14
pushq %rbx
subq $0x20, %rsp
movq %rsi, %r14
movq %rdi, %rbx
callq 0x2bb2e
testl %eax, %eax
je 0x2c12f
addq $0x20, %rsp
popq %rbx
popq %r14
popq %r15
retq
movl (%r14), %eax
shrl $0x4, %eax
andl $0xf, %eax
cmpl $0x8, %eax
je 0x2c14a
cmpl $0x1, %eax
je 0x2c172
testl %eax, %eax
jne 0x2c1ef
movq 0x8(%r14), %rsi
movslq -0x8(%rsi), %rdx
movq %rbx, %rdi
callq 0x2bddc
testl %eax, %eax
je 0x2c125
movq %rbx, %rdi
movq %r14, %rsi
addq $0x20, %rsp
popq %rbx
popq %r14
popq %r15
jmp 0x2be3e
movq 0x60(%rbx), %rax
cmpq $0x0, 0x28(%rax)
jne 0x2c1b8
movslq 0x170(%rbx), %rax
addq $-0x4001, %rax          # imm = 0xBFFF
cmpq $-0x21, %rax
ja 0x2c1b8
movq 0x8(%r14), %rdx
movq %rsp, %r15
pushq $0x20
popq %rsi
movq %r15, %rdi
callq 0x2e511
movslq %eax, %rdx
movq %rbx, %rdi
movq %r15, %rsi
callq 0x2bddc
testl %eax, %eax
je 0x2c125
movq %r14, %rdi
callq 0x2f087
movq %rax, %r14
movq 0x8(%rax), %rsi
movslq -0x8(%rsi), %rdx
movq %rbx, %rdi
callq 0x2bddc
testl %eax, %eax
je 0x2c1e2
movq %rbx, %rdi
movq %r14, %rsi
callq 0x2be3e
movq %r14, %rdi
callq 0x2ee1f
jmp 0x2c125
leaq 0x60b9b(%rip), %rdi     # 0x8cd91
leaq 0x60b71(%rip), %rsi     # 0x8cd6e
movl $0x1c7, %edx            # imm = 0x1C7
callq 0x490e8
pushq $0x1
popq %rdi
callq 0x1f3b0