// File: /workspace/github_cpp_makefile_star2_O2/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 $0x48, %rsp
movq %rdi, %rbx
movq 0x18(%rdi), %rdi
callq 0xabe4
movslq %eax, %r15
movq %r15, %rax
subq 0x30(%rbx), %rax
cmpq $0x5, %rax
jl 0x43d6
movq 0x20(%rbx), %rax
movq 0x30(%rax), %rcx
cmpq 0x28(%rax), %rcx
je 0x43d6
incq 0x18(%rax)
movq %r15, 0x30(%rbx)
callq 0x30a0
movslq %eax, %rcx
movq 0x20(%rbx), %rax
movq 0x28(%rax), %rdi
movq 0x30(%rax), %rax
subq %rdi, %rax
pushq $0x18
popq %rsi
cqto
idivq %rsi
movq %rax, %rsi
movq %rcx, %rax
xorl %edx, %edx
divq %rsi
movslq %edx, %rax
imulq $0x18, %rax, %rsi
addq %rdi, %rsi
leaq 0x18(%rsp), %r14
movq %r14, %rdi
callq 0xac76
movl (%r14), %eax
movzwl 0x4(%r14), %ecx
leaq 0x30(%rsp), %rsi
movl %eax, (%rsi)
movw %cx, 0x4(%rsi)
movq %rbx, %rdi
callq 0x48d6
movq 0x20(%rbx), %rsi
addq $0x8, %rsi
leaq 0x42(%rsp), %rdi
callq 0xac20
movq 0x20(%rbx), %rsi
movq 0x28(%rsi), %r14
leaq -0x13(%r15), %rax
movq %rax, 0x10(%rsp)
movq %r15, (%rsp)
leaq -0x4(%r15), %rax
movq %rax, 0x8(%rsp)
leaq 0x3c(%rsp), %r15
leaq 0x36(%rsp), %r12
leaq 0x18(%rsp), %r13
leaq 0x18ee4(%rip), %rbp     # 0x1d300
cmpq 0x30(%rsi), %r14
je 0x44e0
movl (%r14), %eax
movzwl 0x4(%r14), %ecx
movl %eax, 0x18(%rsp)
movw %cx, 0x1c(%rsp)
addq $0x8, %rsi
movq %r15, %rdi
callq 0xac20
movq %r12, %rdi
movq %r13, %rsi
callq 0xac20
movq %r15, %rsi
movq %r12, %rdx
callq 0x4958
testb %al, %al
jne 0x44d3
movq %rbp, %rdi
movq %r14, %rsi
callq 0x5b18
testq %rax, %rax
je 0x44b6
movq %rbp, %rdi
movq %r14, %rsi
callq 0x5ba8
movq 0x10(%rsp), %rcx
cmpq %rcx, (%rax)
jge 0x44d3
movq 0x20(%rbx), %rdi
addq $0x28, %rdi
movq %r14, %rsi
callq 0x4b54
movq %rax, %r14
movq %rbp, %rdi
movq %rax, %rsi
callq 0x5f10
movq 0x10(%rbx), %rdi
movq 0x20(%rbx), %rsi
addq $0x8, %rsi
movq %r13, %rdx
callq 0xa426
jmp 0x44d7
movq 0x8(%rsp), %rax
cmpq %rax, 0x10(%r14)
jge 0x44d3
movq %rbp, %rdi
movq %r14, %rsi
callq 0x5ba8
movq (%rsp), %rcx
movq %rcx, (%rax)
addq $0x18, %r14
movq 0x20(%rbx), %rsi
jmp 0x441c
addq $0x48, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
nop