LLM4Binary/decompile-bench-makefile huggingface dataset:
// File: /workspace/github_c_makefile_star2_O2/nilyang[P]redis-tdd-annotation/src/redis.c
// Function: bytesToHuman
void bytesToHuman(char *s, unsigned long long n) {
    double d;

    if (n < 1024) {
        /* Bytes */
        sprintf(s,"%lluB",n);
        return;
    } else if (n < (1024*1024)) {
        d = (double)n/(1024);
        sprintf(s,"%.2fK",d);
    } else if (n < (1024LL*1024*1024)) {
        d = (double)n/(1024*1024);
        sprintf(s,"%.2fM",d);
    } else if (n < (1024LL*1024*1024*1024)) {
        d = (double)n/(1024LL*1024*1024);
        sprintf(s,"%.2fG",d);
    }
}

// Assembly:
movq %rsi, %rdx
cmpq $0x3ff, %rsi            # imm = 0x3FF
ja 0x259ac
leaq 0x65b5e(%rip), %rsi     # 0x8b503
xorl %eax, %eax
jmp 0x1f570
cmpq $0xfffff, %rdx          # imm = 0xFFFFF
ja 0x259cb
cvtsi2sd %rdx, %xmm0
mulsd 0x648a6(%rip), %xmm0    # 0x8a268
leaq 0x65b40(%rip), %rsi     # 0x8b509
jmp 0x25a07
cmpq $0x3fffffff, %rdx       # imm = 0x3FFFFFFF
ja 0x259ea
cvtsi2sd %rdx, %xmm0
mulsd 0x6487f(%rip), %xmm0    # 0x8a260
leaq 0x65b27(%rip), %rsi     # 0x8b50f
jmp 0x25a07
movq %rdx, %rax
shrq $0x28, %rax
jne 0x25a0e
cvtsi2sd %rdx, %xmm0
mulsd 0x64858(%rip), %xmm0    # 0x8a258
leaq 0x65b0e(%rip), %rsi     # 0x8b515
movb $0x1, %al
jmp 0x1f570
retq
// File: /workspace/github_c_makefile_star2_O2/nilyang[P]redis-tdd-annotation/src/redis.c
// Function: redisAsciiArt
void redisAsciiArt(void) {
#include "asciilogo.h"
    char *buf = zmalloc(1024*16);
    char *mode = "stand alone";

    if (server.cluster_enabled) mode = "cluster";
    else if (server.sentinel_mode) mode = "sentinel";

    snprintf(buf,1024*16,ascii_logo,
        REDIS_VERSION,
        redisGitSHA1(),
        strtol(redisGitDirty(),NULL,10) > 0,
        (sizeof(long) == 8) ? "64" : "32",
        mode, server.port,
        (long) getpid()
    );
    redisLogRaw(REDIS_NOTICE|REDIS_LOG_RAW,buf);
    zfree(buf);
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r12
pushq %rbx
movl $0x4000, %edi           # imm = 0x4000
callq 0x2828d
cmpl $0x0, 0xa0513(%rip)     # 0xc702c
leaq 0x65c33(%rip), %rcx     # 0x8c753
leaq 0x6eb27(%rip), %rdx     # 0x9564e
cmoveq %rcx, %rdx
cmpl $0x0, 0xa0c32(%rip)     # 0xc7764
movq %rax, %rbx
leaq 0x63aab(%rip), %r15     # 0x8a5e7
cmoveq %rdx, %r15
callq 0x2b740
movq %rax, %r14
callq 0x2b748
pushq $0xa
popq %rdx
movq %rax, %rdi
xorl %esi, %esi
callq 0x1f6d0
xorl %ebp, %ebp
testq %rax, %rax
setg %bpl
movl 0xa04c6(%rip), %r12d    # 0xc7030
callq 0x1f410
movslq %eax, %r10
leaq 0x65be6(%rip), %r11     # 0x8c75f
leaq 0x65766(%rip), %rdx     # 0x8c2e6
leaq 0x65df3(%rip), %rcx     # 0x8c97a
movl $0x4000, %esi           # imm = 0x4000
movq %rbx, %rdi
movq %r14, %r8
movl %ebp, %r9d
xorl %eax, %eax
pushq %r10
pushq %r12
pushq %r15
pushq %r11
callq 0x1f120
addq $0x20, %rsp
movl $0x402, %edi            # imm = 0x402
movq %rbx, %rsi
callq 0x224d3
movq %rbx, %rdi
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
jmp 0x283cd
// File: /workspace/github_c_makefile_star2_O2/nilyang[P]redis-tdd-annotation/src/redis.c
// Function: loadDataFromDisk
void loadDataFromDisk(void) {
    // 记录开始时间
    long long start = ustime();

    // AOF 持久化已打开？
    if (server.aof_state == REDIS_AOF_ON) {
        // 尝试载入 AOF 文件
        if (loadAppendOnlyFile(server.aof_filename) == REDIS_OK)
            // 打印载入信息，并计算载入耗时长度
            redisLog(REDIS_NOTICE,"DB loaded from append only file: %.3f seconds",(float)(ustime()-start)/1000000);
    // AOF 持久化未打开
    } else {
        // 尝试载入 RDB 文件
        if (rdbLoad(server.rdb_filename) == REDIS_OK) {
            // 打印载入信息，并计算载入耗时长度
            redisLog(REDIS_NOTICE,"DB loaded from disk: %.3f seconds",
                (float)(ustime()-start)/1000000);
        } else if (errno != ENOENT) {
            redisLog(REDIS_WARNING,"Fatal error loading the DB: %s. Exiting.",strerror(errno));
            exit(1);
        }
    }
}

// Assembly:
pushq %r14
pushq %rbx
pushq %rax
callq 0x22820
movq %rax, %rbx
cmpl $0x1, 0xa082a(%rip)     # 0xc7478
jne 0x26c69
movq 0xa0829(%rip), %rdi     # 0xc7480
callq 0x465b7
testl %eax, %eax
jne 0x26c85
leaq 0x65b15(%rip), %r14     # 0x8c77c
jmp 0x26c94
movq 0xa08c0(%rip), %rdi     # 0xc7530
callq 0x35a8b
testl %eax, %eax
je 0x26c8d
callq 0x1f810
movl (%rax), %edi
cmpl $0x2, %edi
jne 0x26cc1
addq $0x8, %rsp
popq %rbx
popq %r14
retq
leaq 0x65b16(%rip), %r14     # 0x8c7aa
callq 0x22820
subq %rbx, %rax
cvtsi2ss %rax, %xmm0
divss 0x635cf(%rip), %xmm0    # 0x8a278
cvtss2sd %xmm0, %xmm0
pushq $0x2
popq %rdi
movq %r14, %rsi
movb $0x1, %al
addq $0x8, %rsp
popq %rbx
popq %r14
jmp 0x22613
callq 0x1f630
leaq 0x65aff(%rip), %rsi     # 0x8c7cc
pushq $0x3
popq %rdi
movq %rax, %rdx
xorl %eax, %eax
callq 0x22613
pushq $0x1
popq %rdi
callq 0x1f2b0
// File: /workspace/github_c_makefile_star2_O2/nilyang[P]redis-tdd-annotation/src/sds.c
// Function: sdsnewlen
sds sdsnewlen(const void *init, size_t initlen) {

    struct sdshdr *sh;

    // 根据是否有初始化内容，选择适当的内存分配方式
    // T = O(N)
    if (init) {
        // zmalloc 不初始化所分配的内存
        sh = zmalloc(sizeof(struct sdshdr)+initlen+1);
    } else {
        // zcalloc 将分配的内存全部初始化为 0
        sh = zcalloc(sizeof(struct sdshdr)+initlen+1);
    }

    // 内存分配失败，返回
    if (sh == NULL) return NULL;

    // 设置初始化长度
    sh->len = initlen;
    // 新 sds 不预留任何空间
    sh->free = 0;
    // 如果有指定初始化内容，将它们复制到 sdshdr 的 buf 中
    // T = O(N)
    if (initlen && init)
        memcpy(sh->buf, init, initlen);
    // 以 \0 结尾
    sh->buf[initlen] = '\0';

    // 返回 buf 部分，而不是整个 sdshdr
    return (char*)sh->buf;
}

// Assembly:
pushq %r15
pushq %r14
pushq %rbx
movq %rsi, %rbx
movq %rdi, %r14
leaq 0x9(%rsi), %rdi
testq %r14, %r14
je 0x27173
callq 0x2828d
jmp 0x27178
callq 0x282df
movq %rax, %r15
testq %rax, %rax
je 0x271b3
testq %r14, %r14
sete %al
movl %ebx, (%r15)
andl $0x0, 0x4(%r15)
testq %rbx, %rbx
sete %cl
orb %al, %cl
jne 0x271a7
leaq 0x8(%r15), %rdi
movq %r14, %rsi
movq %rbx, %rdx
callq 0x1fbd0
movb $0x0, 0x8(%r15,%rbx)
addq $0x8, %r15
jmp 0x271b6
xorl %r15d, %r15d
movq %r15, %rax
popq %rbx
popq %r14
popq %r15
retq
// File: /workspace/github_c_makefile_star2_O2/nilyang[P]redis-tdd-annotation/src/sds.c
// Function: sdsIncrLen
void sdsIncrLen(sds s, int incr) {
    struct sdshdr *sh = (void*) (s-(sizeof(struct sdshdr)));

    // 确保 sds 空间足够
    assert(sh->free >= incr);

    // 更新属性
    sh->len += incr;
    sh->free -= incr;

    // 这个 assert 其实可以忽略
    // 因为前一个 assert 已经确保 sh->free - incr >= 0 了
    assert(sh->free >= 0);

    // 放置新的结尾符号
    s[sh->len] = '\0';
}

// Assembly:
pushq %rax
movl -0x4(%rdi), %eax
cmpl %esi, %eax
jl 0x272cf
movslq -0x8(%rdi), %rdx
movslq %esi, %rcx
addq %rdx, %rcx
movl %ecx, -0x8(%rdi)
subl %esi, %eax
movl %eax, -0x4(%rdi)
js 0x272ee
movb $0x0, (%rdi,%rcx)
popq %rax
retq
leaq 0x658b6(%rip), %rdi     # 0x8cb8c
leaq 0x658c0(%rip), %rsi     # 0x8cb9d
leaq 0x658bf(%rip), %rcx     # 0x8cba3
movl $0x164, %edx            # imm = 0x164
callq 0x1f2c0
leaq 0x658c8(%rip), %rdi     # 0x8cbbd
leaq 0x658a1(%rip), %rsi     # 0x8cb9d
leaq 0x658a0(%rip), %rcx     # 0x8cba3
movl $0x16c, %edx            # imm = 0x16C
callq 0x1f2c0
// File: /workspace/github_c_makefile_star2_O2/nilyang[P]redis-tdd-annotation/src/sds.c
// Function: sdsgrowzero
sds sdsgrowzero(sds s, size_t len) {
    struct sdshdr *sh = (void*)(s-(sizeof(struct sdshdr)));
    size_t totlen, curlen = sh->len;

    // 如果 len 比字符串的现有长度小，
    // 那么直接返回，不做动作
    if (len <= curlen) return s;

    // 扩展 sds
    // T = O(N)
    s = sdsMakeRoomFor(s,len-curlen);
    // 如果内存不足，直接返回
    if (s == NULL) return NULL;

    /* Make sure added region doesn't contain garbage */
    // 将新分配的空间用 0 填充，防止出现垃圾内容
    // T = O(N)
    sh = (void*)(s-(sizeof(struct sdshdr)));
    memset(s+curlen,0,(len-curlen+1)); /* also set trailing \0 byte */

    // 更新属性
    totlen = sh->len+sh->free;
    sh->len = len;
    sh->free = totlen-sh->len;

    // 返回新的 sds
    return s;
}

// Assembly:
pushq %r15
pushq %r14
pushq %r12
pushq %rbx
pushq %rax
movq %rdi, %rbx
movslq -0x8(%rdi), %r12
movq %rsi, %r15
subq %r12, %r15
jbe 0x2735e
movq %rsi, %r14
movq %rbx, %rdi
movq %r15, %rsi
callq 0x2722a
testq %rax, %rax
je 0x2735c
movq %rax, %rbx
addq %rax, %r12
incq %r15
movq %r12, %rdi
xorl %esi, %esi
movq %r15, %rdx
callq 0x1f110
movl -0x8(%rbx), %eax
movl %r14d, -0x8(%rbx)
subl %r14d, %eax
addl %eax, -0x4(%rbx)
jmp 0x2735e
xorl %ebx, %ebx
movq %rbx, %rax
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
retq
// File: /workspace/github_c_makefile_star2_O2/nilyang[P]redis-tdd-annotation/src/sds.c
// Function: sdscatlen
sds sdscatlen(sds s, const void *t, size_t len) {
    
    struct sdshdr *sh;
    
    // 原有字符串长度
    size_t curlen = sdslen(s);

    // 扩展 sds 空间
    // T = O(N)
    s = sdsMakeRoomFor(s,len);

    // 内存不足？直接返回
    if (s == NULL) return NULL;

    // 复制 t 中的内容到字符串后部
    // T = O(N)
    sh = (void*) (s-(sizeof(struct sdshdr)));
    memcpy(s+curlen, t, len);

    // 更新属性
    sh->len = curlen+len;
    sh->free = sh->free-len;

    // 添加新结尾符号
    s[curlen+len] = '\0';

    // 返回新 sds
    return s;
}

// Assembly:
pushq %r15
pushq %r14
pushq %r12
pushq %rbx
pushq %rax
movq %rdx, %rbx
movq %rsi, %r15
movslq -0x8(%rdi), %r12
movq %rdx, %rsi
callq 0x2722a
movq %rax, %r14
testq %rax, %rax
je 0x273b0
movq %r14, %rdi
addq %r12, %rdi
movq %r15, %rsi
movq %rbx, %rdx
callq 0x1fbd0
addq %rbx, %r12
movl %r12d, -0x8(%r14)
subl %ebx, -0x4(%r14)
movb $0x0, (%r14,%r12)
movq %r14, %rax
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
retq
// File: /workspace/github_c_makefile_star2_O2/nilyang[P]redis-tdd-annotation/src/sds.c
// Function: sdscpylen
sds sdscpylen(sds s, const char *t, size_t len) {

    struct sdshdr *sh = (void*) (s-(sizeof(struct sdshdr)));

    // sds 现有 buf 的长度
    size_t totlen = sh->free+sh->len;

    // 如果 s 的 buf 长度不满足 len ，那么扩展它
    if (totlen < len) {
        // T = O(N)
        s = sdsMakeRoomFor(s,len-sh->len);
        if (s == NULL) return NULL;
        sh = (void*) (s-(sizeof(struct sdshdr)));
        totlen = sh->free+sh->len;
    }

    // 复制内容
    // T = O(N)
    memcpy(s, t, len);

    // 添加终结符号
    s[len] = '\0';

    // 更新属性
    sh->len = len;
    sh->free = totlen-len;

    // 返回新的 sds
    return s;
}

// Assembly:
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
movq %rdx, %r14
movq %rsi, %r15
movq %rdi, %rbx
movslq -0x4(%rdi), %r12
movslq -0x8(%rdi), %rax
addq %rax, %r12
cmpq %rdx, %r12
jae 0x27438
movq %r14, %rsi
subq %rax, %rsi
movq %rbx, %rdi
callq 0x2722a
testq %rax, %rax
je 0x27467
movq %rax, %rbx
movq %rax, %r13
addq $-0x8, %r13
movl -0x8(%rax), %r12d
addl -0x4(%rax), %r12d
jmp 0x2743c
leaq -0x8(%rbx), %r13
movq %rbx, %rdi
movq %r15, %rsi
movq %r14, %rdx
callq 0x1fbd0
movb $0x0, (%rbx,%r14)
movl %r14d, -0x8(%rbx)
subl %r14d, %r12d
movl %r12d, 0x4(%r13)
movq %rbx, %rax
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
retq
xorl %ebx, %ebx
jmp 0x2745a
// File: /workspace/github_c_makefile_star2_O2/nilyang[P]redis-tdd-annotation/src/sds.c
// Function: sdscatvprintf
sds sdscatvprintf(sds s, const char *fmt, va_list ap) {
    va_list cpy;
    char staticbuf[1024], *buf = staticbuf, *t;
    size_t buflen = strlen(fmt)*2;

    /* We try to start using a static buffer for speed.
     * If not possible we revert to heap allocation. */
    if (buflen > sizeof(staticbuf)) {
        buf = zmalloc(buflen);
        if (buf == NULL) return NULL;
    } else {
        buflen = sizeof(staticbuf);
    }

    /* Try with buffers two times bigger every time we fail to
     * fit the string in the current buffer size. */
    while(1) {
        buf[buflen-2] = '\0';
        va_copy(cpy,ap);
        // T = O(N)
        vsnprintf(buf, buflen, fmt, cpy);
        if (buf[buflen-2] != '\0') {
            if (buf != staticbuf) zfree(buf);
            buflen *= 2;
            buf = zmalloc(buflen);
            if (buf == NULL) return NULL;
            continue;
        }
        break;
    }

    /* Finally concat the obtained string to the SDS string and return it. */
    t = sdscat(s, buf);
    if (buf != staticbuf) zfree(buf);
    return t;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x438, %rsp            # imm = 0x438
movq %rdx, %r14
movq %rsi, %r15
movq %rdi, 0x8(%rsp)
movq %rsi, %rdi
callq 0x1f4f0
movq %rax, %rbx
addq %rax, %rbx
movl $0x400, %ebp            # imm = 0x400
leaq 0x30(%rsp), %r12
movq %r12, %r13
cmpq $0x401, %rbx            # imm = 0x401
jb 0x275ac
movq %rbx, %rdi
callq 0x2828d
movq %rax, %r13
movq %rbx, %rbp
testq %rax, %rax
je 0x27602
leaq 0x10(%rsp), %rbx
movb $0x0, -0x2(%rbp,%r13)
movq 0x10(%r14), %rax
movq %rax, 0x20(%rsp)
movups (%r14), %xmm0
movaps %xmm0, 0x10(%rsp)
movq %r13, %rdi
movq %rbp, %rsi
movq %r15, %rdx
movq %rbx, %rcx
callq 0x1f7b0
cmpb $0x0, -0x2(%rbp,%r13)
je 0x27606
cmpq %r12, %r13
je 0x275ef
movq %r13, %rdi
callq 0x283cd
addq %rbp, %rbp
movq %rbp, %rdi
callq 0x2828d
movq %rax, %r13
testq %rax, %rax
jne 0x275b1
xorl %ebx, %ebx
jmp 0x27628
movq 0x8(%rsp), %rdi
movq %r13, %rsi
callq 0x273bf
movq %rax, %rbx
leaq 0x30(%rsp), %rax
cmpq %rax, %r13
je 0x27628
movq %r13, %rdi
callq 0x283cd
movq %rbx, %rax
addq $0x438, %rsp            # imm = 0x438
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/sds.c
// Function: sdstrim
sds sdstrim(sds s, const char *cset) {
    struct sdshdr *sh = (void*) (s-(sizeof(struct sdshdr)));
    char *start, *end, *sp, *ep;
    size_t len;

    // 设置和记录指针
    sp = start = s;
    ep = end = s+sdslen(s)-1;

    // 修剪, T = O(N^2)
    while(sp <= end && strchr(cset, *sp)) sp++;
    while(ep > start && strchr(cset, *ep)) ep--;

    // 计算 trim 完毕之后剩余的字符串长度
    len = (sp > ep) ? 0 : ((ep-sp)+1);
    
    // 如果有需要，前移字符串内容
    // T = O(N)
    if (sh->buf != sp) memmove(sh->buf, sp, len);

    // 添加终结符
    sh->buf[len] = '\0';

    // 更新属性
    sh->free = sh->free+(sh->len-len);
    sh->len = len;

    // 返回修剪后的 sds
    return s;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
pushq %rax
movq %rsi, %r15
movq %rdi, %rbx
movslq -0x8(%rdi), %r14
leaq (%rdi,%r14), %rbp
decq %rbp
xorl %r13d, %r13d
leaq (%rbx,%r13), %r12
cmpq %rbp, %r12
ja 0x279da
movsbl (%r12), %esi
movq %r15, %rdi
callq 0x1f790
testq %rax, %rax
je 0x279da
incq %r13
jmp 0x279ba
subq %r13, %r14
cmpq %rbx, %rbp
jbe 0x279fb
movsbl (%rbp), %esi
movq %r15, %rdi
callq 0x1f790
testq %rax, %rax
je 0x279fb
decq %rbp
decq %r14
jmp 0x279dd
xorl %eax, %eax
cmpq %rbp, %r12
cmovaq %rax, %r14
testq %r13, %r13
je 0x27a17
movq %rbx, %rdi
movq %r12, %rsi
movq %r14, %rdx
callq 0x1f780
movb $0x0, (%rbx,%r14)
movl -0x4(%rbx), %eax
subl %r14d, %eax
addl -0x8(%rbx), %eax
movl %eax, -0x4(%rbx)
movl %r14d, -0x8(%rbx)
movq %rbx, %rax
addq $0x8, %rsp
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/./sds.h
// Function: sdsrange
static inline size_t sdslen(const sds s) {
    //1. 通过指针运算，将指针向前移动到 struct sdshdr 的开始地址
    //2. 通过(void*)将这个指针转换为void指针，然后赋值给结构体，这样便转换成了结构体指针
    struct sdshdr *sh = (void*)(s-(sizeof(struct sdshdr)));
    return sh->len;
}

// Assembly:
movl -0x8(%rdi), %ecx
testl %ecx, %ecx
je 0x27ace
pushq %r14
pushq %rbx
pushq %rax
movq %rdi, %rbx
leal (%rcx,%rsi), %eax
xorl %r14d, %r14d
testl %eax, %eax
cmovlel %r14d, %eax
testl %esi, %esi
cmovnsl %esi, %eax
leal (%rcx,%rdx), %esi
testl %esi, %esi
cmovlel %r14d, %esi
testl %edx, %edx
cmovnsl %edx, %esi
movl %esi, %edx
subl %eax, %edx
leal 0x1(%rdx), %edi
cmovbl %r14d, %edi
movl %ecx, %edx
subl %eax, %edx
jle 0x27ab2
testl %edi, %edi
je 0x27ab2
leal -0x1(%rcx), %r8d
xorl %r9d, %r9d
cmpl %r8d, %eax
cmoval %r9d, %edx
cmpl %ecx, %esi
cmovbl %edi, %edx
movslq %edx, %r14
testl %eax, %eax
je 0x27ab2
testl %edx, %edx
je 0x27ab2
movl %eax, %esi
addq %rbx, %rsi
movq %rbx, %rdi
movq %r14, %rdx
callq 0x1f780
movb $0x0, (%rbx,%r14)
movl -0x4(%rbx), %eax
subl %r14d, %eax
addl -0x8(%rbx), %eax
movl %eax, -0x4(%rbx)
movl %r14d, -0x8(%rbx)
addq $0x8, %rsp
popq %rbx
popq %r14
retq
// File: /workspace/github_c_makefile_star2_O2/nilyang[P]redis-tdd-annotation/src/sds.c
// Function: sdsfreesplitres
void sdsfreesplitres(sds *tokens, int count) {
    if (!tokens) return;
    while(count--)
        sdsfree(tokens[count]);
    zfree(tokens);
}

// Assembly:
testq %rdi, %rdi
je 0x27d50
pushq %r14
pushq %rbx
pushq %rax
movq %rdi, %rbx
movslq %esi, %r14
decq %r14
cmpq $-0x1, %r14
je 0x27d41
movq (%rbx,%r14,8), %rdi
callq 0x271f7
jmp 0x27d2d
movq %rbx, %rdi
addq $0x8, %rsp
popq %rbx
popq %r14
jmp 0x283cd
retq
// File: /workspace/github_c_makefile_star2_O2/nilyang[P]redis-tdd-annotation/src/zmalloc.c
// Function: zmalloc_get_private_dirty
size_t zmalloc_get_private_dirty(void) {
    char line[1024];
    size_t pd = 0;
    FILE *fp = fopen("/proc/self/smaps","r");

    if (!fp) return 0;
    while(fgets(line,sizeof(line),fp) != NULL) {
        if (strncmp(line,"Private_Dirty:",14) == 0) {
            char *p = strchr(line,'k');
            if (p) {
                *p = '\0';
                pd += strtol(line+14,NULL,10) * 1024;
            }
        }
    }
    fclose(fp);
    return pd;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x408, %rsp            # imm = 0x408
leaq 0x64642(%rip), %rdi     # 0x8cbf3
leaq 0x6461b(%rip), %rsi     # 0x8cbd3
callq 0x1f360
testq %rax, %rax
je 0x28634
movq %rax, %r14
xorl %ebx, %ebx
movq %rsp, %r12
leaq 0x64633(%rip), %r13     # 0x8cc04
pushq $0xe
popq %rbp
pushq $0x6b
popq %r15
movq %r12, %rdi
movl $0x400, %esi            # imm = 0x400
movq %r14, %rdx
callq 0x1f430
testq %rax, %rax
je 0x2862a
movq %r12, %rdi
movq %r13, %rsi
movq %rbp, %rdx
callq 0x1f6a0
testl %eax, %eax
jne 0x285d8
movq %r12, %rdi
movl %r15d, %esi
callq 0x1f790
testq %rax, %rax
je 0x285d8
movb $0x0, (%rax)
leaq 0xe(%rsp), %rdi
xorl %esi, %esi
pushq $0xa
popq %rdx
callq 0x1f6d0
shlq $0xa, %rax
addq %rax, %rbx
jmp 0x285d8
movq %r14, %rdi
callq 0x1f9a0
jmp 0x28636
xorl %ebx, %ebx
movq %rbx, %rax
addq $0x408, %rsp            # imm = 0x408
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/zipmap.c
// Function: zipmapLookupRaw
static unsigned char *zipmapLookupRaw(unsigned char *zm, unsigned char *key, unsigned int klen, unsigned int *totlen) {

    // zm+1 略过 <zmlen> 属性，将 p 指向 zipmap 的首个节点
    unsigned char *p = zm+1, *k = NULL;
    unsigned int l,llen;

    // 遍历整个 zipmap 来寻找
    // T = O(N^2)
    while(*p != ZIPMAP_END) {
        unsigned char free;

        /* Match or skip the key */
        // 计算键的长度
        l = zipmapDecodeLength(p);
        // 计算编码键的长度所需的字节数
        llen = zipmapEncodeLength(NULL,l);
        // 对比 key
        // T = O(N)
        if (key != NULL && k == NULL && l == klen && !memcmp(p+llen,key,l)) {
            /* Only return when the user doesn't care
             * for the total length of the zipmap. */
            if (totlen != NULL) {
                // 如果调用者需要知道整个 zipmap 的长度，那么记录找到的指针到变量 k
                // 之后遍历时，程序只计算 zipmap 剩余节点的长度，不再用 memcmp 进行对比
                // 因为 k 已经不为 NULL 了
                k = p;
            } else {
                // 如果调用者不需要知道整个 zipmap 的长度，那么直接返回 p 
                return p;
            }
        }

        // 越过键节点，指向值节点
        p += llen+l;

        /* Skip the value as well */
        // 计算值的长度
        l = zipmapDecodeLength(p);
        // 计算编码值的长度所需的字节数，
        // 并移动指针 p ，越过该 <len> 属性，指向 <free> 属性
        p += zipmapEncodeLength(NULL,l);
        // 取出 <free> 属性的值
        free = p[0];
        // 略过值节点，指向下一节点
        p += l+1+free; /* +1 to skip the free byte */
    }

    // 计算并记录 zipmap 的空间长度
    // + 1 是将 ZIPMAP_END 也计算在内
    if (totlen != NULL) *totlen = (unsigned int)(p-zm)+1;

    // 返回找到 key 的指针
    return k;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x18, %rsp
movq %rcx, %rbp
movl %edx, %r15d
movq %rsi, %r12
movq %rdi, 0x8(%rsp)
leaq 0x1(%rdi), %r13
movl %edx, %eax
movq %rax, 0x10(%rsp)
xorl %eax, %eax
movzbl (%r13), %r14d
cmpl $0xfe, %r14d
je 0x292a4
cmpl $0xff, %r14d
jne 0x292a8
jmp 0x2933f
movl 0x1(%r13), %r14d
xorl %edx, %edx
cmpl $0xfe, %r14d
setae %dl
leal 0x1(,%rdx,4), %ebx
testq %r12, %r12
je 0x292fc
testq %rax, %rax
jne 0x292fc
cmpl %r15d, %r14d
jne 0x292fa
testq %rbp, %rbp
sete 0x7(%rsp)
movl %ebx, %edi
addq %r13, %rdi
movq %r12, %rsi
movq 0x10(%rsp), %rdx
callq 0x1f6a0
testl %eax, %eax
sete %dl
movl $0x0, %eax
cmoveq %r13, %rax
testb %dl, 0x7(%rsp)
je 0x292fc
jmp 0x29352
xorl %eax, %eax
addl %r14d, %ebx
leaq (%rbx,%r13), %rdx
movzbl (%r13,%rbx), %r8d
cmpl $0xfd, %r8d
jbe 0x29316
movl 0x1(%rdx), %r8d
xorl %r10d, %r10d
cmpl $0xfe, %r8d
setae %r10b
leaq (%rdx,%r10,4), %rdi
movzbl 0x1(%rdx,%r10,4), %edx
addl %r8d, %edx
incl %edx
leaq (%rdx,%rdi), %r13
incq %r13
jmp 0x29288
testq %rbp, %rbp
je 0x29355
subl 0x8(%rsp), %r13d
incl %r13d
movl %r13d, (%rbp)
jmp 0x29355
movq %r13, %rax
addq $0x18, %rsp
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/zipmap.c
// Function: zipmapGet
int zipmapGet(unsigned char *zm, unsigned char *key, unsigned int klen, unsigned char **value, unsigned int *vlen) {
    unsigned char *p;

    // 在 zipmap 中按 key 查找
    // 没找到直接返回 0 
    // T = O(N^2)
    if ((p = zipmapLookupRaw(zm,key,klen,NULL)) == NULL) return 0;

    // 越过键，指向值
    p += zipmapRawKeyLength(p);
    // 取出值的长度
    *vlen = zipmapDecodeLength(p);
    // 将 *value 指向值， +1 为越过 <free> 属性
    *value = p + ZIPMAP_LEN_BYTES(*vlen) + 1;

    // 找到，返回 1 
    return 1;
}

// Assembly:
pushq %r15
pushq %r14
pushq %rbx
movq %r8, %r14
movq %rcx, %rbx
xorl %r15d, %r15d
xorl %ecx, %ecx
callq 0x2925f
testq %rax, %rax
je 0x29559
movq %rax, %rcx
movzbl (%rax), %edx
cmpl $0xfd, %edx
jbe 0x29519
movl 0x1(%rcx), %edx
xorl %esi, %esi
cmpl $0xfe, %edx
setae %sil
leal (%rdx,%rsi,4), %edx
incl %edx
addq %rdx, %rax
movzbl (%rcx,%rdx), %ecx
cmpl $0xfd, %ecx
jbe 0x2953c
movl 0x1(%rax), %ecx
movl %ecx, (%r14)
xorl %edx, %edx
cmpl $0xfe, %ecx
setae %dl
leaq (%rax,%rdx,4), %rax
addq $0x2, %rax
movq %rax, (%rbx)
pushq $0x1
popq %r15
movl %r15d, %eax
popq %rbx
popq %r14
popq %r15
retq
// File: /workspace/github_c_makefile_star2_O2/nilyang[P]redis-tdd-annotation/src/zipmap.c
// Function: zipmapLen
unsigned int zipmapLen(unsigned char *zm) {

    unsigned int len = 0;

    if (zm[0] < ZIPMAP_BIGLEN) {
        // 长度可以用 1 字节保存
        // T = O(1)
        len = zm[0];
    } else {
        // 长度不能用 1 字节保存，需要遍历整个 zipmap
        // T = O(N)
        unsigned char *p = zipmapRewind(zm);
        while((p = zipmapNext(p,NULL,NULL,NULL,NULL)) != NULL) len++;

        /* Re-store length if small enough */
        // 如果字节数量已经少于 ZIPMAP_BIGLEN ，那么重新将值保存到 len 中
        // 这种情况在节点数超过 ZIPMAP_BIGLEN 之后，有节点被删除时会出现
        if (len < ZIPMAP_BIGLEN) zm[0] = len;
    }

    return len;
}

// Assembly:
pushq %r14
pushq %rbx
pushq %rax
movzbl (%rdi), %ebx
cmpl $0xfd, %ebx
jbe 0x295b2
movq %rdi, %r14
leaq 0x1(%rdi), %rax
pushq $-0x1
popq %rbx
movq %rax, %rdi
xorl %esi, %esi
xorl %edx, %edx
xorl %ecx, %ecx
xorl %r8d, %r8d
callq 0x29430
incl %ebx
testq %rax, %rax
jne 0x2958f
cmpl $0xfd, %ebx
ja 0x295b2
movb %bl, (%r14)
movl %ebx, %eax
addq $0x8, %rsp
popq %rbx
popq %r14
retq
// File: /workspace/github_c_makefile_star2_O2/nilyang[P]redis-tdd-annotation/src/sha1.c
// Function: SHA1Update
void SHA1Update(SHA1_CTX* context, const unsigned char* data, u_int32_t len)
{
    u_int32_t i, j;

    j = context->count[0];
    if ((context->count[0] += len << 3) < j)
        context->count[1]++;
    context->count[1] += (len>>29);
    j = (j >> 3) & 63;
    if ((j + len) > 63) {
        memcpy(&context->buffer[j], data, (i = 64-j));
        SHA1Transform(context->state, context->buffer);
        for ( ; i + 63 < len; i += 64) {
            SHA1Transform(context->state, &data[i]);
        }
        j = 0;
    }
    else i = 0;
    memcpy(&context->buffer[j], &data[i], len - i);
}

// Assembly:
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
movl %edx, %ebx
movq %rsi, %r14
movq %rdi, %r15
movl 0x14(%rdi), %eax
leal (,%rbx,8), %ecx
shrl $0x1d, %edx
addl %eax, %ecx
movl %ecx, 0x14(%rdi)
adcl %edx, 0x18(%rdi)
shrl $0x3, %eax
andl $0x3f, %eax
leal (%rax,%rbx), %ecx
cmpl $0x40, %ecx
jb 0x2a75e
leaq 0x1c(%r15), %r13
leaq (%r15,%rax), %rdi
addq $0x1c, %rdi
pushq $0x40
popq %r12
subl %eax, %r12d
movq %r14, %rsi
movq %r12, %rdx
callq 0x1fbd0
movq %r15, %rdi
movq %r13, %rsi
callq 0x295dc
xorl %r13d, %r13d
leal 0x3f(%r12), %eax
cmpl %ebx, %eax
jae 0x2a764
movl %r12d, %esi
addq %r14, %rsi
movq %r15, %rdi
callq 0x295dc
addl $0x40, %r12d
jmp 0x2a741
movl %eax, %r13d
xorl %r12d, %r12d
leaq (%r15,%r13), %rdi
addq $0x1c, %rdi
movl %r12d, %eax
addq %rax, %r14
subl %r12d, %ebx
movq %r14, %rsi
movq %rbx, %rdx
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
jmp 0x1fbd0
// File: /workspace/github_c_makefile_star2_O2/nilyang[P]redis-tdd-annotation/src/ziplist.c
// Function: ziplistPush
unsigned char *ziplistPush(unsigned char *zl, unsigned char *s, unsigned int slen, int where) {

    // 根据 where 参数的值，决定将值推入到表头还是表尾
    unsigned char *p;
    p = (where == ZIPLIST_HEAD) ? ZIPLIST_ENTRY_HEAD(zl) : ZIPLIST_ENTRY_END(zl);

    // 返回添加新值后的 ziplist
    // T = O(N^2)
    return __ziplistInsert(zl,p,s,slen);
}

// Assembly:
movl %ecx, %eax
movl %edx, %ecx
movq %rsi, %rdx
testl %eax, %eax
je 0x2a89f
movl (%rdi), %eax
leaq (%rdi,%rax), %rsi
decq %rsi
jmp 0x2a8a5
leaq 0xa(%rdi), %rsi
jmp 0x2a8a5
// File: /workspace/github_c_makefile_star2_O2/nilyang[P]redis-tdd-annotation/src/ziplist.c
// Function: ziplistIndex
unsigned char *ziplistIndex(unsigned char *zl, int index) {

    unsigned char *p;

    zlentry entry;

    // 处理负数索引
    if (index < 0) {

        // 将索引转换为正数
        index = (-index)-1;
        
        // 定位到表尾节点
        p = ZIPLIST_ENTRY_TAIL(zl);

        // 如果列表不为空，那么。。。
        if (p[0] != ZIP_END) {

            // 从表尾向表头遍历
            entry = zipEntry(p);
            // T = O(N)
            while (entry.prevrawlen > 0 && index--) {
                // 前移指针
                p -= entry.prevrawlen;
                // T = O(1)
                entry = zipEntry(p);
            }
        }

    // 处理正数索引
    } else {

        // 定位到表头节点
        p = ZIPLIST_ENTRY_HEAD(zl);

        // T = O(N)
        while (p[0] != ZIP_END && index--) {
            // 后移指针
            // T = O(1)
            p += zipRawEntryLength(p);
        }
    }

    // 返回结果
    return (p[0] == ZIP_END || index > 0) ? NULL : p;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %rbx
subq $0x28, %rsp
movl %esi, %ebx
testl %esi, %esi
js 0x2ac32
addq $0xa, %rdi
pushq $-0x1
popq %rbp
movq %rdi, %r14
cmpb $-0x1, (%r14)
sete %al
je 0x2ac88
subl $0x1, %ebx
jb 0x2ac77
movq %r14, %rdi
callq 0x2ad80
movl %eax, %eax
addq %rax, %r14
jmp 0x2ac15
notl %ebx
movl 0x4(%rdi), %eax
leaq (%rdi,%rax), %r14
cmpb $-0x1, (%rdi,%rax)
je 0x2ac7b
leaq 0x8(%rsp), %r15
movq %r15, %rdi
movq %r14, %rsi
callq 0x2aca4
movl 0x4(%r15), %eax
pushq $-0x1
popq %rbp
testl %eax, %eax
je 0x2ac81
subl $0x1, %ebx
jb 0x2ac7f
movl %eax, %eax
subq %rax, %r14
movq %r15, %rdi
movq %r14, %rsi
callq 0x2aca4
movl 0xc(%rsp), %eax
jmp 0x2ac58
movl %ebp, %ebx
jmp 0x2ac88
movb $0x1, %al
jmp 0x2ac88
movl %ebp, %ebx
cmpb $-0x1, (%r14)
sete %al
xorl %ecx, %ecx
testl %ebx, %ebx
cmovgq %rcx, %r14
testb %al, %al
cmovneq %rcx, %r14
movq %r14, %rax
addq $0x28, %rsp
popq %rbx
popq %r14
popq %r15
popq %rbp
retq
// File: /workspace/github_c_makefile_star2_O2/nilyang[P]redis-tdd-annotation/src/ziplist.c
// Function: zipEntry
static zlentry zipEntry(unsigned char *p) {
    zlentry e;

    // e.prevrawlensize 保存着编码前一个节点的长度所需的字节数
    // e.prevrawlen 保存着前一个节点的长度
    // T = O(1)
    ZIP_DECODE_PREVLEN(p, e.prevrawlensize, e.prevrawlen);

    // p + e.prevrawlensize 将指针移动到列表节点本身
    // e.encoding 保存着节点值的编码类型
    // e.lensize 保存着编码节点值长度所需的字节数
    // e.len 保存着节点值的长度
    // T = O(1)
    ZIP_DECODE_LENGTH(p + e.prevrawlensize, e.encoding, e.lensize, e.len);

    // 计算头结点的字节数
    e.headersize = e.prevrawlensize + e.lensize;

    // 记录指针
    e.p = p;

    return e;
}

// Assembly:
pushq %rbp
pushq %r14
pushq %rbx
movq %rsi, %r14
movq %rdi, %rbx
movzbl (%rsi), %eax
xorl %ecx, %ecx
cmpl $0xfe, %eax
setae %cl
leal 0x1(,%rcx,4), %ebp
movl %ebp, (%rdi)
jb 0x2acca
movl 0x1(%r14), %eax
movl %eax, 0x4(%rbx)
movl %ebp, %ecx
movzbl (%r14,%rcx), %eax
movl %eax, %edx
andb $-0x40, %dl
movzbl %dl, %edx
cmpl $0xc0, %eax
cmovael %eax, %edx
movb %dl, 0x14(%rbx)
jae 0x2ad16
movl %eax, %edx
shrb $0x6, %dl
xorb $0x2, %dl
movzbl %dl, %edx
leaq 0x61f65(%rip), %rsi     # 0x8cc60
movslq (%rsi,%rdx,4), %rdx
addq %rsi, %rdx
jmpq *%rdx
movl $0x5, 0x8(%rbx)
movl 0x1(%r14,%rcx), %eax
bswapl %eax
pushq $0x5
jmp 0x2ad32
movl $0x1, 0x8(%rbx)
movl %eax, %edi
callq 0x2b426
jmp 0x2ad30
movl $0x1, 0x8(%rbx)
andl $0x3f, %eax
pushq $0x1
popq %rcx
movl %eax, 0xc(%rbx)
addl %ebp, %ecx
movl %ecx, 0x10(%rbx)
movq %r14, 0x18(%rbx)
movq %rbx, %rax
popq %rbx
popq %r14
popq %rbp
retq
movl $0x2, 0x8(%rbx)
andl $0x3f, %eax
shll $0x8, %eax
movzbl 0x1(%r14,%rcx), %ecx
orl %ecx, %eax
pushq $0x2
jmp 0x2ad32
leaq 0x64559(%rip), %rdi     # 0x8f2c0
leaq 0x61f17(%rip), %rsi     # 0x8cc85
movl $0x2e9, %edx            # imm = 0x2E9
callq 0x4906b
pushq $0x1
popq %rdi
callq 0x1f3b0
// File: /workspace/github_c_makefile_star2_O2/nilyang[P]redis-tdd-annotation/src/ziplist.c
// Function: zipRawEntryLength
static unsigned int zipRawEntryLength(unsigned char *p) {
    unsigned int prevlensize, encoding, lensize, len;

    // 取出编码前置节点的长度所需的字节数
    // T = O(1)
    ZIP_DECODE_PREVLENSIZE(p, prevlensize);

    // 取出当前节点值的编码类型，编码节点值长度所需的字节数，以及节点值的长度
    // T = O(1)
    ZIP_DECODE_LENGTH(p + prevlensize, encoding, lensize, len);

    // 计算节点占用的字节数总和
    return prevlensize + lensize + len;
}

// Assembly:
pushq %rbx
xorl %eax, %eax
cmpb $-0x2, (%rdi)
setae %al
leal 0x1(,%rax,4), %ebx
movzbl (%rdi,%rbx), %eax
movl %eax, %ecx
andl $-0x40, %ecx
cmpl $0xc0, %eax
cmovael %eax, %ecx
cmpl $0xbf, %ecx
ja 0x2adbf
cmpb $-0x80, %cl
je 0x2ade3
movzbl %cl, %ecx
cmpl $0x40, %ecx
je 0x2add2
testl %ecx, %ecx
jne 0x2aded
andl $0x3f, %eax
jmp 0x2adc7
movzbl %cl, %edi
callq 0x2b426
pushq $0x1
popq %rcx
addl %ecx, %ebx
addl %eax, %ebx
movl %ebx, %eax
popq %rbx
retq
andl $0x3f, %eax
shll $0x8, %eax
movzbl 0x1(%rdi,%rbx), %ecx
orl %ecx, %eax
pushq $0x2
jmp 0x2adc9
movl 0x1(%rdi,%rbx), %eax
bswapl %eax
pushq $0x5
jmp 0x2adc9
leaq 0x644cc(%rip), %rdi     # 0x8f2c0
leaq 0x61e8a(%rip), %rsi     # 0x8cc85
movl $0x253, %edx            # imm = 0x253
callq 0x4906b
pushq $0x1
popq %rdi
callq 0x1f3b0
// File: /workspace/github_c_makefile_star2_O2/nilyang[P]redis-tdd-annotation/src/ziplist.c
// Function: ziplistPrev
unsigned char *ziplistPrev(unsigned char *zl, unsigned char *p) {
    zlentry entry;

    /* Iterating backwards from ZIP_END should return the tail. When "p" is
     * equal to the first element of the list, we're already at the head,
     * and should return NULL. */
    
    // 如果 p 指向列表末端（列表为空，或者刚开始从表尾向表头迭代）
    // 那么尝试取出列表尾端节点
    if (p[0] == ZIP_END) {
        p = ZIPLIST_ENTRY_TAIL(zl);
        // 尾端节点也指向列表末端，那么列表为空
        return (p[0] == ZIP_END) ? NULL : p;
    
    // 如果 p 指向列表头，那么说明迭代已经完成
    } else if (p == ZIPLIST_ENTRY_HEAD(zl)) {
        return NULL;

    // 既不是表头也不是表尾，从表尾向表头移动指针
    } else {
        // 计算前一个节点的节点数
        entry = zipEntry(p);
        assert(entry.prevrawlen > 0);
        // 移动指针，指向前一个节点
        return p-entry.prevrawlen;
    }
}

// Assembly:
pushq %r14
pushq %rbx
subq $0x28, %rsp
cmpb $-0x1, (%rsi)
je 0x2ae69
movq %rsi, %rbx
addq $0xa, %rdi
cmpq %rsi, %rdi
je 0x2ae7c
leaq 0x8(%rsp), %r14
movq %r14, %rdi
movq %rbx, %rsi
callq 0x2aca4
movl 0x4(%r14), %eax
testq %rax, %rax
je 0x2ae89
subq %rax, %rbx
jmp 0x2ae7e
movl 0x4(%rdi), %eax
leaq (%rdi,%rax), %rcx
xorl %ebx, %ebx
cmpb $-0x1, (%rdi,%rax)
cmovneq %rcx, %rbx
jmp 0x2ae7e
xorl %ebx, %ebx
movq %rbx, %rax
addq $0x28, %rsp
popq %rbx
popq %r14
retq
leaq 0x61de0(%rip), %rdi     # 0x8cc70
leaq 0x61dee(%rip), %rsi     # 0x8cc85
movl $0x55c, %edx            # imm = 0x55C
callq 0x4906b
pushq $0x1
popq %rdi
callq 0x1f3b0
// File: /workspace/github_c_makefile_star2_O2/nilyang[P]redis-tdd-annotation/src/ziplist.c
// Function: ziplistGet
unsigned int ziplistGet(unsigned char *p, unsigned char **sstr, unsigned int *slen, long long *sval) {

    zlentry entry;
    if (p == NULL || p[0] == ZIP_END) return 0;
    if (sstr) *sstr = NULL;

    // 取出 p 所指向的节点的各项信息，并保存到结构 entry 中
    // T = O(1)
    entry = zipEntry(p);

    // 节点的值为字符串，将字符串长度保存到 *slen ，字符串保存到 *sstr
    // T = O(1)
    if (ZIP_IS_STR(entry.encoding)) {
        if (sstr) {
            *slen = entry.len;
            *sstr = p+entry.headersize;
        }
    
    // 节点的值为整数，解码值，并将值保存到 *sval
    // T = O(1)
    } else {
        if (sval) {
            *sval = zipLoadInteger(p+entry.headersize,entry.encoding);
        }
    }

    return 1;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x28, %rsp
xorl %ebp, %ebp
testq %rdi, %rdi
je 0x2af23
movq %rdi, %rbx
cmpb $-0x1, (%rdi)
je 0x2af23
movq %rcx, %r14
movq %rdx, %r12
movq %rsi, %r15
testq %rsi, %rsi
je 0x2aed8
andq $0x0, (%r15)
leaq 0x8(%rsp), %r13
movq %r13, %rdi
movq %rbx, %rsi
callq 0x2aca4
movl 0x10(%r13), %eax
movb 0x14(%r13), %cl
pushq $0x1
popq %rbp
cmpb $-0x41, %cl
jbe 0x2af10
testq %r14, %r14
je 0x2af23
addq %rax, %rbx
movzbl %cl, %esi
movq %rbx, %rdi
callq 0x2af34
movq %rax, (%r14)
jmp 0x2af23
testq %r15, %r15
je 0x2af23
movl 0x14(%rsp), %ecx
movl %ecx, (%r12)
addq %rax, %rbx
movq %rbx, (%r15)
movl %ebp, %eax
addq $0x28, %rsp
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/ziplist.c
// Function: ziplistCompare
unsigned int ziplistCompare(unsigned char *p, unsigned char *sstr, unsigned int slen) {
    zlentry entry;
    unsigned char sencoding;
    long long zval, sval;
    if (p[0] == ZIP_END) return 0;

    // 取出节点
    entry = zipEntry(p);
    if (ZIP_IS_STR(entry.encoding)) {

        // 节点值为字符串，进行字符串对比

        /* Raw compare */
        if (entry.len == slen) {
            // T = O(N)
            return memcmp(p+entry.headersize,sstr,slen) == 0;
        } else {
            return 0;
        }
    } else {
        
        // 节点值为整数，进行整数对比

        /* Try to compare encoded values. Don't compare encoding because
         * different implementations may encoded integers differently. */
        if (zipTryEncoding(sstr,slen,&sval,&sencoding)) {
          // T = O(1)
          zval = zipLoadInteger(p+entry.headersize,entry.encoding);
          return zval == sval;
        }
    }

    return 0;
}

// Assembly:
cmpb $-0x1, (%rdi)
je 0x2b1c9
pushq %rbp
pushq %r15
pushq %r14
pushq %r12
pushq %rbx
subq $0x30, %rsp
movl %edx, %ebp
movq %rsi, %r14
movq %rdi, %rbx
leaq 0x10(%rsp), %r15
movq %r15, %rdi
movq %rbx, %rsi
callq 0x2aca4
movl 0x10(%r15), %r12d
movb 0x14(%r15), %r15b
cmpb $-0x41, %r15b
jbe 0x2b1cd
leaq 0x10(%rsp), %rdx
leaq 0xf(%rsp), %rcx
movq %r14, %rdi
movl %ebp, %esi
callq 0x2b1fc
testl %eax, %eax
je 0x2b1ea
addq %r12, %rbx
movzbl %r15b, %esi
movq %rbx, %rdi
callq 0x2af34
cmpq 0x10(%rsp), %rax
jmp 0x2b1e5
xorl %eax, %eax
jmp 0x2b1f8
cmpl %ebp, 0x1c(%rsp)
jne 0x2b1ea
addq %r12, %rbx
movl %ebp, %edx
movq %rbx, %rdi
movq %r14, %rsi
callq 0x1f6a0
testl %eax, %eax
sete %al
jmp 0x2b1ec
xorl %eax, %eax
addq $0x30, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
movzbl %al, %eax
retq
// File: /workspace/github_c_makefile_star2_O2/nilyang[P]redis-tdd-annotation/src/ziplist.c
// Function: ziplistLen
unsigned int ziplistLen(unsigned char *zl) {

    unsigned int len = 0;

    // 节点数小于 UINT16_MAX
    // T = O(1)
    if (intrev16ifbe(ZIPLIST_LENGTH(zl)) < UINT16_MAX) {
        len = intrev16ifbe(ZIPLIST_LENGTH(zl));

    // 节点数大于 UINT16_MAX 时，需要遍历整个列表才能计算出节点数
    // T = O(N)
    } else {
        unsigned char *p = zl+ZIPLIST_HEADER_SIZE;
        while (*p != ZIP_END) {
            p += zipRawEntryLength(p);
            len++;
        }

        /* Re-store length if small enough */
        if (len < UINT16_MAX) ZIPLIST_LENGTH(zl) = intrev16ifbe(len);
    }

    return len;
}

// Assembly:
pushq %r15
pushq %r14
pushq %rbx
movzwl 0x8(%rdi), %ebx
cmpl $0xffff, %ebx           # imm = 0xFFFF
jne 0x2b4a3
movq %rdi, %r14
leaq 0xa(%rdi), %r15
xorl %ebx, %ebx
cmpb $-0x1, (%r15)
je 0x2b496
movq %r15, %rdi
callq 0x2ad80
movl %eax, %eax
addq %rax, %r15
incl %ebx
jmp 0x2b47f
cmpl $0xfffe, %ebx           # imm = 0xFFFE
ja 0x2b4a3
movw %bx, 0x8(%r14)
movl %ebx, %eax
popq %rbx
popq %r14
popq %r15
retq
// File: /workspace/github_c_makefile_star2_O2/nilyang[P]redis-tdd-annotation/src/networking.c
// Function: getStringObjectSdsUsedMemory
size_t getStringObjectSdsUsedMemory(robj *o) {
    redisAssertWithInfo(NULL,o,o->type == REDIS_STRING);
    switch(o->encoding) {
    case REDIS_ENCODING_RAW: return zmalloc_size_sds(o->ptr);
    case REDIS_ENCODING_EMBSTR: return sdslen(o->ptr);
    default: return 0; /* Just integer encoding for now. */
    }
}

// Assembly:
movq %rdi, %rsi
movl (%rdi), %eax
testb $0xf, %al
jne 0x2b79e
shrl $0x4, %eax
andl $0xf, %eax
cmpl $0x8, %eax
je 0x2b792
testl %eax, %eax
jne 0x2b79b
movq 0x8(%rsi), %rdi
addq $-0x8, %rdi
jmp 0x76897
movq 0x8(%rsi), %rax
movslq -0x8(%rax), %rax
retq
xorl %eax, %eax
retq
pushq %rax
leaq 0x615b0(%rip), %rdx     # 0x8cd56
leaq 0x615c1(%rip), %rcx     # 0x8cd6e
pushq $0x31
popq %r8
xorl %edi, %edi
callq 0x4980c
pushq $0x1
popq %rdi
callq 0x1f3b0
// File: /workspace/github_c_makefile_star2_O2/nilyang[P]redis-tdd-annotation/src/networking.c
// Function: prepareClientToWrite
int prepareClientToWrite(redisClient *c) {

    // LUA 脚本环境所使用的伪客户端总是可写的
    if (c->flags & REDIS_LUA_CLIENT) return REDIS_OK;
    
    // 客户端是主服务器并且不接受查询，
    // 那么它是不可写的，出错
    if ((c->flags & REDIS_MASTER) &&
        !(c->flags & REDIS_MASTER_FORCE_REPLY)) return REDIS_ERR;

    // 无连接的伪客户端总是不可写的
    if (c->fd <= 0) return REDIS_ERR; /* Fake client */

    // 一般情况，为客户端套接字安装写处理器到事件循环
    if (c->bufpos == 0 && listLength(c->reply) == 0 &&
        (c->replstate == REDIS_REPL_NONE ||
         c->replstate == REDIS_REPL_ONLINE) &&
        aeCreateFileEvent(server.el, c->fd, AE_WRITABLE,
        sendReplyToClient, c) == AE_ERR) return REDIS_ERR;

    return REDIS_OK;
}

// Assembly:
pushq %rbx
movl 0x90(%rdi), %eax
xorl %ebx, %ebx
btl $0x8, %eax
jb 0x2bb6a
andl $0x2002, %eax           # imm = 0x2002
pushq $-0x1
popq %rbx
cmpl $0x2, %eax
je 0x2bb6a
movq %rdi, %r8
movl (%rdi), %esi
testl %esi, %esi
jle 0x2bb6a
cmpl $0x0, 0x170(%r8)
jne 0x2bb68
movq 0x60(%r8), %rax
cmpq $0x0, 0x28(%rax)
je 0x2bb6e
xorl %ebx, %ebx
movl %ebx, %eax
popq %rbx
retq
movl 0x98(%r8), %eax
cmpl $0x9, %eax
je 0x2bb7e
testl %eax, %eax
jne 0x2bb68
leaq 0x9b423(%rip), %rax     # 0xc6fa8
movq 0x28(%rax), %rdi
leaq 0xf(%rip), %rcx         # 0x2bb9f
pushq $0x2
popq %rdx
callq 0x2030c
cmpl $-0x1, %eax
jne 0x2bb68
jmp 0x2bb6a
// File: /workspace/github_c_makefile_star2_O2/nilyang[P]redis-tdd-annotation/src/networking.c
// Function: addReplyToBuffer
int _addReplyToBuffer(redisClient *c, char *s, size_t len) {
    size_t available = sizeof(c->buf)-c->bufpos;

    // 正准备关闭客户端，无须再发送内容
    if (c->flags & REDIS_CLOSE_AFTER_REPLY) return REDIS_OK;

    /* If there already are entries in the reply list, we cannot
     * add anything more to the static buffer. */
    // 回复链表里已经有内容，再添加内容到 c->buf 里面就是错误了
    if (listLength(c->reply) > 0) return REDIS_ERR;

    /* Check that the buffer has enough space available for this string. */
    // 空间必须满足
    if (len > available) return REDIS_ERR;

    // 复制内容到 c->buf 里面
    memcpy(c->buf+c->bufpos,s,len);
    c->bufpos+=len;

    return REDIS_OK;
}

// Assembly:
pushq %r15
pushq %r14
pushq %rbx
xorl %ebx, %ebx
testb $0x40, 0x90(%rdi)
jne 0x2be36
movq %rdx, %r14
movq %rdi, %r15
movslq 0x170(%rdi), %rax
movl $0x4000, %ecx           # imm = 0x4000
subq %rax, %rcx
movq 0x60(%rdi), %rdx
cmpq $0x0, 0x28(%rdx)
setne %dl
cmpq %r14, %rcx
setb %cl
orb %dl, %cl
je 0x2be1c
pushq $-0x1
popq %rbx
jmp 0x2be36
leaq (%r15,%rax), %rdi
addq $0x174, %rdi            # imm = 0x174
movq %r14, %rdx
callq 0x1fbd0
addl %r14d, 0x170(%r15)
movl %ebx, %eax
popq %rbx
popq %r14
popq %r15
retq
// File: /workspace/github_c_makefile_star2_O2/nilyang[P]redis-tdd-annotation/src/networking.c
// Function: addReplyObjectToList
void _addReplyObjectToList(redisClient *c, robj *o) {
    robj *tail;

    // 客户端即将被关闭，无须再发送回复
    if (c->flags & REDIS_CLOSE_AFTER_REPLY) return;

    // 链表中无缓冲块，直接将对象追加到链表中
    if (listLength(c->reply) == 0) {
        incrRefCount(o);
        listAddNodeTail(c->reply,o);

        // 链表中已有缓冲块，尝试将回复添加到块内
        // 如果当前的块不能容纳回复的话，那么新建一个块
        c->reply_bytes += getStringObjectSdsUsedMemory(o);
    } else {

        // 取出表尾的 SDS
        tail = listNodeValue(listLast(c->reply));

        /* Append to this object when possible. */
        // 如果表尾 SDS 的已用空间加上对象的长度，小于 REDIS_REPLY_CHUNK_BYTES
        // 那么将新对象的内容拼接到表尾 SDS 的末尾
        if (tail->ptr != NULL &&
            tail->encoding == REDIS_ENCODING_RAW &&
            sdslen(tail->ptr)+sdslen(o->ptr) <= REDIS_REPLY_CHUNK_BYTES)
        {
            c->reply_bytes -= zmalloc_size_sds(tail->ptr);
            tail = dupLastObjectIfNeeded(c->reply);
            // 拼接
            tail->ptr = sdscatlen(tail->ptr,o->ptr,sdslen(o->ptr));
            c->reply_bytes += zmalloc_size_sds(tail->ptr);

        // 直接将对象追加到末尾
        } else {
            incrRefCount(o);
            listAddNodeTail(c->reply,o);
            c->reply_bytes += getStringObjectSdsUsedMemory(o);
        }
    }

    // 检查回复缓冲区的大小，如果超过系统限制的话，那么关闭客户端
    asyncCloseClientOnOutputBufferLimitReached(c);
}

// Assembly:
testb $0x40, 0x90(%rdi)
jne 0x2bec4
pushq %r15
pushq %r14
pushq %rbx
movq %rsi, %r14
movq %rdi, %rbx
movq 0x60(%rdi), %rax
cmpq $0x0, 0x28(%rax)
je 0x2bec5
movq 0x8(%rax), %rax
movq 0x10(%rax), %rax
movq 0x8(%rax), %rdi
testq %rdi, %rdi
je 0x2bec5
testb $-0x10, (%rax)
jne 0x2bec5
movslq -0x8(%rdi), %rax
movq 0x8(%r14), %rcx
movslq -0x8(%rcx), %rcx
addq %rax, %rcx
cmpq $0x4000, %rcx           # imm = 0x4000
ja 0x2bec5
addq $-0x8, %rdi
callq 0x76897
subq %rax, 0x68(%rbx)
movq 0x60(%rbx), %rdi
callq 0x2bd7f
movq %rax, %r15
movq 0x8(%rax), %rdi
movq 0x8(%r14), %rsi
movslq -0x8(%rsi), %rdx
callq 0x2736d
movq %rax, 0x8(%r15)
leaq -0x8(%rax), %rdi
callq 0x76897
jmp 0x2bee1
retq
movq %r14, %rdi
callq 0x2eacc
movq 0x60(%rbx), %rdi
movq %r14, %rsi
callq 0x1fe4c
movq %r14, %rdi
callq 0x2b76d
addq %rax, 0x68(%rbx)
movq %rbx, %rdi
popq %rbx
popq %r14
popq %r15
jmp 0x2bef2
// File: /workspace/github_c_makefile_star2_O2/nilyang[P]redis-tdd-annotation/src/networking.c
// Function: asyncCloseClientOnOutputBufferLimitReached
void asyncCloseClientOnOutputBufferLimitReached(redisClient *c) {
    redisAssert(c->reply_bytes < ULONG_MAX-(1024*64));

    // 已经被标记了
    if (c->reply_bytes == 0 || c->flags & REDIS_CLOSE_ASAP) return;

    // 检查限制
    if (checkClientOutputBufferLimits(c)) {
        sds client = catClientInfoString(sdsempty(),c);

        // 异步关闭
        freeClientAsync(c);
        redisLog(REDIS_WARNING,"Client %s scheduled to be closed ASAP for overcoming of output buffer limits.", client);
        sdsfree(client);
    }
}

// Assembly:
pushq %r14
pushq %rbx
pushq %rax
movq 0x68(%rdi), %rax
cmpq $-0x10001, %rax         # imm = 0xFFFEFFFF
jae 0x2bf65
testq %rax, %rax
je 0x2bf5d
movq %rdi, %rbx
testb $0x4, 0x91(%rdi)
jne 0x2bf5d
movq %rbx, %rdi
callq 0x2dfb3
testl %eax, %eax
je 0x2bf5d
callq 0x271bf
movq %rax, %rdi
movq %rbx, %rsi
callq 0x2d623
movq %rax, %r14
movq %rbx, %rdi
callq 0x2ced9
leaq 0x612b4(%rip), %rsi     # 0x8d1f5
pushq $0x3
popq %rdi
movq %r14, %rdx
xorl %eax, %eax
callq 0x22613
movq %r14, %rdi
addq $0x8, %rsp
popq %rbx
popq %r14
jmp 0x271f7
addq $0x8, %rsp
popq %rbx
popq %r14
retq
leaq 0x61264(%rip), %rdi     # 0x8d1d0
leaq 0x60dfb(%rip), %rsi     # 0x8cd6e
movl $0x81a, %edx            # imm = 0x81A
callq 0x4906b
pushq $0x1
popq %rdi
callq 0x1f3b0
// File: /workspace/github_c_makefile_star2_O2/nilyang[P]redis-tdd-annotation/src/networking.c
// Function: addReplySdsToList
void _addReplySdsToList(redisClient *c, sds s) {
    robj *tail;

    if (c->flags & REDIS_CLOSE_AFTER_REPLY) {
        sdsfree(s);
        return;
    }

    if (listLength(c->reply) == 0) {
        listAddNodeTail(c->reply,createObject(REDIS_STRING,s));
        c->reply_bytes += zmalloc_size_sds(s);
    } else {
        tail = listNodeValue(listLast(c->reply));

        /* Append to this object when possible. */
        if (tail->ptr != NULL && tail->encoding == REDIS_ENCODING_RAW &&
            sdslen(tail->ptr)+sdslen(s) <= REDIS_REPLY_CHUNK_BYTES)
        {
            c->reply_bytes -= zmalloc_size_sds(tail->ptr);
            tail = dupLastObjectIfNeeded(c->reply);
            tail->ptr = sdscatlen(tail->ptr,s,sdslen(s));
            c->reply_bytes += zmalloc_size_sds(tail->ptr);
            sdsfree(s);
        } else {
            listAddNodeTail(c->reply,createObject(REDIS_STRING,s));
            c->reply_bytes += zmalloc_size_sds(s);
        }
    }
    asyncCloseClientOnOutputBufferLimitReached(c);
}

// Assembly:
pushq %r15
pushq %r14
pushq %rbx
movq %rsi, %r14
testb $0x40, 0x90(%rdi)
jne 0x2c012
movq %rdi, %rbx
movq 0x60(%rdi), %r15
cmpq $0x0, 0x28(%r15)
je 0x2c01f
movq 0x8(%r15), %rax
movq 0x10(%rax), %rax
movq 0x8(%rax), %rdi
testq %rdi, %rdi
je 0x2c01f
testb $-0x10, (%rax)
jne 0x2c01f
movslq -0x8(%rdi), %rax
movslq -0x8(%r14), %rcx
addq %rax, %rcx
cmpq $0x4000, %rcx           # imm = 0x4000
ja 0x2c01f
addq $-0x8, %rdi
callq 0x76897
subq %rax, 0x68(%rbx)
movq 0x60(%rbx), %rdi
callq 0x2bd7f
movq %rax, %r15
movq 0x8(%rax), %rdi
movslq -0x8(%r14), %rdx
movq %r14, %rsi
callq 0x2736d
movq %rax, 0x8(%r15)
leaq -0x8(%rax), %rdi
callq 0x76897
addq %rax, 0x68(%rbx)
movq %r14, %rdi
callq 0x271f7
jmp 0x2c044
movq %r14, %rdi
popq %rbx
popq %r14
popq %r15
jmp 0x271f7
xorl %edi, %edi
movq %r14, %rsi
callq 0x2e9b4
movq %r15, %rdi
movq %rax, %rsi
callq 0x1fe4c
addq $-0x8, %r14
movq %r14, %rdi
callq 0x76897
addq %rax, 0x68(%rbx)
movq %rbx, %rdi
popq %rbx
popq %r14
popq %r15
jmp 0x2bef2
// File: /workspace/github_c_makefile_star2_O2/nilyang[P]redis-tdd-annotation/src/networking.c
// Function: addReplyStringToList
void _addReplyStringToList(redisClient *c, char *s, size_t len) {
    robj *tail;

    if (c->flags & REDIS_CLOSE_AFTER_REPLY) return;

    if (listLength(c->reply) == 0) {
        // 为字符串创建字符串对象并追加到回复链表末尾
        robj *o = createStringObject(s,len);

        listAddNodeTail(c->reply,o);
        c->reply_bytes += getStringObjectSdsUsedMemory(o);
    } else {
        tail = listNodeValue(listLast(c->reply));

        /* Append to this object when possible. */
        if (tail->ptr != NULL && tail->encoding == REDIS_ENCODING_RAW &&
            sdslen(tail->ptr)+len <= REDIS_REPLY_CHUNK_BYTES)
        {
            c->reply_bytes -= zmalloc_size_sds(tail->ptr);
            tail = dupLastObjectIfNeeded(c->reply);
            // 将字符串拼接到一个 SDS 之后
            tail->ptr = sdscatlen(tail->ptr,s,len);
            c->reply_bytes += zmalloc_size_sds(tail->ptr);
        } else {
            // 为字符串创建字符串对象并追加到回复链表末尾
            robj *o = createStringObject(s,len);

            listAddNodeTail(c->reply,o);
            c->reply_bytes += getStringObjectSdsUsedMemory(o);
        }
    }
    asyncCloseClientOnOutputBufferLimitReached(c);
}

// Assembly:
testb $0x40, 0x90(%rdi)
jne 0x2c0d3
pushq %r15
pushq %r14
pushq %r12
pushq %rbx
pushq %rax
movq %rdx, %r14
movq %rsi, %r15
movq %rdi, %rbx
movq 0x60(%rdi), %rax
cmpq $0x0, 0x28(%rax)
je 0x2c0d4
movq 0x8(%rax), %rax
movq 0x10(%rax), %rax
movq 0x8(%rax), %rdi
testq %rdi, %rdi
je 0x2c0d4
testb $-0x10, (%rax)
jne 0x2c0d4
movslq -0x8(%rdi), %rax
addq %r14, %rax
cmpq $0x4000, %rax           # imm = 0x4000
ja 0x2c0d4
addq $-0x8, %rdi
callq 0x76897
subq %rax, 0x68(%rbx)
movq 0x60(%rbx), %rdi
callq 0x2bd7f
movq %rax, %r12
movq 0x8(%rax), %rdi
movq %r15, %rsi
movq %r14, %rdx
callq 0x2736d
movq %rax, 0x8(%r12)
leaq -0x8(%rax), %rdi
callq 0x76897
jmp 0x2c0f6
retq
movq %r15, %rdi
movq %r14, %rsi
callq 0x2ea81
movq %rax, %r14
movq 0x60(%rbx), %rdi
movq %rax, %rsi
callq 0x1fe4c
movq %r14, %rdi
callq 0x2b76d
addq %rax, 0x68(%rbx)
movq %rbx, %rdi
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
jmp 0x2bef2