// File: /workspace/github_c_makefile_star2_O0/nilyang[P]redis-tdd-annotation/src/replication.c
// Function: feedReplicationBacklog
void feedReplicationBacklog(void *ptr, size_t len) {
    unsigned char *p = ptr;

    // 将长度累加到全局 offset 中
    server.master_repl_offset += len;

    /* This is a circular buffer, so write as much data we can at every
     * iteration and rewind the "idx" index if we reach the limit. */
    // 环形 buffer ，每次写尽可能多的数据，并在到达尾部时将 idx 重置到头部
    while(len) {
        // 从 idx 到 backlog 尾部的字节数
        size_t thislen = server.repl_backlog_size - server.repl_backlog_idx;
        // 如果 idx 到 backlog 尾部这段空间足以容纳要写入的内容
        // 那么直接将写入数据长度设为 len
        // 在将这些 len 字节复制之后，这个 while 循环将跳出
        if (thislen > len) thislen = len;
        // 将 p 中的 thislen 字节内容复制到 backlog
        memcpy(server.repl_backlog+server.repl_backlog_idx,p,thislen);
        // 更新 idx ，指向新写入的数据之后
        server.repl_backlog_idx += thislen;
        // 如果写入达到尾部，那么将索引重置到头部
        if (server.repl_backlog_idx == server.repl_backlog_size)
            server.repl_backlog_idx = 0;
        // 减去已写入的字节数
        len -= thislen;
        // 将指针移动到已被写入数据的后面，指向未被复制数据的开头
        p += thislen;
        // 增加实际长度
        server.repl_backlog_histlen += thislen;
    }
    // histlen 的最大值只能等于 backlog_size
    // 另外，当 histlen 大于 repl_backlog_size 时，
    // 表示写入数据的前头有一部分数据被自己的尾部覆盖了
    // 举个例子，例如 abcde 要写入到一个只有三个字节的环形数组中
    // 且假设索引为 0
    // 那么 abc 首先被写入，数组为 [a, b, c] 
    // 然后 de 被写入，数组为 [d, e, c]
    if (server.repl_backlog_histlen > server.repl_backlog_size)
        server.repl_backlog_histlen = server.repl_backlog_size;
    /* Set the offset of the first byte we have in the backlog. */
    // 记录程序可以依靠 backlog 来还原的数据的第一个字节的偏移量
    // 比如 master_repl_offset = 10086
    // repl_backlog_histlen = 30
    // 那么 backlog 所保存的数据的第一个字节的偏移量为
    // 10086 - 30 + 1 = 10056 + 1 = 10057
    // 这说明如果从服务器如果从 10057 至 10086 之间的任何时间断线
    // 那么从服务器都可以使用 PSYNC
    server.repl_backlog_off = server.master_repl_offset -
                              server.repl_backlog_histlen + 1;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x20, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x18(%rbp)
movq -0x10(%rbp), %rcx
leaq 0xd4975(%rip), %rax     # 0x1138f8
addq 0x5f0(%rax), %rcx
leaq 0xd4967(%rip), %rax     # 0x1138f8
movq %rcx, 0x5f0(%rax)
cmpq $0x0, -0x10(%rbp)
je 0x3f08e
leaq 0xd494e(%rip), %rax     # 0x1138f8
movq 0x608(%rax), %rax
leaq 0xd4940(%rip), %rcx     # 0x1138f8
subq 0x618(%rcx), %rax
movq %rax, -0x20(%rbp)
movq -0x20(%rbp), %rax
cmpq -0x10(%rbp), %rax
jbe 0x3efd5
movq -0x10(%rbp), %rax
movq %rax, -0x20(%rbp)
leaq 0xd491c(%rip), %rax     # 0x1138f8
movq 0x600(%rax), %rdi
leaq 0xd490e(%rip), %rax     # 0x1138f8
addq 0x618(%rax), %rdi
movq -0x18(%rbp), %rsi
movq -0x20(%rbp), %rdx
callq 0x1fbf0
movq -0x20(%rbp), %rcx
leaq 0xd48ef(%rip), %rax     # 0x1138f8
addq 0x618(%rax), %rcx
leaq 0xd48e1(%rip), %rax     # 0x1138f8
movq %rcx, 0x618(%rax)
leaq 0xd48d3(%rip), %rax     # 0x1138f8
movq 0x618(%rax), %rax
leaq 0xd48c5(%rip), %rcx     # 0x1138f8
cmpq 0x608(%rcx), %rax
jne 0x3f04e
leaq 0xd48b5(%rip), %rax     # 0x1138f8
movq $0x0, 0x618(%rax)
movq -0x20(%rbp), %rcx
movq -0x10(%rbp), %rax
subq %rcx, %rax
movq %rax, -0x10(%rbp)
movq -0x20(%rbp), %rax
addq -0x18(%rbp), %rax
movq %rax, -0x18(%rbp)
movq -0x20(%rbp), %rcx
leaq 0xd4884(%rip), %rax     # 0x1138f8
addq 0x610(%rax), %rcx
leaq 0xd4876(%rip), %rax     # 0x1138f8
movq %rcx, 0x610(%rax)
jmp 0x3ef98
leaq 0xd4863(%rip), %rax     # 0x1138f8
movq 0x610(%rax), %rax
leaq 0xd4855(%rip), %rcx     # 0x1138f8
cmpq 0x608(%rcx), %rax
jle 0x3f0c8
leaq 0xd4845(%rip), %rax     # 0x1138f8
movq 0x608(%rax), %rcx
leaq 0xd4837(%rip), %rax     # 0x1138f8
movq %rcx, 0x610(%rax)
leaq 0xd4829(%rip), %rax     # 0x1138f8
movq 0x5f0(%rax), %rcx
leaq 0xd481b(%rip), %rax     # 0x1138f8
subq 0x610(%rax), %rcx
addq $0x1, %rcx
leaq 0xd4809(%rip), %rax     # 0x1138f8
movq %rcx, 0x620(%rax)
addq $0x20, %rsp
popq %rbp
retq
nopl (%rax)