// File: /workspace/github_c_makefile_star2_O0/nilyang[P]redis-tdd-annotation/src/sentinel.c
// Function: createSentinelRedisInstance
sentinelRedisInstance *createSentinelRedisInstance(char *name, int flags, char *hostname, int port, int quorum, sentinelRedisInstance *master) {
    sentinelRedisInstance *ri;
    sentinelAddr *addr;
    dict *table = NULL;
    char slavename[128], *sdsname;

    redisAssert(flags & (SRI_MASTER|SRI_SLAVE|SRI_SENTINEL));
    redisAssert((flags & SRI_MASTER) || master != NULL);

    /* Check address validity. */
    // 保存 IP 地址和端口号到 addr
    addr = createSentinelAddr(hostname,port);
    if (addr == NULL) return NULL;

    /* For slaves and sentinel we use ip:port as name. */
    // 如果实例是从服务器或者 sentinel ，那么使用 ip:port 格式为实例设置名字
    if (flags & (SRI_SLAVE|SRI_SENTINEL)) {
        snprintf(slavename,sizeof(slavename),
            strchr(hostname,':') ? "[%s]:%d" : "%s:%d",
            hostname,port);
        name = slavename;
    }

    /* Make sure the entry is not duplicated. This may happen when the same
     * name for a master is used multiple times inside the configuration or
     * if we try to add multiple times a slave or sentinel with same ip/port
     * to a master. */
    // 配置文件中添加了重复的主服务器配置
    // 或者尝试添加一个相同 ip 或者端口号的从服务器或者 sentinel 时
    // 就可能出现重复添加同一个实例的情况
    // 为了避免这种现象，程序在添加新实例之前，需要先检查实例是否已存在
    // 只有不存在的实例会被添加

    // 选择要添加的表
    // 注意主服务会被添加到 sentinel.masters 表
    // 而从服务器和 sentinel 则会被添加到 master 所属的 slaves 表和 sentinels 表中
    if (flags & SRI_MASTER) table = sentinel.masters;
    else if (flags & SRI_SLAVE) table = master->slaves;
    else if (flags & SRI_SENTINEL) table = master->sentinels;
    sdsname = sdsnew(name);
    if (dictFind(table,sdsname)) {

        // 实例已存在，函数直接返回

        sdsfree(sdsname);
        errno = EBUSY;
        return NULL;
    }

    /* Create the instance object. */
    // 创建实例对象
    ri = zmalloc(sizeof(*ri));
    /* Note that all the instances are started in the disconnected state,
     * the event loop will take care of connecting them. */
    // 所有连接都已断线为起始状态，sentinel 会在需要时自动为它创建连接
    ri->flags = flags | SRI_DISCONNECTED;
    ri->name = sdsname;
    ri->runid = NULL;
    ri->config_epoch = 0;
    ri->addr = addr;
    ri->cc = NULL;
    ri->pc = NULL;
    ri->pending_commands = 0;
    ri->cc_conn_time = 0;
    ri->pc_conn_time = 0;
    ri->pc_last_activity = 0;
    /* We set the last_ping_time to "now" even if we actually don't have yet
     * a connection with the node, nor we sent a ping.
     * This is useful to detect a timeout in case we'll not be able to connect
     * with the node at all. */
    ri->last_ping_time = mstime();
    ri->last_avail_time = mstime();
    ri->last_pong_time = mstime();
    ri->last_pub_time = mstime();
    ri->last_hello_time = mstime();
    ri->last_master_down_reply_time = mstime();
    ri->s_down_since_time = 0;
    ri->o_down_since_time = 0;
    ri->down_after_period = master ? master->down_after_period :
                            SENTINEL_DEFAULT_DOWN_AFTER;
    ri->master_link_down_time = 0;
    ri->auth_pass = NULL;
    ri->slave_priority = SENTINEL_DEFAULT_SLAVE_PRIORITY;
    ri->slave_reconf_sent_time = 0;
    ri->slave_master_host = NULL;
    ri->slave_master_port = 0;
    ri->slave_master_link_status = SENTINEL_MASTER_LINK_STATUS_DOWN;
    ri->slave_repl_offset = 0;
    ri->sentinels = dictCreate(&instancesDictType,NULL);
    ri->quorum = quorum;
    ri->parallel_syncs = SENTINEL_DEFAULT_PARALLEL_SYNCS;
    ri->master = master;
    ri->slaves = dictCreate(&instancesDictType,NULL);
    ri->info_refresh = 0;

    /* Failover state. */
    ri->leader = NULL;
    ri->leader_epoch = 0;
    ri->failover_epoch = 0;
    ri->failover_state = SENTINEL_FAILOVER_STATE_NONE;
    ri->failover_state_change_time = 0;
    ri->failover_start_time = 0;
    ri->failover_timeout = SENTINEL_DEFAULT_FAILOVER_TIMEOUT;
    ri->failover_delay_logged = 0;
    ri->promoted_slave = NULL;
    ri->notification_script = NULL;
    ri->client_reconfig_script = NULL;

    /* Role */
    ri->role_reported = ri->flags & (SRI_MASTER|SRI_SLAVE);
    ri->role_reported_time = mstime();
    ri->slave_conf_change_time = mstime();

    /* Add into the right table. */
    // 将实例添加到适当的表中
    dictAdd(table, ri->name, ri);

    // 返回实例
    return ri;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xf0, %rsp
movq %rdi, -0x10(%rbp)
movl %esi, -0x14(%rbp)
movq %rdx, -0x20(%rbp)
movl %ecx, -0x24(%rbp)
movl %r8d, -0x28(%rbp)
movq %r9, -0x30(%rbp)
movq $0x0, -0x48(%rbp)
movl -0x14(%rbp), %eax
andl $0x7, %eax
cmpl $0x0, %eax
je 0x7aa16
jmp 0x7aa38
leaq 0x6e591(%rip), %rdi     # 0xe8fae
leaq 0x6e3c4(%rip), %rsi     # 0xe8de8
movl $0x50c, %edx            # imm = 0x50C
callq 0x63ca0
movl $0x1, %edi
callq 0x1f3b0
movl -0x14(%rbp), %eax
andl $0x1, %eax
cmpl $0x0, %eax
jne 0x7aa4a
cmpq $0x0, -0x30(%rbp)
je 0x7aa4c
jmp 0x7aa6e
leaq 0x6e587(%rip), %rdi     # 0xe8fda
leaq 0x6e38e(%rip), %rsi     # 0xe8de8
movl $0x50d, %edx            # imm = 0x50D
callq 0x63ca0
movl $0x1, %edi
callq 0x1f3b0
movq -0x20(%rbp), %rdi
movl -0x24(%rbp), %esi
callq 0x79990
movq %rax, -0x40(%rbp)
cmpq $0x0, -0x40(%rbp)
jne 0x7aa92
movq $0x0, -0x8(%rbp)
jmp 0x7aec8
movl -0x14(%rbp), %eax
andl $0x6, %eax
cmpl $0x0, %eax
je 0x7aaf8
leaq -0xd0(%rbp), %rax
movq %rax, -0xe0(%rbp)
movq -0x20(%rbp), %rdi
movl $0x3a, %esi
callq 0x1f790
movq -0xe0(%rbp), %rdi
movq %rax, %rcx
leaq 0x67fa3(%rip), %rdx     # 0xe2a6d
leaq 0x66687(%rip), %rax     # 0xe1158
cmpq $0x0, %rcx
cmovneq %rax, %rdx
movq -0x20(%rbp), %rcx
movl -0x24(%rbp), %r8d
movl $0x80, %esi
movb $0x0, %al
callq 0x1f120
leaq -0xd0(%rbp), %rax
movq %rax, -0x10(%rbp)
movl -0x14(%rbp), %eax
andl $0x1, %eax
cmpl $0x0, %eax
je 0x7ab10
movq 0xad736(%rip), %rax     # 0x128240
movq %rax, -0x48(%rbp)
jmp 0x7ab4a
movl -0x14(%rbp), %eax
andl $0x2, %eax
cmpl $0x0, %eax
je 0x7ab2c
movq -0x30(%rbp), %rax
movq 0xc8(%rax), %rax
movq %rax, -0x48(%rbp)
jmp 0x7ab48
movl -0x14(%rbp), %eax
andl $0x4, %eax
cmpl $0x0, %eax
je 0x7ab46
movq -0x30(%rbp), %rax
movq 0xc0(%rax), %rax
movq %rax, -0x48(%rbp)
jmp 0x7ab48
jmp 0x7ab4a
movq -0x10(%rbp), %rdi
callq 0x2c0e0
movq %rax, -0xd8(%rbp)
movq -0x48(%rbp), %rdi
movq -0xd8(%rbp), %rsi
callq 0x23aa0
cmpq $0x0, %rax
je 0x7ab94
movq -0xd8(%rbp), %rdi
callq 0x2c160
callq 0x1f820
movl $0x10, (%rax)
movq $0x0, -0x8(%rbp)
jmp 0x7aec8
movl $0x170, %edi            # imm = 0x170
callq 0x2e130
movq %rax, -0x38(%rbp)
movl -0x14(%rbp), %ecx
orl $0x8, %ecx
movq -0x38(%rbp), %rax
movl %ecx, (%rax)
movq -0xd8(%rbp), %rcx
movq -0x38(%rbp), %rax
movq %rcx, 0x8(%rax)
movq -0x38(%rbp), %rax
movq $0x0, 0x10(%rax)
movq -0x38(%rbp), %rax
movq $0x0, 0x18(%rax)
movq -0x40(%rbp), %rcx
movq -0x38(%rbp), %rax
movq %rcx, 0x20(%rax)
movq -0x38(%rbp), %rax
movq $0x0, 0x28(%rax)
movq -0x38(%rbp), %rax
movq $0x0, 0x30(%rax)
movq -0x38(%rbp), %rax
movl $0x0, 0x38(%rax)
movq -0x38(%rbp), %rax
movq $0x0, 0x40(%rax)
movq -0x38(%rbp), %rax
movq $0x0, 0x48(%rax)
movq -0x38(%rbp), %rax
movq $0x0, 0x50(%rax)
callq 0x252e0
movq %rax, %rcx
movq -0x38(%rbp), %rax
movq %rcx, 0x60(%rax)
callq 0x252e0
movq %rax, %rcx
movq -0x38(%rbp), %rax
movq %rcx, 0x58(%rax)
callq 0x252e0
movq %rax, %rcx
movq -0x38(%rbp), %rax
movq %rcx, 0x68(%rax)
callq 0x252e0
movq %rax, %rcx
movq -0x38(%rbp), %rax
movq %rcx, 0x70(%rax)
callq 0x252e0
movq %rax, %rcx
movq -0x38(%rbp), %rax
movq %rcx, 0x78(%rax)
callq 0x252e0
movq %rax, %rcx
movq -0x38(%rbp), %rax
movq %rcx, 0x80(%rax)
movq -0x38(%rbp), %rax
movq $0x0, 0x88(%rax)
movq -0x38(%rbp), %rax
movq $0x0, 0x90(%rax)
cmpq $0x0, -0x30(%rbp)
je 0x7acc4
movq -0x30(%rbp), %rax
movq 0x98(%rax), %rax
movq %rax, -0xe8(%rbp)
jmp 0x7acd2
movl $0x7530, %eax           # imm = 0x7530
movq %rax, -0xe8(%rbp)
jmp 0x7acd2
movq -0xe8(%rbp), %rcx
movq -0x38(%rbp), %rax
movq %rcx, 0x98(%rax)
movq -0x38(%rbp), %rax
movq $0x0, 0xe0(%rax)
movq -0x38(%rbp), %rax
movq $0x0, 0xd8(%rax)
movq -0x38(%rbp), %rax
movl $0x64, 0xe8(%rax)
movq -0x38(%rbp), %rax
movq $0x0, 0xf0(%rax)
movq -0x38(%rbp), %rax
movq $0x0, 0x100(%rax)
movq -0x38(%rbp), %rax
movl $0x0, 0x108(%rax)
movq -0x38(%rbp), %rax
movl $0x1, 0x10c(%rax)
movq -0x38(%rbp), %rax
movq $0x0, 0x110(%rax)
leaq 0x97ef0(%rip), %rdi     # 0x112c50
xorl %eax, %eax
movl %eax, %esi
callq 0x231a0
movq %rax, %rcx
movq -0x38(%rbp), %rax
movq %rcx, 0xc0(%rax)
movl -0x28(%rbp), %ecx
movq -0x38(%rbp), %rax
movl %ecx, 0xd0(%rax)
movq -0x38(%rbp), %rax
movl $0x1, 0xd4(%rax)
movq -0x30(%rbp), %rcx
movq -0x38(%rbp), %rax
movq %rcx, 0xf8(%rax)
leaq 0x97ea8(%rip), %rdi     # 0x112c50
xorl %eax, %eax
movl %eax, %esi
callq 0x231a0
movq %rax, %rcx
movq -0x38(%rbp), %rax
movq %rcx, 0xc8(%rax)
movq -0x38(%rbp), %rax
movq $0x0, 0xa0(%rax)
movq -0x38(%rbp), %rax
movq $0x0, 0x118(%rax)
movq -0x38(%rbp), %rax
movq $0x0, 0x120(%rax)
movq -0x38(%rbp), %rax
movq $0x0, 0x128(%rax)
movq -0x38(%rbp), %rax
movl $0x0, 0x130(%rax)
movq -0x38(%rbp), %rax
movq $0x0, 0x138(%rax)
movq -0x38(%rbp), %rax
movq $0x0, 0x140(%rax)
movq -0x38(%rbp), %rax
movq $0x2bf20, 0x148(%rax) # imm = 0x2BF20
movq -0x38(%rbp), %rax
movq $0x0, 0x150(%rax)
movq -0x38(%rbp), %rax
movq $0x0, 0x158(%rax)
movq -0x38(%rbp), %rax
movq $0x0, 0x160(%rax)
movq -0x38(%rbp), %rax
movq $0x0, 0x168(%rax)
movq -0x38(%rbp), %rax
movl (%rax), %ecx
andl $0x3, %ecx
movq -0x38(%rbp), %rax
movl %ecx, 0xa8(%rax)
callq 0x252e0
movq %rax, %rcx
movq -0x38(%rbp), %rax
movq %rcx, 0xb0(%rax)
callq 0x252e0
movq %rax, %rcx
movq -0x38(%rbp), %rax
movq %rcx, 0xb8(%rax)
movq -0x48(%rbp), %rdi
movq -0x38(%rbp), %rax
movq 0x8(%rax), %rsi
movq -0x38(%rbp), %rdx
callq 0x236d0
movq -0x38(%rbp), %rax
movq %rax, -0x8(%rbp)
movq -0x8(%rbp), %rax
addq $0xf0, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)