// File: /workspace/github_cpp_makefile_star2_O1/obliviousram[P]PathOHeap/src/PlainHeapComparisonTest.cpp
// Function: PlainHeapComparisonTest::run()
void PlainHeapComparisonTest::run() {
  int bucket_size = 3;
  int num_blocks = pow(2, 20);
  this->max_heap_size = num_blocks;
  UntrustedStorageInterface* storage = new ServerStorage();
  RandForOHeapInterface* random = new RandomForOHeap();
  OHeapInterface* oheap = new OHeapReadPathEviction(storage, random, bucket_size, num_blocks, false);

  // Test: compare the OHeap to a 'plain' heap by performing several million random operations on
  // both, making sure that the results match.

  // Since C++ heaps use "pop max" while this OHeap implementation uses "pop min", negate all items
  // in the plain heap.

  const int num_ops = 10000000;
  const int frequency = 10000;

  for (int i = 1; i <= num_ops; i++) {
    std::pair<Operation, int> op_v = this->randomOp();
    Operation op = op_v.first;
    int v = op_v.second;

    if (op == PUSH) {
      this->plain_heap.push_back(-v);
      std::push_heap(this->plain_heap.begin(), this->plain_heap.end());
      
      oheap->insertBlock(v, this->sampleData(v));
    } else if (op == POP) {
      std::pop_heap(this->plain_heap.begin(), this->plain_heap.end());
      int plain_v = -this->plain_heap.back();
      this->plain_heap.pop_back();

      int oheap_v = oheap->extractMin().k;

      if (plain_v != oheap_v) {
        std::cout << "Error! " << plain_v << " and " << oheap_v << " don't match!" << std::endl;
      }
    }

    if (i % frequency == 0) {
      std::cout << "Performed " << i << " operations; current heap size is " << this->plain_heap.size() << std::endl;
    }
  }

  delete oheap;
  delete random;
  delete storage;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x88, %rsp
movq %rdi, %r14
movl $0x100000, 0x18(%rdi)   # imm = 0x100000
movl $0x28, %edi
callq 0x2160
movq %rax, %r15
movq %rax, %rdi
callq 0x6178
movl $0x20, %edi
callq 0x2160
movq %rax, %r13
movq %rax, %rdi
callq 0x6000
movl $0x58, %edi
callq 0x2160
movq %rax, %r12
movq %rax, %rdi
movq %r15, 0x48(%rsp)
movq %r15, %rsi
movq %r13, 0x40(%rsp)
movq %r13, %rdx
movl $0x3, %ecx
movl $0x100000, %r8d         # imm = 0x100000
xorl %r9d, %r9d
callq 0x3c98
movl $0x1, %ebp
movq 0x5346(%rip), %rbx      # 0xafd0
movq %r14, %rdi
callq 0x5b90
movq %rax, %r15
cmpl $0x1, %r15d
je 0x5cd1
testl %r15d, %r15d
jne 0x5e57
movq %r15, %r13
shrq $0x20, %r13
movl %r13d, %eax
negl %eax
movl %eax, 0x50(%rsp)
movq 0x8(%r14), %rsi
cmpq 0x10(%r14), %rsi
je 0x5db2
movl %eax, (%rsi)
addq $0x4, %rsi
movq %rsi, 0x8(%r14)
jmp 0x5dbf
movq (%r14), %rdi
movq 0x8(%r14), %rax
movq %rax, %rcx
subq %rdi, %rcx
cmpq $0x5, %rcx
jl 0x5cfe
leaq -0x4(%rax), %rdx
movl -0x4(%rax), %ecx
movl (%rdi), %esi
movl %esi, -0x4(%rax)
subq %rdi, %rdx
sarq $0x2, %rdx
xorl %esi, %esi
callq 0x5f56
movq 0x8(%r14), %rax
xorl %r13d, %r13d
subl -0x4(%rax), %r13d
addq $-0x4, %rax
movq %rax, 0x8(%r14)
movq (%r12), %rax
leaq 0x50(%rsp), %rdi
movq %r12, %rsi
callq *0x18(%rax)
movl 0x60(%rsp), %r15d
cmpl %r13d, %r15d
je 0x5e57
movl $0x7, %edx
movq %rbx, %rdi
leaq 0x154a(%rip), %rsi      # 0x7287
callq 0x2190
movq %rbx, %rdi
movl %r13d, %esi
callq 0x2240
movq %rax, %r13
movl $0x5, %edx
movq %rax, %rdi
leaq 0x1530(%rip), %rsi      # 0x728f
callq 0x2190
movq %r13, %rdi
movl %r15d, %esi
callq 0x2240
movq %rax, %r15
movl $0xd, %edx
movq %rax, %rdi
leaq 0x1514(%rip), %rsi      # 0x7295
callq 0x2190
movq (%r15), %rax
movq -0x18(%rax), %rdi
addq %r15, %rdi
movl $0xa, %esi
callq 0x2150
movsbl %al, %esi
movq %r15, %rdi
callq 0x2030
movq %rax, %rdi
callq 0x2100
jmp 0x5e57
movq %r14, %rdi
leaq 0x50(%rsp), %rdx
callq 0x5674
movq (%r14), %rax
movq 0x8(%r14), %rsi
movl -0x4(%rsi), %ecx
subq %rax, %rsi
sarq $0x2, %rsi
leaq -0x1(%rsi), %rdx
cmpq $0x2, %rsi
jl 0x5e00
leaq -0x1(%rdx), %rsi
shrq $0x3f, %rsi
addq %rdx, %rsi
decq %rsi
sarq %rsi
movl (%rax,%rsi,4), %edi
cmpl %ecx, %edi
jge 0x5e00
movl %edi, (%rax,%rdx,4)
cmpq $0x2, %rdx
movq %rsi, %rdx
jg 0x5dda
jmp 0x5e03
movq %rdx, %rsi
movl %ecx, (%rax,%rsi,4)
xorps %xmm0, %xmm0
movaps %xmm0, 0x20(%rsp)
movaps %xmm0, 0x30(%rsp)
movq %r15, %rax
shrq $0x38, %rax
movb %al, 0x20(%rsp)
movq %r15, %rax
shrq $0x30, %rax
movb %al, 0x21(%rsp)
shrq $0x28, %r15
movb %r15b, 0x22(%rsp)
movb %r13b, 0x23(%rsp)
movq (%r12), %rax
movaps 0x20(%rsp), %xmm0
movaps 0x30(%rsp), %xmm1
movups %xmm1, 0x10(%rsp)
movups %xmm0, (%rsp)
movq %r12, %rdi
movl %r13d, %esi
callq *0x8(%rax)
imull $0x3afb7e91, %ebp, %eax # imm = 0x3AFB7E91
rorl $0x4, %eax
cmpl $0x68db8, %eax          # imm = 0x68DB8
ja 0x5ed9
movl $0xa, %edx
movq %rbx, %rdi
leaq 0x142d(%rip), %rsi      # 0x72a3
callq 0x2190
movq %rbx, %rdi
movl %ebp, %esi
callq 0x2240
movq %rax, %r15
movl $0x22, %edx
movq %rax, %rdi
leaq 0x1417(%rip), %rsi      # 0x72ae
callq 0x2190
movq 0x8(%r14), %rsi
subq (%r14), %rsi
sarq $0x2, %rsi
movq %r15, %rdi
callq 0x20f0
movq %rax, %r15
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %r15, %rdi
movl $0xa, %esi
callq 0x2150
movsbl %al, %esi
movq %r15, %rdi
callq 0x2030
movq %rax, %rdi
callq 0x2100
incl %ebp
cmpl $0x989681, %ebp         # imm = 0x989681
jne 0x5c8a
movl $0x8, %esi
movq %r12, %rdi
callq 0x2170
movl $0x8, %esi
movq 0x40(%rsp), %rdi
callq 0x2170
movl $0x8, %esi
movq 0x48(%rsp), %rdi
callq 0x2170
addq $0x88, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %rax, %rbx
movl $0x58, %esi
movq %r12, %rdi
jmp 0x5f49
movq %rax, %rbx
movl $0x20, %esi
movq %r13, %rdi
jmp 0x5f49
movq %rax, %rbx
movl $0x28, %esi
movq %r15, %rdi
callq 0x2170
movq %rbx, %rdi
callq 0x2250