// File: /workspace/github_cpp_makefile_star2_O2/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
pushq $0x28
popq %rdi
callq 0x2150
movq %rax, %r15
movq %rax, %rdi
callq 0x5990
pushq $0x20
popq %rdi
callq 0x2150
movq %rax, %rbx
movq %rax, %rdi
callq 0x583c
pushq $0x58
popq %rdi
callq 0x2150
movq %rax, %r12
pushq $0x3
popq %rcx
movq %rax, %rdi
movq %r15, 0x28(%rsp)
movq %r15, %rsi
movq %rbx, 0x20(%rsp)
movq %rbx, %rdx
movl $0x100000, %r8d         # imm = 0x100000
xorl %r9d, %r9d
callq 0x396c
pushq $0x1
popq %rbx
movl %ebx, %eax
xorl %edx, %edx
movl $0x2710, %ecx           # imm = 0x2710
divl %ecx
cmpl $0x989681, %ebx         # imm = 0x989681
je 0x56d4
movl %eax, %r15d
movq %r14, %rdi
callq 0x5478
movq %rax, %r13
cmpl $0x1, %r13d
je 0x55ee
testl %r13d, %r13d
jne 0x5673
movq %r13, %rbp
shrq $0x20, %rbp
movl %ebp, %eax
negl %eax
movl %eax, 0x50(%rsp)
movq %r14, %rdi
leaq 0x50(%rsp), %rsi
callq 0x4e84
movq (%r14), %rdi
movq 0x8(%r14), %rsi
callq 0x573a
leaq 0x34(%rsp), %rax
xorps %xmm0, %xmm0
movups %xmm0, 0xc(%rax)
movups %xmm0, (%rax)
movq %r13, %rax
shrq $0x38, %rax
movb %al, 0x30(%rsp)
movq %r13, %rax
shrq $0x30, %rax
movb %al, 0x31(%rsp)
shrq $0x28, %r13
movb %r13b, 0x32(%rsp)
movb %bpl, 0x33(%rsp)
movq (%r12), %rax
movups 0x30(%rsp), %xmm0
movups 0x40(%rsp), %xmm1
movups %xmm1, 0x10(%rsp)
movups %xmm0, (%rsp)
movq %r12, %rdi
movl %ebp, %esi
callq *0x8(%rax)
jmp 0x5673
movq (%r14), %rdi
movq 0x8(%r14), %rsi
callq 0x5756
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), %ebp
cmpl %r13d, %ebp
je 0x5673
movq 0x59a4(%rip), %rdi      # 0xafd0
leaq 0x1c54(%rip), %rsi      # 0x7287
callq 0x2140
movq %rax, %rdi
movl %r13d, %esi
callq 0x2230
movq %rax, %rdi
leaq 0x1c42(%rip), %rsi      # 0x728f
callq 0x2140
movq %rax, %rdi
movl %ebp, %esi
callq 0x2230
movq %rax, %rdi
leaq 0x1c2f(%rip), %rsi      # 0x7295
callq 0x2140
movq %rax, %rdi
callq 0x20b0
imull $0x2710, %r15d, %eax    # imm = 0x2710
pushq $0x1
popq %rcx
subl %eax, %ecx
addl %ebx, %ecx
cmpl $0x1, %ecx
jne 0x56cd
movq 0x5943(%rip), %rdi      # 0xafd0
leaq 0x1c0f(%rip), %rsi      # 0x72a3
callq 0x2140
movq %rax, %rdi
movl %ebx, %esi
callq 0x2230
movq %rax, %rdi
leaq 0x1c01(%rip), %rsi      # 0x72ae
callq 0x2140
movq 0x8(%r14), %rsi
subq (%r14), %rsi
sarq $0x2, %rsi
movq %rax, %rdi
callq 0x20f0
movq %rax, %rdi
callq 0x20b0
incl %ebx
jmp 0x5537
pushq $0x8
popq %rbx
movq %r12, %rdi
movq %rbx, %rsi
callq 0x2160
movq 0x20(%rsp), %rdi
movq %rbx, %rsi
callq 0x2160
movq 0x28(%rsp), %rdi
movq %rbx, %rsi
callq 0x2160
addq $0x88, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %rax, %rbx
pushq $0x58
popq %rsi
movq %r12, %rdi
jmp 0x572d
movq %rbx, %rdi
movq %rax, %rbx
pushq $0x20
popq %rsi
jmp 0x572d
movq %rax, %rbx
pushq $0x28
popq %rsi
movq %r15, %rdi
callq 0x2160
movq %rbx, %rdi
callq 0x2240