// File: /workspace/github_cpp_makefile_star2_O3/tonymuu[P]distributed-kv-store/MP1Node.cpp
// Function: MP1Node::nodeLoopOps()
void MP1Node::nodeLoopOps() {
    long currTime = par->getcurrtime();
    auto shouldSendGossip = (currTime - timeLastGossip) >= TGOSSIP && memberNode->memberList.size() > 0;

    // select a random neighbour and send gossip
    if (shouldSendGossip) {
        memberNode->heartbeat++;
        timeLastGossip = currTime;
        int index = rand() % memberNode->memberList.size();
        auto neighbour = memberNode->memberList[index];
        Address neighbourAddr = createAddressFromIdAndPort(neighbour.id, neighbour.port);
        sendGossip(&neighbourAddr);
    }

    int id = 0;
    short port = 0;
    setIdAndPortFromAddress(memberNode->addr, &id, &port);

    // update any node that has failed, remove any failed nodes that are passed Tcleanup
    // If a node's heartbeat hasn't increased for more than Tfail (currentTime - node.timestamp), we mark it as failed
    // if a node is marked as failed for more than Tcleanup, remove the node from list, and log
    auto neighbour = memberNode->memberList.begin();
    while (neighbour != memberNode->memberList.end()) {
        Address neighbourAddr = createAddressFromIdAndPort(neighbour->id, neighbour->port);
        if (areAddressesEqual(memberNode->addr, neighbourAddr)) {
            neighbour++;
            continue;
        }

        auto hasFailed = failed.count(neighbour->id) != 0;
        long timeSinceLastUpdate = currTime - neighbour->timestamp;
        if (hasFailed && currTime - failed[neighbour->id] >= TREMOVE) { // remove node
            neighbour = memberNode->memberList.erase(neighbour);
            failed.erase(neighbour->id);
            log->logNodeRemove(&(memberNode->addr), &neighbourAddr);
            continue;
        }

        if (!hasFailed && timeSinceLastUpdate >= TFAIL) { // if node has failed, we don't send msg to it
            failed[neighbour->id] = currTime;
            hasFailed = true;
        }
        neighbour++;
    }

    return;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x58, %rsp
movq %rdi, %rbx
movq 0x18(%rdi), %rdi
callq 0xc87e
cltq
movq %rax, 0x8(%rsp)
subq 0x30(%rbx), %rax
cmpq $0x5, %rax
jl 0x48b0
movq 0x20(%rbx), %rax
movq 0x30(%rax), %rcx
cmpq 0x28(%rax), %rcx
je 0x48b0
incq 0x18(%rax)
movq 0x8(%rsp), %rax
movq %rax, 0x30(%rbx)
callq 0x30a0
cltq
movq 0x20(%rbx), %rcx
movq 0x28(%rcx), %rsi
movq 0x30(%rcx), %rcx
subq %rsi, %rcx
sarq $0x3, %rcx
movabsq $-0x5555555555555555, %rdi # imm = 0xAAAAAAAAAAAAAAAB
imulq %rcx, %rdi
xorl %edx, %edx
divq %rdi
movslq %edx, %rax
leaq (%rax,%rax,2), %rax
leaq (%rsi,%rax,8), %rsi
leaq 0x30(%rsp), %r14
movq %r14, %rdi
callq 0xc926
movl (%r14), %eax
movzwl 0x4(%r14), %ecx
leaq 0x4c(%rsp), %rsi
movl %eax, (%rsi)
movw %cx, 0x4(%rsi)
movq %rbx, %rdi
callq 0x4e02
movq 0x20(%rbx), %rsi
addq $0x8, %rsi
leaq 0x52(%rsp), %rdi
callq 0xc8c4
movq 0x20(%rbx), %rsi
movq 0x28(%rsi), %r14
cmpq 0x30(%rsi), %r14
je 0x49cb
movq 0x8(%rsp), %rax
leaq -0x13(%rax), %rcx
movq %rcx, 0x28(%rsp)
addq $-0x4, %rax
movq %rax, 0x20(%rsp)
leaq 0x1a(%rsp), %r15
leaq 0x14(%rsp), %r12
leaq 0x30(%rsp), %r13
leaq 0x1b9ef(%rip), %rbp     # 0x202f0
movl (%r14), %eax
movzwl 0x4(%r14), %ecx
movl %eax, 0x30(%rsp)
movw %cx, 0x34(%rsp)
addq $0x8, %rsi
movq %r15, %rdi
callq 0xc8c4
movq %r12, %rdi
movq %r13, %rsi
callq 0xc8c4
movl 0x1a(%rsp), %eax
xorl 0x14(%rsp), %eax
movzwl 0x1e(%rsp), %ecx
xorw 0x18(%rsp), %cx
movzwl %cx, %ecx
orl %eax, %ecx
je 0x49b9
movq %rbp, %rdi
movq %r14, %rsi
callq 0x5e8a
testq %rax, %rax
je 0x499b
movq %rbp, %rdi
movq %r14, %rsi
callq 0x5ee6
movq 0x28(%rsp), %rcx
cmpq %rcx, (%rax)
jge 0x49b9
movq 0x20(%rbx), %rdi
addq $0x28, %rdi
movq %r14, %rsi
callq 0x6176
movq %rax, %r14
movq %rbp, %rdi
movq %rax, %rsi
callq 0x61ea
movq 0x10(%rbx), %rdi
movq 0x20(%rbx), %rsi
addq $0x8, %rsi
movq %r13, %rdx
callq 0xbeea
jmp 0x49bd
movq 0x20(%rsp), %rax
cmpq %rax, 0x10(%r14)
jge 0x49b9
movq %rbp, %rdi
movq %r14, %rsi
callq 0x5ee6
movq 0x8(%rsp), %rcx
movq %rcx, (%rax)
addq $0x18, %r14
movq 0x20(%rbx), %rsi
cmpq 0x30(%rsi), %r14
jne 0x4901
addq $0x58, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq