// File: nvanbenschoten[P]byzantine-agreement/src/general.cc
// Function: generals::Lieutenant::InitNewRound()
void Lieutenant::InitNewRound() {
  ClearSenders();
  IncrementRound();

  // Determine the set of messages to forward in the next round.
  std::unordered_map<unsigned int, std::vector<msg::Message>> toSend;
  for (msg::Message msg : msgs_this_round_) {
    if (msg.round != round_ - 1) {
      throw std::logic_error(
          "message in msgs_this_round_ not from current round");
    }

    // Update the messages round number to the current round.
    msg.round = round_;

    // Add this process in at the end of the message id list.
    msg.ids.push_back(id_);

    // Determine which processes we need to send this message to.
    for (unsigned int pid = 0; pid < processes_.size(); ++pid) {
      // Only send to processes not already in this message.
      bool inMsg = false;
      for (auto const& id : msg.ids) {
        if (id == pid) {
          inMsg = true;
          break;
        }
      }
      if (!inMsg) {
        if (ShouldSendMsg()) {
          logging::out << "Sending  " << msg << " to p" << pid << "\n";
          toSend[pid].push_back(msg);
        }
      }
    }
  }

  // For each process that we have messages to send to...
  for (auto const& batch : toSend) {
    sender_threads_this_round_.AddThread([this, batch] {
      // Send each message to the process serially in a new thread.
      unsigned int pid = batch.first;
      udp::ClientPtr client = ClientForId(pid);
      for (auto const& msg : batch.second) {
        MaybeDelaySend();
        SendMessage(client, msg);
      }
    });
  }

  // Clear round-specific containers and reset round start timestamp.
  ids_this_round_.clear();
  msgs_this_round_.clear();
  round_start_ts_ = std::chrono::steady_clock::now();
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x150, %rsp            # imm = 0x150
movq %rdi, -0x8(%rbp)
movq -0x8(%rbp), %rdi
movq %rdi, -0x108(%rbp)
callq 0x26ac0
movq -0x108(%rbp), %rdi
callq 0x29b00
leaq -0x40(%rbp), %rdi
callq 0x29b60
movq -0x108(%rbp), %rax
addq $0xa8, %rax
movq %rax, -0x48(%rbp)
movq -0x48(%rbp), %rdi
callq 0x29b80
movq %rax, -0x50(%rbp)
movq -0x48(%rbp), %rdi
callq 0x29bb0
movq %rax, -0x58(%rbp)
leaq -0x50(%rbp), %rdi
leaq -0x58(%rbp), %rsi
callq 0x29be0
testb $0x1, %al
jne 0x26b75
jmp 0x26e34
leaq -0x50(%rbp), %rdi
callq 0x29c10
movq %rax, %rsi
leaq -0x78(%rbp), %rdi
callq 0x29020
jmp 0x26b8c
movq -0x108(%rbp), %rcx
movl -0x78(%rbp), %eax
movl 0x64(%rcx), %ecx
subl $0x1, %ecx
cmpl %ecx, %eax
je 0x26c30
movl $0x10, %edi
callq 0x6240
movq %rax, %rdi
movq %rdi, %rax
movq %rax, -0x110(%rbp)
leaq 0x10b64(%rip), %rsi     # 0x37726
callq 0x6610
jmp 0x26bc9
movq -0x110(%rbp), %rdi
movq 0x2c3e9(%rip), %rsi     # 0x52fc0
movq 0x2c3a2(%rip), %rdx     # 0x52f80
callq 0x6730
jmp 0x26f88
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x80(%rbp)
movl %eax, -0x84(%rbp)
jmp 0x26f76
movq -0x110(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x80(%rbp)
movl %eax, -0x84(%rbp)
callq 0x6300
jmp 0x26e26
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x80(%rbp)
movl %eax, -0x84(%rbp)
jmp 0x26e26
movq -0x108(%rbp), %rsi
movl 0x64(%rsi), %eax
movl %eax, -0x78(%rbp)
leaq -0x70(%rbp), %rdi
addq $0x58, %rsi
callq 0x29c30
jmp 0x26c4c
movl $0x0, -0x88(%rbp)
movq -0x108(%rbp), %rdi
movl -0x88(%rbp), %eax
movq %rax, -0x118(%rbp)
addq $0x8, %rdi
callq 0xcaf0
movq %rax, %rcx
movq -0x118(%rbp), %rax
cmpq %rcx, %rax
jae 0x26e0f
movb $0x0, -0x89(%rbp)
leaq -0x78(%rbp), %rax
addq $0x8, %rax
movq %rax, -0x98(%rbp)
movq -0x98(%rbp), %rdi
callq 0x29ca0
movq %rax, -0xa0(%rbp)
movq -0x98(%rbp), %rdi
callq 0x29cd0
movq %rax, -0xa8(%rbp)
leaq -0xa0(%rbp), %rdi
leaq -0xa8(%rbp), %rsi
callq 0x29d00
testb $0x1, %al
jne 0x26cdb
jmp 0x26d18
leaq -0xa0(%rbp), %rdi
callq 0x29d40
movq %rax, -0xb0(%rbp)
movq -0xb0(%rbp), %rax
movl (%rax), %eax
cmpl -0x88(%rbp), %eax
jne 0x26d08
movb $0x1, -0x89(%rbp)
jmp 0x26d18
jmp 0x26d0a
leaq -0xa0(%rbp), %rdi
callq 0x29d60
jmp 0x26cc2
testb $0x1, -0x89(%rbp)
jne 0x26df9
movq -0x108(%rbp), %rdi
callq 0x26140
movb %al, -0x119(%rbp)
jmp 0x26d39
movb -0x119(%rbp), %al
testb $0x1, %al
jne 0x26d48
jmp 0x26df7
leaq 0x2c921(%rip), %rdi     # 0x53670
leaq 0x109ae(%rip), %rsi     # 0x37704
callq 0x295f0
movq %rax, -0x128(%rbp)
jmp 0x26d64
movq -0x128(%rbp), %rdi
leaq -0x78(%rbp), %rsi
callq 0x29640
movq %rax, -0x130(%rbp)
jmp 0x26d7d
movq -0x130(%rbp), %rdi
leaq 0x10983(%rip), %rsi     # 0x3770e
callq 0x29690
movq %rax, -0x138(%rbp)
jmp 0x26d99
movq -0x138(%rbp), %rdi
leaq -0x88(%rbp), %rsi
callq 0x296e0
movq %rax, -0x140(%rbp)
jmp 0x26db5
movq -0x140(%rbp), %rdi
leaq 0xfd8f(%rip), %rsi      # 0x36b52
callq 0x29730
jmp 0x26dca
leaq -0x40(%rbp), %rdi
leaq -0x88(%rbp), %rsi
callq 0x29d80
movq %rax, -0x148(%rbp)
jmp 0x26de3
movq -0x148(%rbp), %rdi
leaq -0x78(%rbp), %rsi
callq 0x29db0
jmp 0x26df5
jmp 0x26df7
jmp 0x26df9
jmp 0x26dfb
movl -0x88(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x88(%rbp)
jmp 0x26c56
leaq -0x78(%rbp), %rdi
callq 0x28fb0
leaq -0x50(%rbp), %rdi
callq 0x29e20
jmp 0x26b5f
leaq -0x78(%rbp), %rdi
callq 0x28fb0
jmp 0x26f76
leaq -0x40(%rbp), %rax
movq %rax, -0xb8(%rbp)
movq -0xb8(%rbp), %rdi
callq 0x29e50
movq %rax, -0xc0(%rbp)
movq -0xb8(%rbp), %rdi
callq 0x29e80
movq %rax, -0xc8(%rbp)
leaq -0xc0(%rbp), %rdi
leaq -0xc8(%rbp), %rsi
callq 0x29eb0
testb $0x1, %al
jne 0x26e81
jmp 0x26f1a
leaq -0xc0(%rbp), %rdi
callq 0x29ee0
movq %rax, %rcx
movq -0x108(%rbp), %rax
movq %rcx, -0xd0(%rbp)
movq %rax, %rcx
addq $0x108, %rcx            # imm = 0x108
movq %rcx, -0x150(%rbp)
movq %rax, -0xf8(%rbp)
leaq -0xf0(%rbp), %rdi
movq -0xd0(%rbp), %rsi
callq 0x29f10
jmp 0x26ecb
movq -0x150(%rbp), %rdi
leaq -0xf8(%rbp), %rsi
callq 0x26f90
jmp 0x26ee0
leaq -0xf8(%rbp), %rdi
callq 0x27000
leaq -0xc0(%rbp), %rdi
callq 0x29f50
jmp 0x26e65
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x80(%rbp)
movl %eax, -0x84(%rbp)
leaq -0xf8(%rbp), %rdi
callq 0x27000
jmp 0x26f76
movq -0x108(%rbp), %rdi
addq $0xd8, %rdi
callq 0x29f80
movq -0x108(%rbp), %rdi
addq $0xa8, %rdi
callq 0x29fa0
callq 0x65a0
movq %rax, %rcx
movq -0x108(%rbp), %rax
movq %rcx, -0x100(%rbp)
movq -0x100(%rbp), %rcx
movq %rcx, 0xa0(%rax)
leaq -0x40(%rbp), %rdi
callq 0x29fc0
addq $0x150, %rsp            # imm = 0x150
popq %rbp
retq
leaq -0x40(%rbp), %rdi
callq 0x29fc0
movq -0x80(%rbp), %rdi
callq 0x6750
nopl (%rax,%rax)