// File: /workspace/github_c_makefile_star2_O2/nilyang[P]redis-tdd-annotation/src/cluster.c
// Function: clusterBuildMessageHdr
void clusterBuildMessageHdr(clusterMsg *hdr, int type) {
    int totlen = 0;
    uint64_t offset;
    clusterNode *master;

    /* If this node is a master, we send its slots bitmap and configEpoch.
     *
     * 如果这是一个主节点，那么发送该节点的槽 bitmap 和配置纪元。
     *
     * If this node is a slave we send the master's information instead (the
     * node is flagged as slave so the receiver knows that it is NOT really
     * in charge for this slots.
     * 如果这是一个从节点，
     * 那么发送这个节点的主节点的槽 bitmap 和配置纪元。
     *
     * 因为接收信息的节点通过标识可以知道这个节点是一个从节点，
     * 所以接收信息的节点不会将从节点错认作是主节点。
     */
    master = (nodeIsSlave(myself) && myself->slaveof) ?
              myself->slaveof : myself;

    // 清零信息头
    memset(hdr,0,sizeof(*hdr));

    hdr->sig[0] = 'R';
    hdr->sig[1] = 'C';
    hdr->sig[2] = 'm';
    hdr->sig[3] = 'b';

    // 设置信息类型
    hdr->type = htons(type);

    // 设置信息发送者
    memcpy(hdr->sender,myself->name,REDIS_CLUSTER_NAMELEN);

    // 设置当前节点负责的槽
    memcpy(hdr->myslots,master->slots,sizeof(hdr->myslots));

    // 清零 slaveof 域
    memset(hdr->slaveof,0,REDIS_CLUSTER_NAMELEN);

    // 如果节点是从节点的话，那么设置 slaveof 域
    if (myself->slaveof != NULL)
        memcpy(hdr->slaveof,myself->slaveof->name, REDIS_CLUSTER_NAMELEN);

    // 设置端口号
    hdr->port = htons(server.port);

    // 设置标识
    hdr->flags = htons(myself->flags);

    // 设置状态
    hdr->state = server.cluster->state;

    /* Set the currentEpoch and configEpochs. */
    // 设置集群当前配置纪元
    hdr->currentEpoch = htonu64(server.cluster->currentEpoch);
    // 设置主节点当前配置纪元
    hdr->configEpoch = htonu64(master->configEpoch);

    /* Set the replication offset. */
    // 设置复制偏移量
    if (nodeIsSlave(myself))
        offset = replicationGetSlaveOffset();
    else
        offset = server.master_repl_offset;
    hdr->offset = htonu64(offset);

    /* Set the message flags. */
    if (nodeIsMaster(myself) && server.cluster->mf_end)
        hdr->mflags[0] |= CLUSTERMSG_FLAG0_PAUSED;

    /* Compute the message length for certain messages. For other messages
     * this is up to the caller. */
    // 计算信息的长度
    if (type == CLUSTERMSG_TYPE_FAIL) {
        totlen = sizeof(clusterMsg)-sizeof(union clusterMsgData);
        totlen += sizeof(clusterMsgDataFail);
    } else if (type == CLUSTERMSG_TYPE_UPDATE) {
        totlen = sizeof(clusterMsg)-sizeof(union clusterMsgData);
        totlen += sizeof(clusterMsgDataUpdate);
    }

    // 设置信息的长度
    hdr->totlen = htonl(totlen);
    /* For PING, PONG, and MEET, fixing the totlen field is up to the caller. */
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r12
pushq %rbx
movl %esi, %ebp
movq %rdi, %rbx
movq 0x8cd63(%rip), %rax     # 0xdb628
testb $0x2, 0x30(%rax)
je 0x4e8d7
movq 0x850(%rax), %r14
testq %r14, %r14
jne 0x4e8da
movq %rax, %r14
movl $0x10d0, %edx           # imm = 0x10D0
movq %rbx, %rdi
xorl %esi, %esi
callq 0x1f110
movl $0x626d4352, (%rbx)     # imm = 0x626D4352
movl %ebp, %eax
rolw $0x8, %ax
movw %ax, 0xc(%rbx)
movq 0x8cd28(%rip), %r12     # 0xdb628
movups 0x8(%r12), %xmm0
movups 0x18(%r12), %xmm1
movups %xmm0, 0x28(%rbx)
movups %xmm1, 0x38(%rbx)
movq 0x28(%r12), %rax
movq %rax, 0x48(%rbx)
leaq 0x50(%rbx), %rdi
leaq 0x40(%r14), %rsi
movl $0x800, %edx            # imm = 0x800
callq 0x1fbd0
xorps %xmm0, %xmm0
andq $0x0, 0x870(%rbx)
movups %xmm0, 0x850(%rbx)
movups %xmm0, 0x860(%rbx)
movq 0x850(%r12), %rax
testq %rax, %rax
je 0x4e973
leaq 0x850(%rbx), %rcx
movq 0x28(%rax), %rdx
movq %rdx, 0x20(%rcx)
movups 0x8(%rax), %xmm0
movups 0x18(%rax), %xmm1
movups %xmm1, 0x10(%rcx)
movups %xmm0, (%rcx)
leaq 0x7862e(%rip), %r15     # 0xc6fa8
movzwl 0x88(%r15), %eax
rolw $0x8, %ax
movw %ax, 0x898(%rbx)
movzwl 0x30(%r12), %eax
rolw $0x8, %ax
movw %ax, 0x89a(%rbx)
movq 0x7d0(%r15), %rax
movb 0x10(%rax), %cl
movb %cl, 0x89c(%rbx)
movq 0x8(%rax), %rdi
callq 0x51cb3
movq %rax, 0x10(%rbx)
movq 0x38(%r14), %rdi
callq 0x51cb3
movq %rax, 0x18(%rbx)
movq 0x8cc59(%rip), %rax     # 0xdb628
testb $0x2, 0x30(%rax)
jne 0x4e9de
movq 0x5f0(%r15), %rdi
jmp 0x4e9e6
callq 0x33b20
movq %rax, %rdi
callq 0x51cb3
movq %rax, 0x20(%rbx)
movq 0x8cc32(%rip), %rax     # 0xdb628
testb $0x1, 0x30(%rax)
je 0x4ea14
movq 0x7d0(%r15), %rax
cmpq $0x0, 0x60050(%rax)
je 0x4ea14
orb $0x1, 0x89d(%rbx)
xorl %eax, %eax
cmpl $0x7, %ebp
movl $0x10d0, %ecx           # imm = 0x10D0
cmovnel %eax, %ecx
cmpl $0x3, %ebp
movl $0x8c8, %eax            # imm = 0x8C8
cmovnel %ecx, %eax
bswapl %eax
movl %eax, 0x4(%rbx)
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
retq