// File: /workspace/github_c_makefile_star2_O0/nilyang[P]redis-tdd-annotation/src/sentinel.c
// Function: sentinelProcessHelloMessage
void sentinelProcessHelloMessage(char *hello, int hello_len) {
    /* Format is composed of 8 tokens:
     * 0=ip,1=port,2=runid,3=current_epoch,4=master_name,
     * 5=master_ip,6=master_port,7=master_config_epoch. */
    int numtokens, port, removed, master_port;
    uint64_t current_epoch, master_config_epoch;
    char **token = sdssplitlen(hello, hello_len, ",", 1, &numtokens);
    sentinelRedisInstance *si, *master;

    if (numtokens == 8) {
        /* Obtain a reference to the master this hello message is about */
        // 获取主服务器的名字，并丢弃和未知主服务器相关的消息。
        master = sentinelGetMasterByName(token[4]);
        if (!master) goto cleanup; /* Unknown master, skip the message. */

        /* First, try to see if we already have this sentinel. */
        // 看这个 Sentinel 是否已经认识发送消息的 Sentinel
        port = atoi(token[1]);
        master_port = atoi(token[6]);
        si = getSentinelRedisInstanceByAddrAndRunID(
                        master->sentinels,token[0],port,token[2]);
        current_epoch = strtoull(token[3],NULL,10);
        master_config_epoch = strtoull(token[7],NULL,10);

        if (!si) {

            // 这个 Sentinel 不认识发送消息的 Sentinel 
            // 将对方加入到 Sentinel 列表中

            /* If not, remove all the sentinels that have the same runid
             * OR the same ip/port, because it's either a restart or a
             * network topology change. */
            removed = removeMatchingSentinelsFromMaster(master,token[0],port,
                            token[2]);
            if (removed) {
                sentinelEvent(REDIS_NOTICE,"-dup-sentinel",master,
                    "%@ #duplicate of %s:%d or %s",
                    token[0],port,token[2]);
            }

            /* Add the new sentinel. */
            si = createSentinelRedisInstance(NULL,SRI_SENTINEL,
                            token[0],port,master->quorum,master);
            if (si) {
                sentinelEvent(REDIS_NOTICE,"+sentinel",si,"%@");
                /* The runid is NULL after a new instance creation and
                 * for Sentinels we don't have a later chance to fill it,
                 * so do it now. */
                si->runid = sdsnew(token[2]);
                sentinelFlushConfig();
            }
        }

        /* Update local current_epoch if received current_epoch is greater.*/
        // 如果消息中记录的纪元比 Sentinel 当前的纪元要高，那么更新纪元
        if (current_epoch > sentinel.current_epoch) {
            sentinel.current_epoch = current_epoch;
            sentinelFlushConfig();
            sentinelEvent(REDIS_WARNING,"+new-epoch",master,"%llu",
                (unsigned long long) sentinel.current_epoch);
        }

        /* Update master info if received configuration is newer. */
        // 如果消息中记录的配置信息更新，那么对主服务器的信息进行更新
        if (master->config_epoch < master_config_epoch) {
            master->config_epoch = master_config_epoch;
            if (master_port != master->addr->port ||
                strcmp(master->addr->ip, token[5]))
            {
                sentinelAddr *old_addr;

                sentinelEvent(REDIS_WARNING,"+config-update-from",si,"%@");
                sentinelEvent(REDIS_WARNING,"+switch-master",
                    master,"%s %s %d %s %d",
                    master->name,
                    master->addr->ip, master->addr->port,
                    token[5], master_port);

                old_addr = dupSentinelAddr(master->addr);
                sentinelResetMasterAndChangeAddress(master, token[5], master_port);
                sentinelCallClientReconfScript(master,
                    SENTINEL_OBSERVER,"start",
                    old_addr,master->addr);
                releaseSentinelAddr(old_addr);
            }
        }

        /* Update the state of the Sentinel. */
        // 更新我方 Sentinel 记录的对方 Sentinel 的信息。
        if (si) si->last_hello_time = mstime();
    }

cleanup:
    sdsfreesplitres(token,numtokens);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x70, %rsp
movq %rdi, -0x8(%rbp)
movl %esi, -0xc(%rbp)
movq -0x8(%rbp), %rdi
movl -0xc(%rbp), %esi
leaq 0x683b8(%rip), %rdx     # 0xe6165
movl $0x1, %ecx
leaq -0x10(%rbp), %r8
callq 0x2d5a0
movq %rax, -0x38(%rbp)
cmpl $0x8, -0x10(%rbp)
jne 0x7e0a1
movq -0x38(%rbp), %rax
movq 0x20(%rax), %rdi
callq 0x7b210
movq %rax, -0x48(%rbp)
cmpq $0x0, -0x48(%rbp)
jne 0x7dde6
jmp 0x7e0a3
movq -0x38(%rbp), %rax
movq 0x8(%rax), %rdi
callq 0x1f700
movl %eax, -0x14(%rbp)
movq -0x38(%rbp), %rax
movq 0x30(%rax), %rdi
callq 0x1f700
movl %eax, -0x1c(%rbp)
movq -0x48(%rbp), %rax
movq 0xc0(%rax), %rdi
movq -0x38(%rbp), %rax
movq (%rax), %rsi
movl -0x14(%rbp), %edx
movq -0x38(%rbp), %rax
movq 0x10(%rax), %rcx
callq 0x7b110
movq %rax, -0x40(%rbp)
movq -0x38(%rbp), %rax
movq 0x18(%rax), %rdi
xorl %eax, %eax
movl %eax, %esi
movl $0xa, %edx
callq 0x1fa10
movq %rax, -0x28(%rbp)
movq -0x38(%rbp), %rax
movq 0x38(%rax), %rdi
xorl %eax, %eax
movl %eax, %esi
movl $0xa, %edx
callq 0x1fa10
movq %rax, -0x30(%rbp)
cmpq $0x0, -0x40(%rbp)
jne 0x7df33
movq -0x48(%rbp), %rdi
movq -0x38(%rbp), %rax
movq (%rax), %rsi
movl -0x14(%rbp), %edx
movq -0x38(%rbp), %rax
movq 0x10(%rax), %rcx
callq 0x7b020
movl %eax, -0x18(%rbp)
cmpl $0x0, -0x18(%rbp)
je 0x7dec4
movq -0x48(%rbp), %rdx
movq -0x38(%rbp), %rax
movq (%rax), %r8
movl -0x14(%rbp), %r9d
movq -0x38(%rbp), %rax
movq 0x10(%rax), %rax
movl $0x2, %edi
leaq 0x6b7c0(%rip), %rsi     # 0xe9672
leaq 0x6b7c7(%rip), %rcx     # 0xe9680
movq %rax, (%rsp)
movb $0x0, %al
callq 0x79b10
movq -0x38(%rbp), %rax
movq (%rax), %rdx
movl -0x14(%rbp), %ecx
movq -0x48(%rbp), %rax
movl 0xd0(%rax), %r8d
movq -0x48(%rbp), %r9
xorl %eax, %eax
movl %eax, %edi
movl $0x4, %esi
callq 0x7a9e0
movq %rax, -0x40(%rbp)
cmpq $0x0, -0x40(%rbp)
je 0x7df31
movq -0x40(%rbp), %rdx
movl $0x2, %edi
leaq 0x6b797(%rip), %rsi     # 0xe969d
leaq 0x6b125(%rip), %rcx     # 0xe9032
movb $0x0, %al
callq 0x79b10
movq -0x38(%rbp), %rax
movq 0x10(%rax), %rdi
callq 0x2c0e0
movq %rax, %rcx
movq -0x40(%rbp), %rax
movq %rcx, 0x10(%rax)
callq 0x7b820
jmp 0x7df33
movq -0x28(%rbp), %rax
cmpq 0xaa2fa(%rip), %rax     # 0x128238
jbe 0x7df75
movq -0x28(%rbp), %rax
movq %rax, 0xaa2ed(%rip)     # 0x128238
callq 0x7b820
movq -0x48(%rbp), %rdx
movq 0xaa2dd(%rip), %r8      # 0x128238
movl $0x3, %edi
leaq 0x6b740(%rip), %rsi     # 0xe96a7
leaq 0x6b48a(%rip), %rcx     # 0xe93f8
movb $0x0, %al
callq 0x79b10
movq -0x48(%rbp), %rax
movq 0x18(%rax), %rax
cmpq -0x30(%rbp), %rax
jae 0x7e088
movq -0x30(%rbp), %rcx
movq -0x48(%rbp), %rax
movq %rcx, 0x18(%rax)
movl -0x1c(%rbp), %eax
movq -0x48(%rbp), %rcx
movq 0x20(%rcx), %rcx
cmpl 0x8(%rcx), %eax
jne 0x7dfc4
movq -0x48(%rbp), %rax
movq 0x20(%rax), %rax
movq (%rax), %rdi
movq -0x38(%rbp), %rax
movq 0x28(%rax), %rsi
callq 0x1f890
cmpl $0x0, %eax
je 0x7e086
movq -0x40(%rbp), %rdx
movl $0x3, %edi
leaq 0x6b6de(%rip), %rsi     # 0xe96b2
leaq 0x6b057(%rip), %rcx     # 0xe9032
movb $0x0, %al
callq 0x79b10
movq -0x48(%rbp), %rdx
movq -0x48(%rbp), %rax
movq 0x8(%rax), %r8
movq -0x48(%rbp), %rax
movq 0x20(%rax), %rax
movq (%rax), %r9
movq -0x48(%rbp), %rax
movq 0x20(%rax), %rax
movl 0x8(%rax), %r11d
movq -0x38(%rbp), %rax
movq 0x28(%rax), %r10
movl -0x1c(%rbp), %eax
movl $0x3, %edi
leaq 0x6b6aa(%rip), %rsi     # 0xe96c6
leaq 0x6b6b2(%rip), %rcx     # 0xe96d5
movl %r11d, (%rsp)
movq %r10, 0x8(%rsp)
movl %eax, 0x10(%rsp)
movb $0x0, %al
callq 0x79b10
movq -0x48(%rbp), %rax
movq 0x20(%rax), %rdi
callq 0x79a30
movq %rax, -0x50(%rbp)
movq -0x48(%rbp), %rdi
movq -0x38(%rbp), %rax
movq 0x28(%rax), %rsi
movl -0x1c(%rbp), %edx
callq 0x7b5c0
movq -0x48(%rbp), %rdi
movq -0x50(%rbp), %rcx
movq -0x48(%rbp), %rax
movq 0x20(%rax), %r8
movl $0x40000, %esi          # imm = 0x40000
leaq 0x6b69b(%rip), %rdx     # 0xe9713
callq 0x7a910
movq -0x50(%rbp), %rdi
callq 0x79a80
jmp 0x7e088
cmpq $0x0, -0x40(%rbp)
je 0x7e09f
callq 0x252e0
movq %rax, %rcx
movq -0x40(%rbp), %rax
movq %rcx, 0x78(%rax)
jmp 0x7e0a1
jmp 0x7e0a3
movq -0x38(%rbp), %rdi
movl -0x10(%rbp), %esi
callq 0x2d7d0
addq $0x70, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)