// File: /workspace/github_cpp_makefile_star2_O1/nvanbenschoten[P]total-order-multicast/src/process.cc
// Function: process::HoldBackQueue::SetDeliverable(msg::SeqMessage const&, std::function<void (msg::SeqMessage&)>)
void HoldBackQueue::SetDeliverable(const msg::SeqMessage& seq_msg,
                                   const deliverMsgFn deliver) {
  // Look up the messages old sequence information in the sequence map using the
  // messages uniquely defining information. This allows us to find the pending
  // message in the ordered set faster.
  PendingMessageKey pmk;
  pmk.sender = seq_msg.sender;
  pmk.msg_id = seq_msg.msg_id;

  auto old_pms_it = pending_seqs_.find(pmk);
  if (old_pms_it == pending_seqs_.end()) {
    // Return without error to permit message replays.
    logging::out << "Unknown SeqMessage " << seq_msg << "...\n";
    return;
  }

  // Remove the message from the sequence cache.
  PendingMessageSeq old_pms = old_pms_it->second;
  pending_seqs_.erase(old_pms_it);

  // Remove old pending message.
  PendingMessage pm;
  pm.pmk = pmk;
  pm.pms = old_pms;
  pm.deliverable = false;
  ordering_.erase(pm);

  // Update with the new information and reinsert.
  PendingMessageSeq pms;
  pms.seq = seq_msg.final_seq;
  pms.seq_proposer = seq_msg.final_seq_proposer;

  pm.pms = pms;
  pm.deliverable = true;
  ordering_.insert(pm);

  // Iterate through map and deliver messages that can be delivered.
  for (auto it = ordering_.begin(); it != ordering_.end() /* not hoisted */;) {
    if (!it->deliverable) {
      break;
    }
    // Deliver and delete for as long as the head of the queue is deliverable.
    msg::SeqMessage to_deliver;
    to_deliver.sender = it->pmk.sender;
    to_deliver.msg_id = it->pmk.msg_id;
    to_deliver.final_seq = it->pms.seq;
    to_deliver.final_seq_proposer = it->pms.seq_proposer;
    deliver(to_deliver);

    // Erase and move to next message in ordered map.
    it = ordering_.erase(it);
  }
}

// Assembly:
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x40, %rsp
movq %rdx, %rbx
movq %rsi, %r12
movq %rdi, %r14
movl 0x4(%rsi), %eax
leaq 0x8(%rsp), %rsi
movl %eax, (%rsi)
movl 0x8(%r12), %eax
movl %eax, 0x4(%rsi)
callq 0x895e
testq %rax, %rax
je 0x6634
movq 0x10(%rax), %r15
movq %r14, %rdi
movq %rax, %rsi
callq 0x8e40
movq 0x8(%rsp), %rax
leaq 0x28(%rsp), %r13
movq %rax, (%r13)
movq %r15, 0x8(%r13)
movb $0x0, 0x14(%r13)
leaq 0x38(%r14), %r15
movq %r15, %rdi
movq %r13, %rsi
callq 0x8f08
movq %r15, %rdi
movq %rax, %rsi
callq 0x8fc4
movq 0xc(%r12), %rax
movq %rax, 0x8(%r13)
movb $0x1, 0x14(%r13)
movq %r15, %rdi
movq %r13, %rsi
callq 0x8d06
movq 0x50(%r14), %r12
addq $0x40, %r14
cmpq %r14, %r12
je 0x666b
leaq 0x14(%rsp), %r13
cmpb $0x1, 0x34(%r12)
jne 0x666b
movl 0x20(%r12), %eax
movl %eax, 0x18(%rsp)
movl 0x24(%r12), %eax
movl %eax, 0x1c(%rsp)
movl 0x28(%r12), %eax
movl %eax, 0x20(%rsp)
movl 0x2c(%r12), %eax
movl %eax, 0x24(%rsp)
cmpq $0x0, 0x10(%rbx)
je 0x6679
movq %rbx, %rdi
movq %r13, %rsi
callq *0x18(%rbx)
movq %r15, %rdi
movq %r12, %rsi
callq 0x90a6
movq %rax, %r12
cmpq %r14, %rax
jne 0x65df
jmp 0x666b
leaq 0x15ec5(%rip), %rdi     # 0x1c500
leaq 0xdc68(%rip), %rsi      # 0x142aa
callq 0x7786
movq %rax, %rbx
movb 0x8(%rax), %al
testb $0x1, %al
je 0x665c
movq (%rbx), %rdi
movq %r12, %rsi
callq 0x132d6
leaq 0xdc5b(%rip), %rsi      # 0x142be
movq %rbx, %rdi
callq 0x77ba
addq $0x40, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
retq
callq 0x5140