// File: zkl94[P]distributed-key-value-store/MP1Node.cpp
// Function: MP1Node::handleMEMBERLIST(void*, char*, int)
void MP1Node::handleMEMBERLIST(void *env, char *data, int size) {
    #ifdef DEBUG_MEMBERLIST
        cout << "just got a member list" << endl;
    #endif

    int entry_num = (size - 4)/ (6+8);
    int currentOffset = 4;
    char addr[6];
    int id = 0;
    short port;
    long heartbeat = 0;

    MessageHdr *msg = (MessageHdr *)data;

    // if, during the process of to be deleted, a heartbeat from that node is received,
    // the node entry should be removed from to be deleted map and member list entry
    // should be re-activated
    // how to tell: the first entry in message is the node's source
    memcpy(&addr, (char *)(msg)+currentOffset, 6);
    memcpy(&id, &addr[0], sizeof(int));
    if (this->tobedeleted->count(id) != 0) {
        std::map<int, int>::iterator it = this->tobedeleted->begin();
    
        while(it != this->tobedeleted->end()) {
            if (it->first == id) {
                this->tobedeleted->erase(it);
                break;
            }
            ++it;
        }
    } // then updateEntry will do the normal update

    // for every addr and heartbeat in the incoming member list
    for (int i = 0; i < entry_num; ++i)
    {
        // extract id and port
        memcpy(&addr, (char *)(msg)+currentOffset, 6);
        currentOffset += 6;
        memcpy(&id, &addr[0], sizeof(int));
        memcpy(&port, &addr[4], sizeof(short));
        
        // heartbeat
        memcpy(&heartbeat, (char *)(msg)+currentOffset, 8);
        currentOffset += 8;

        updateEntry(memberNode, id, port, heartbeat);
    }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x80, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movl %ecx, -0x1c(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x78(%rbp)
movl -0x1c(%rbp), %eax
subl $0x4, %eax
movl $0xe, %ecx
cltd
idivl %ecx
movl %eax, %ecx
movq -0x78(%rbp), %rax
movl %ecx, -0x20(%rbp)
movl $0x4, -0x24(%rbp)
movl $0x0, -0x30(%rbp)
movq $0x0, -0x40(%rbp)
movq -0x18(%rbp), %rcx
movq %rcx, -0x48(%rbp)
movq -0x48(%rbp), %rcx
movslq -0x24(%rbp), %rdx
movl (%rcx,%rdx), %esi
movl %esi, -0x2a(%rbp)
movw 0x4(%rcx,%rdx), %cx
movw %cx, -0x26(%rbp)
movl -0x2a(%rbp), %ecx
movl %ecx, -0x30(%rbp)
movq 0x38(%rax), %rdi
leaq -0x30(%rbp), %rsi
callq 0x7310
cmpq $0x0, %rax
je 0x6588
movq -0x78(%rbp), %rax
movq 0x38(%rax), %rdi
callq 0x7390
movq %rax, -0x50(%rbp)
movq -0x78(%rbp), %rax
movq 0x38(%rax), %rdi
callq 0x73f0
movq %rax, -0x58(%rbp)
leaq -0x50(%rbp), %rdi
leaq -0x58(%rbp), %rsi
callq 0x73c0
testb $0x1, %al
jne 0x654c
jmp 0x6586
leaq -0x50(%rbp), %rdi
callq 0x7420
movl (%rax), %eax
cmpl -0x30(%rbp), %eax
jne 0x657b
movq -0x78(%rbp), %rax
movq 0x38(%rax), %rdi
movq -0x50(%rbp), %rax
movq %rax, -0x60(%rbp)
movq -0x60(%rbp), %rsi
callq 0x7450
movq %rax, -0x68(%rbp)
jmp 0x6586
leaq -0x50(%rbp), %rdi
callq 0x7490
jmp 0x6528
jmp 0x6588
movl $0x0, -0x6c(%rbp)
movl -0x6c(%rbp), %eax
cmpl -0x20(%rbp), %eax
jge 0x6604
movq -0x78(%rbp), %rdi
movq -0x48(%rbp), %rax
movslq -0x24(%rbp), %rcx
movl (%rax,%rcx), %edx
movl %edx, -0x2a(%rbp)
movw 0x4(%rax,%rcx), %ax
movw %ax, -0x26(%rbp)
movl -0x24(%rbp), %eax
addl $0x6, %eax
movl %eax, -0x24(%rbp)
movl -0x2a(%rbp), %eax
movl %eax, -0x30(%rbp)
movw -0x26(%rbp), %ax
movw %ax, -0x32(%rbp)
movq -0x48(%rbp), %rax
movslq -0x24(%rbp), %rcx
movq (%rax,%rcx), %rax
movq %rax, -0x40(%rbp)
movl -0x24(%rbp), %eax
addl $0x8, %eax
movl %eax, -0x24(%rbp)
movq 0x20(%rdi), %rsi
movl -0x30(%rbp), %edx
movw -0x32(%rbp), %ax
movq -0x40(%rbp), %r8
movswl %ax, %ecx
callq 0x6610
movl -0x6c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x6c(%rbp)
jmp 0x658f
addq $0x80, %rsp
popq %rbp
retq
nopl (%rax)