// File: /workspace/github_cpp_makefile_star2_O3/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 0x5ff4
movl $0x20, %edi
callq 0x2160
movq %rax, %r13
movq %rax, %rdi
callq 0x5e7c
movl $0x58, %edi
callq 0x2160
movq %rax, %r12
movq %rax, %rdi
movq %r15, 0x28(%rsp)
movq %r15, %rsi
movq %r13, 0x20(%rsp)
movq %r13, %rdx
movl $0x3, %ecx
movl $0x100000, %r8d         # imm = 0x100000
xorl %r9d, %r9d
callq 0x3be8
movl $0x1, %ebp
movq 0x54c4(%rip), %rbx      # 0xafd0
movq %r14, %rdi
callq 0x5a12
movq %rax, %r15
cmpl $0x1, %r15d
je 0x5b53
testl %r15d, %r15d
jne 0x5cd4
movq %r15, %r13
shrq $0x20, %r13
movl %r13d, %eax
negl %eax
movl %eax, 0x50(%rsp)
movq 0x8(%r14), %rsi
cmpq 0x10(%r14), %rsi
je 0x5c34
movl %eax, (%rsi)
addq $0x4, %rsi
movq %rsi, 0x8(%r14)
jmp 0x5c45
movq (%r14), %rdi
movq 0x8(%r14), %rax
movq %rax, %rcx
subq %rdi, %rcx
cmpq $0x5, %rcx
jl 0x5b84
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 0x5dd3
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 0x5cd4
movl $0x7, %edx
movq %rbx, %rdi
leaq 0x16c8(%rip), %rsi      # 0x7287
callq 0x2190
movq %rbx, %rdi
movl %r13d, %esi
callq 0x2240
movq %rax, %r13
movl $0x5, %edx
movq %rax, %rdi
leaq 0x16ae(%rip), %rsi      # 0x728f
callq 0x2190
movq %r13, %rdi
movl %r15d, %esi
callq 0x2240
movq %rax, %r15
movl $0xd, %edx
movq %rax, %rdi
leaq 0x1692(%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 0x5cd4
movq %r14, %rdi
leaq 0x50(%rsp), %rdx
callq 0x5508
movq 0x8(%r14), %rsi
movq (%r14), %rax
movl -0x4(%rsi), %ecx
subq %rax, %rsi
sarq $0x2, %rsi
leaq -0x1(%rsi), %rdx
cmpq $0x2, %rsi
jl 0x5c7e
leaq -0x1(%rdx), %rsi
movq %rsi, %rdi
shrq %rdi
movl (%rax,%rdi,4), %r8d
cmpl %ecx, %r8d
jge 0x5c7e
movl %r8d, (%rax,%rdx,4)
movq %rdi, %rdx
cmpq $0x1, %rsi
ja 0x5c5c
xorl %edx, %edx
movl %ecx, (%rax,%rdx,4)
leaq 0x34(%rsp), %rax
xorps %xmm0, %xmm0
movups %xmm0, 0xc(%rax)
movups %xmm0, (%rax)
movq %r15, %rax
shrq $0x38, %rax
movb %al, 0x30(%rsp)
movq %r15, %rax
shrq $0x30, %rax
movb %al, 0x31(%rsp)
shrq $0x28, %r15
movb %r15b, 0x32(%rsp)
movb %r13b, 0x33(%rsp)
movq (%r12), %rax
movups 0x30(%rsp), %xmm0
movups 0x40(%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 0x5d56
movl $0xa, %edx
movq %rbx, %rdi
leaq 0x15b0(%rip), %rsi      # 0x72a3
callq 0x2190
movq %rbx, %rdi
movl %ebp, %esi
callq 0x2240
movq %rax, %r15
movl $0x22, %edx
movq %rax, %rdi
leaq 0x159a(%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 0x5b0c
movl $0x8, %esi
movq %r12, %rdi
callq 0x2170
movl $0x8, %esi
movq 0x20(%rsp), %rdi
callq 0x2170
movl $0x8, %esi
movq 0x28(%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 0x5dc6
movq %rax, %rbx
movl $0x20, %esi
movq %r13, %rdi
jmp 0x5dc6
movq %rax, %rbx
movl $0x28, %esi
movq %r15, %rdi
callq 0x2170
movq %rbx, %rdi
callq 0x2250