// File: /workspace/github_c_makefile_star2_O0/aspone[P]OrderBook/./OrderBook.h
// Function: OrderBook::OrderBook<unsigned int, OrderLevelEntry>::handleTrade(TradeMessage&)
void handleTrade(TradeMessage &tm) {
      // Confirm levels are active.  For buy orders, we take highest buy level
      // and assume the trade price was due to lowest sell order.
      if (buy_book_map_.empty() || sell_book_map_.empty()) {
         FHErrorTracker::instance()->tradeMissingOrders();
         return;
      }

      // Match against highest buy orders on book
      auto bit = buy_book_map_.end();
      --bit;
      if (bit->first < tm.trade_price_) {
         FHErrorTracker::instance()->tradeMissingOrders();
         return;
      }

      // Sell order drives trade price
      auto sit = sell_book_map_.find(tm.trade_price_);
      if (sit == sell_book_map_.end()) {
         FHErrorTracker::instance()->tradeMissingOrders();
         return;
      }

      // Confirm sufficient qty for execution
      if (bit->second.getQuantity() < tm.trade_qty_ ||
          sit->second.getQuantity() < tm.trade_qty_) {
         FHErrorTracker::instance()->tradeMissingOrders();
         return;
      }

      // Buy side - remove orders as matched if trade depletes them
      uint32_t trade_qty = tm.trade_qty_;
      while (trade_qty > 0) {
         ORDERTYPE *tail = bit->second.getTail();
         if (tail->order_qty_ > trade_qty) {
            trade_qty = 0;
         }
         else {
            trade_qty -= tail->order_qty_;
         }

         if (tm.trade_qty_ >= tail->order_qty_) {
            bit->second.removeNode(tail);
            auto odit = orders_.find(tail->order_id_);
            delete odit->second;
            orders_.erase(odit);
         }
         else {
            bit->second.changeNodeQuantity(tail, tail->order_qty_ - tm.trade_qty_);
         }
      }
      if (bit->second.getQuantity() == 0) {
         buy_book_map_.erase(bit);
      }

      // Repeat for Sell side
      trade_qty = tm.trade_qty_;
      while (trade_qty > 0) {
         ORDERTYPE *tail = sit->second.getTail();
         if (tail->order_qty_ > trade_qty) {
            trade_qty = 0;
         }
         else {
            trade_qty -= tail->order_qty_;
         }

         if (tm.trade_qty_ >= tail->order_qty_) {
            sit->second.removeNode(tail);
            auto odit = orders_.find(tail->order_id_);
            delete odit->second;
            orders_.erase(odit);
         }
         else {
            sit->second.changeNodeQuantity(tail, tail->order_qty_ - tm.trade_qty_);
         }
      }
      if (sit->second.getQuantity() == 0) {
         sell_book_map_.erase(sit);
      }

      // Update recent_trade_price and recent_trade_qty and print
      if (tm.trade_price_ != recent_trade_price_) {
         recent_trade_price_ = tm.trade_price_;
         recent_trade_qty_ = 0;
      }
      recent_trade_qty_ += tm.trade_qty_;

      // Request is to print once per trade message, not once per matched trade.
      char trade_buffer[25];
      sprintf(trade_buffer, "%u@%.2f\n", recent_trade_qty_, recent_trade_price_ / 100.);
      logger_.print(trade_buffer);

      checkCross();
   }

// Assembly:
subq $0x128, %rsp            # imm = 0x128
movq %rdi, 0x120(%rsp)
movq %rsi, 0x118(%rsp)
movq 0x120(%rsp), %rdi
movq %rdi, 0x30(%rsp)
addq $0xd8, %rdi
callq 0xb760
testb $0x1, %al
jne 0x6b1b
movq 0x30(%rsp), %rdi
addq $0x108, %rdi            # imm = 0x108
callq 0xb760
testb $0x1, %al
jne 0x6b1b
jmp 0x6b2d
callq 0x3a30
movq %rax, %rdi
callq 0xb780
jmp 0x70cd
movq 0x30(%rsp), %rdi
addq $0xd8, %rdi
callq 0x5310
movq %rax, 0x110(%rsp)
leaq 0x110(%rsp), %rdi
callq 0xb7a0
leaq 0x110(%rsp), %rdi
callq 0x5340
movq (%rax), %rax
movq 0x118(%rsp), %rcx
cmpq 0x8(%rcx), %rax
jae 0x6b83
callq 0x3a30
movq %rax, %rdi
callq 0xb780
jmp 0x70cd
movq 0x30(%rsp), %rdi
addq $0x108, %rdi            # imm = 0x108
movq 0x118(%rsp), %rsi
addq $0x8, %rsi
callq 0xb7d0
movq 0x30(%rsp), %rdi
movq %rax, 0x108(%rsp)
addq $0x108, %rdi            # imm = 0x108
callq 0x5310
movq %rax, 0x100(%rsp)
leaq 0x108(%rsp), %rdi
leaq 0x100(%rsp), %rsi
callq 0xb800
testb $0x1, %al
jne 0x6bdc
jmp 0x6bee
callq 0x3a30
movq %rax, %rdi
callq 0xb780
jmp 0x70cd
leaq 0x110(%rsp), %rdi
callq 0x5340
movq %rax, %rdi
addq $0x8, %rdi
callq 0xb820
movq 0x118(%rsp), %rcx
cmpl (%rcx), %eax
jb 0x6c38
leaq 0x108(%rsp), %rdi
callq 0x5340
movq %rax, %rdi
addq $0x8, %rdi
callq 0xb820
movq 0x118(%rsp), %rcx
cmpl (%rcx), %eax
jae 0x6c4a
callq 0x3a30
movq %rax, %rdi
callq 0xb780
jmp 0x70cd
movq 0x118(%rsp), %rax
movl (%rax), %eax
movl %eax, 0xfc(%rsp)
cmpl $0x0, 0xfc(%rsp)
jbe 0x6db7
leaq 0x110(%rsp), %rdi
callq 0x5340
movq %rax, %rdi
addq $0x8, %rdi
callq 0x5680
movq %rax, 0xf0(%rsp)
movq 0xf0(%rsp), %rax
movl 0x10(%rax), %eax
cmpl 0xfc(%rsp), %eax
jbe 0x6cab
movl $0x0, 0xfc(%rsp)
jmp 0x6cc6
movq 0xf0(%rsp), %rax
movl 0x10(%rax), %ecx
movl 0xfc(%rsp), %eax
subl %ecx, %eax
movl %eax, 0xfc(%rsp)
movq 0x118(%rsp), %rax
movl (%rax), %eax
movq 0xf0(%rsp), %rcx
cmpl 0x10(%rcx), %eax
jb 0x6d7c
leaq 0x110(%rsp), %rdi
callq 0x5340
movq %rax, %rdi
addq $0x8, %rdi
movq 0xf0(%rsp), %rsi
callq 0x5690
movq 0x30(%rsp), %rdi
addq $0x138, %rdi            # imm = 0x138
movq 0xf0(%rsp), %rsi
callq 0xb830
movq %rax, 0xe8(%rsp)
leaq 0xe8(%rsp), %rdi
callq 0x5480
movq 0x8(%rax), %rax
movq %rax, 0x28(%rsp)
cmpq $0x0, %rax
je 0x6d49
movq 0x28(%rsp), %rdi
callq 0x21a0
movq 0x30(%rsp), %rdi
addq $0x138, %rdi            # imm = 0x138
movq 0xe8(%rsp), %rax
movq %rax, 0xe0(%rsp)
movq 0xe0(%rsp), %rsi
callq 0x54a0
movq %rax, 0xd8(%rsp)
jmp 0x6db2
leaq 0x110(%rsp), %rdi
callq 0x5340
movq %rax, %rdi
addq $0x8, %rdi
movq 0xf0(%rsp), %rsi
movq 0xf0(%rsp), %rax
movl 0x10(%rax), %edx
movq 0x118(%rsp), %rax
subl (%rax), %edx
callq 0xb860
jmp 0x6c5b
leaq 0x110(%rsp), %rdi
callq 0x5340
movq %rax, %rdi
addq $0x8, %rdi
callq 0xb820
cmpl $0x0, %eax
jne 0x6e06
movq 0x30(%rsp), %rdi
addq $0xd8, %rdi
movq 0x110(%rsp), %rax
movq %rax, 0xd0(%rsp)
movq 0xd0(%rsp), %rsi
callq 0xb8a0
movq %rax, 0xc8(%rsp)
movq 0x118(%rsp), %rax
movl (%rax), %eax
movl %eax, 0xfc(%rsp)
cmpl $0x0, 0xfc(%rsp)
jbe 0x6f73
leaq 0x108(%rsp), %rdi
callq 0x5340
movq %rax, %rdi
addq $0x8, %rdi
callq 0x5680
movq %rax, 0xc0(%rsp)
movq 0xc0(%rsp), %rax
movl 0x10(%rax), %eax
cmpl 0xfc(%rsp), %eax
jbe 0x6e67
movl $0x0, 0xfc(%rsp)
jmp 0x6e82
movq 0xc0(%rsp), %rax
movl 0x10(%rax), %ecx
movl 0xfc(%rsp), %eax
subl %ecx, %eax
movl %eax, 0xfc(%rsp)
movq 0x118(%rsp), %rax
movl (%rax), %eax
movq 0xc0(%rsp), %rcx
cmpl 0x10(%rcx), %eax
jb 0x6f38
leaq 0x108(%rsp), %rdi
callq 0x5340
movq %rax, %rdi
addq $0x8, %rdi
movq 0xc0(%rsp), %rsi
callq 0x5690
movq 0x30(%rsp), %rdi
addq $0x138, %rdi            # imm = 0x138
movq 0xc0(%rsp), %rsi
callq 0xb830
movq %rax, 0xb8(%rsp)
leaq 0xb8(%rsp), %rdi
callq 0x5480
movq 0x8(%rax), %rax
movq %rax, 0x20(%rsp)
cmpq $0x0, %rax
je 0x6f05
movq 0x20(%rsp), %rdi
callq 0x21a0
movq 0x30(%rsp), %rdi
addq $0x138, %rdi            # imm = 0x138
movq 0xb8(%rsp), %rax
movq %rax, 0xb0(%rsp)
movq 0xb0(%rsp), %rsi
callq 0x54a0
movq %rax, 0xa8(%rsp)
jmp 0x6f6e
leaq 0x108(%rsp), %rdi
callq 0x5340
movq %rax, %rdi
addq $0x8, %rdi
movq 0xc0(%rsp), %rsi
movq 0xc0(%rsp), %rax
movl 0x10(%rax), %edx
movq 0x118(%rsp), %rax
subl (%rax), %edx
callq 0xb860
jmp 0x6e17
leaq 0x108(%rsp), %rdi
callq 0x5340
movq %rax, %rdi
addq $0x8, %rdi
callq 0xb820
cmpl $0x0, %eax
jne 0x6fc2
movq 0x30(%rsp), %rdi
addq $0x108, %rdi            # imm = 0x108
movq 0x108(%rsp), %rax
movq %rax, 0xa0(%rsp)
movq 0xa0(%rsp), %rsi
callq 0xb8a0
movq %rax, 0x98(%rsp)
movq 0x30(%rsp), %rcx
movq 0x118(%rsp), %rax
movq 0x8(%rax), %rax
cmpq 0x170(%rcx), %rax
je 0x6ffe
movq 0x30(%rsp), %rax
movq 0x118(%rsp), %rcx
movq 0x8(%rcx), %rcx
movq %rcx, 0x170(%rax)
movl $0x0, 0x178(%rax)
movq 0x30(%rsp), %rax
movq 0x118(%rsp), %rcx
movl (%rcx), %edx
movl 0x178(%rax), %ecx
addl %edx, %ecx
movl %ecx, 0x178(%rax)
movl 0x178(%rax), %edx
movq 0x170(%rax), %xmm0
movaps 0x9070(%rip), %xmm1     # 0x100a0
punpckldq %xmm1, %xmm0    # xmm0 = xmm0[0],xmm1[0],xmm0[1],xmm1[1]
movapd 0x9074(%rip), %xmm1     # 0x100b0
subpd %xmm1, %xmm0
movaps %xmm0, %xmm1
unpckhpd %xmm0, %xmm0            # xmm0 = xmm0[1,1]
addsd %xmm1, %xmm0
movsd 0x901d(%rip), %xmm1     # 0x10070
divsd %xmm1, %xmm0
leaq 0x925e(%rip), %rsi      # 0x102bc
leaq 0x70(%rsp), %rdi
movq %rdi, 0x10(%rsp)
movb $0x1, %al
callq 0x2040
movq 0x30(%rsp), %rax
movq %rax, 0x8(%rsp)
leaq 0x4f(%rsp), %rdi
movq %rdi, 0x18(%rsp)
callq 0x2310
movq 0x10(%rsp), %rsi
movq 0x18(%rsp), %rdx
leaq 0x50(%rsp), %rdi
callq 0x2250
jmp 0x709e
movq 0x8(%rsp), %rdi
leaq 0x50(%rsp), %rsi
callq 0xb8e0
jmp 0x70af
leaq 0x50(%rsp), %rdi
callq 0x2110
leaq 0x4f(%rsp), %rdi
callq 0x2200
movq 0x30(%rsp), %rdi
callq 0xb980
addq $0x128, %rsp            # imm = 0x128
retq
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x40(%rsp)
movl %eax, 0x3c(%rsp)
jmp 0x70fd
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x40(%rsp)
movl %eax, 0x3c(%rsp)
leaq 0x50(%rsp), %rdi
callq 0x2110
leaq 0x4f(%rsp), %rdi
callq 0x2200
movq 0x40(%rsp), %rdi
callq 0x2300
nopw %cs:(%rax,%rax)
nopl (%rax,%rax)