// File: obliviousram[P]PathOHeap/src/OHeapReadPathEviction.cpp
// Function: OHeapReadPathEviction::evictAndUpdateMin(int)
void OHeapReadPathEviction::evictAndUpdateMin(int leaf) {
  if (leaf != -1) {
    // pull all blocks on path into stash
    for (int l = 0; l < num_levels; l++) {
      std::vector<Block> blocks = this->storage->readBucket(this->P(leaf, l)).getBlocks();
      for (const Block& b : blocks) {
        if (b.t != -1) {
          this->stash.push_back(b);
        }
      }
    }

    // push as many stash blocks as possible into the leaf bucket
    // then push as many stash blocks as possible into the leaf's parent
    // etc.
    for (int l = num_levels-1; l >= 0; l--) {
      auto timestamps_evicted = std::vector<int>();
      Bucket bucket;
      int Pxl = P(leaf, l);
      int counter = 0;

      for (const Block& be_evicted : this->stash) {
        if (counter >= this->bucket_size) {
          break;
        }
        if (Pxl == this->P(be_evicted.leaf_id, l)) {
          bucket.addBlock(be_evicted);
          timestamps_evicted.push_back(be_evicted.t);
          counter++;
        }
      }

      // removing from the stash; careful not to modify the stash while iterating over it
      for (int i = 0; i < timestamps_evicted.size(); i++) {
        for (int j = 0; j < this->stash.size(); j++) {
          if (this->stash.at(j).t == timestamps_evicted.at(i)) {
            this->stash.erase(this->stash.begin() + j);
            break;
          }
        }
      }

      // pad out the bucket with dummy blocks
      while (counter < bucket_size) {
        bucket.addBlock(Block());
        counter++;
      }

      this->storage->writeBucket(Pxl, bucket);
    }
  } else {
    // dummy ops
    leaf = this->rand_gen->getRandomLeaf();
    auto buckets = std::vector<Bucket>();

    for (int l = 0; l < num_levels; l++) {
      buckets.push_back(this->storage->readBucket(P(leaf, l)));
    }

    for (int l = num_levels-1; l >= 0; l--) {
      this->storage->writeBucket(this->P(leaf, l), buckets.at(l));
    }
  }

  this->updateMin(leaf);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x2c0, %rsp            # imm = 0x2C0
movq %rdi, -0x8(%rbp)
movl %esi, -0xc(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x230(%rbp)
cmpl $-0x1, -0xc(%rbp)
je 0x8c09
movl $0x0, -0x10(%rbp)
movq -0x230(%rbp), %rcx
movl -0x10(%rbp), %eax
cmpl 0xc(%rcx), %eax
jge 0x880c
movq -0x230(%rbp), %rdi
movq (%rdi), %rax
movq 0x30(%rdi), %rcx
movq %rcx, -0x248(%rbp)
movl -0xc(%rbp), %esi
movl -0x10(%rbp), %edx
movq 0x30(%rax), %rax
callq *%rax
movq -0x248(%rbp), %rsi
movl %eax, %edx
movq (%rsi), %rax
movq 0x8(%rax), %rax
leaq -0x78(%rbp), %rdi
movq %rdi, -0x240(%rbp)
callq *%rax
movq -0x240(%rbp), %rdi
callq 0x2f40
movq %rax, -0x238(%rbp)
jmp 0x8704
movq -0x238(%rbp), %rsi
leaq -0x28(%rbp), %rdi
callq 0x9c10
jmp 0x8716
leaq -0x78(%rbp), %rdi
callq 0x9ae0
leaq -0x28(%rbp), %rax
movq %rax, -0x90(%rbp)
movq -0x90(%rbp), %rdi
callq 0x31f0
movq %rax, -0x98(%rbp)
movq -0x90(%rbp), %rdi
callq 0x3840
movq %rax, -0xa0(%rbp)
leaq -0x98(%rbp), %rdi
leaq -0xa0(%rbp), %rsi
callq 0x4040
testb $0x1, %al
jne 0x876c
jmp 0x87f5
leaq -0x98(%rbp), %rdi
callq 0x9ba0
movq %rax, -0xa8(%rbp)
movq -0xa8(%rbp), %rax
cmpq $-0x1, 0x8(%rax)
je 0x87e2
movq -0x230(%rbp), %rdi
addq $0x40, %rdi
movq -0xa8(%rbp), %rsi
callq 0x30b0
jmp 0x87a6
jmp 0x87e2
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x80(%rbp)
movl %eax, -0x84(%rbp)
leaq -0x78(%rbp), %rdi
callq 0x9ae0
jmp 0x8ddc
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x80(%rbp)
movl %eax, -0x84(%rbp)
leaq -0x28(%rbp), %rdi
callq 0x3020
jmp 0x8ddc
jmp 0x87e4
leaq -0x98(%rbp), %rdi
callq 0x9d00
jmp 0x8750
leaq -0x28(%rbp), %rdi
callq 0x3020
movl -0x10(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x10(%rbp)
jmp 0x869e
movq -0x230(%rbp), %rax
movl 0xc(%rax), %eax
subl $0x1, %eax
movl %eax, -0xac(%rbp)
cmpl $0x0, -0xac(%rbp)
jl 0x8c04
xorps %xmm0, %xmm0
movaps %xmm0, -0xd0(%rbp)
movq $0x0, -0xc0(%rbp)
leaq -0xd0(%rbp), %rdi
callq 0x4bf0
leaq -0x120(%rbp), %rdi
callq 0x2cf0
jmp 0x885b
movq -0x230(%rbp), %rdi
movl -0xc(%rbp), %esi
movl -0xac(%rbp), %edx
movq (%rdi), %rax
movq 0x30(%rax), %rax
callq *%rax
movl %eax, -0x24c(%rbp)
jmp 0x887c
movq -0x230(%rbp), %rax
movl -0x24c(%rbp), %ecx
movl %ecx, -0x124(%rbp)
movl $0x0, -0x128(%rbp)
addq $0x40, %rax
movq %rax, -0x130(%rbp)
movq -0x130(%rbp), %rdi
callq 0x31f0
movq %rax, -0x138(%rbp)
movq -0x130(%rbp), %rdi
callq 0x3840
movq %rax, -0x140(%rbp)
leaq -0x138(%rbp), %rdi
leaq -0x140(%rbp), %rsi
callq 0x4040
testb $0x1, %al
jne 0x88e6
jmp 0x89e3
leaq -0x138(%rbp), %rdi
callq 0x9ba0
movq -0x230(%rbp), %rcx
movq %rax, -0x148(%rbp)
movl -0x128(%rbp), %eax
cmpl 0x8(%rcx), %eax
jl 0x8944
jmp 0x89e3
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x80(%rbp)
movl %eax, -0x84(%rbp)
jmp 0x8bf3
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x80(%rbp)
movl %eax, -0x84(%rbp)
leaq -0x120(%rbp), %rdi
callq 0x9ae0
jmp 0x8bf3
movq -0x230(%rbp), %rdi
movl -0x124(%rbp), %eax
movl %eax, -0x254(%rbp)
movq -0x148(%rbp), %rax
movl (%rax), %esi
movl -0xac(%rbp), %edx
movq (%rdi), %rax
movq 0x30(%rax), %rax
callq *%rax
movl %eax, -0x250(%rbp)
jmp 0x8977
movl -0x254(%rbp), %eax
movl -0x250(%rbp), %ecx
cmpl %ecx, %eax
jne 0x89d0
movq -0x148(%rbp), %rsi
leaq -0x120(%rbp), %rdi
callq 0x2db0
jmp 0x899c
movq -0x148(%rbp), %rax
movl 0x8(%rax), %eax
movl %eax, -0x14c(%rbp)
leaq -0xd0(%rbp), %rdi
leaq -0x14c(%rbp), %rsi
callq 0x9d20
jmp 0x89c1
movl -0x128(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x128(%rbp)
jmp 0x89d2
leaq -0x138(%rbp), %rdi
callq 0x9d00
jmp 0x88ca
movl $0x0, -0x150(%rbp)
movslq -0x150(%rbp), %rax
movq %rax, -0x260(%rbp)
leaq -0xd0(%rbp), %rdi
callq 0x53a0
movq %rax, %rcx
movq -0x260(%rbp), %rax
cmpq %rcx, %rax
jae 0x8b5c
movl $0x0, -0x154(%rbp)
movq -0x230(%rbp), %rdi
movslq -0x154(%rbp), %rax
movq %rax, -0x268(%rbp)
addq $0x40, %rdi
callq 0x3080
movq %rax, %rcx
movq -0x268(%rbp), %rax
cmpq %rcx, %rax
jae 0x8b46
movq -0x230(%rbp), %rdi
addq $0x40, %rdi
movslq -0x154(%rbp), %rsi
callq 0x3120
movq %rax, -0x270(%rbp)
jmp 0x8a75
movq -0x270(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x280(%rbp)
movslq -0x150(%rbp), %rsi
leaq -0xd0(%rbp), %rdi
callq 0x4c80
movq %rax, -0x278(%rbp)
jmp 0x8aa3
movq -0x280(%rbp), %rax
movq -0x278(%rbp), %rcx
movslq (%rcx), %rcx
cmpq %rcx, %rax
jne 0x8b30
movq -0x230(%rbp), %rdi
addq $0x40, %rdi
movq %rdi, -0x290(%rbp)
callq 0x31f0
movq %rax, -0x170(%rbp)
movslq -0x154(%rbp), %rsi
leaq -0x170(%rbp), %rdi
callq 0x3220
movq %rax, -0x168(%rbp)
leaq -0x160(%rbp), %rdi
leaq -0x168(%rbp), %rsi
callq 0x3260
movq -0x290(%rbp), %rdi
movq -0x160(%rbp), %rsi
callq 0x3180
movq %rax, -0x288(%rbp)
jmp 0x8b20
movq -0x288(%rbp), %rax
movq %rax, -0x178(%rbp)
jmp 0x8b46
jmp 0x8b32
movl -0x154(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x154(%rbp)
jmp 0x8a24
jmp 0x8b48
movl -0x150(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x150(%rbp)
jmp 0x89ed
jmp 0x8b5e
movq -0x230(%rbp), %rcx
movl -0x128(%rbp), %eax
cmpl 0x8(%rcx), %eax
jge 0x8ba4
leaq -0x1b0(%rbp), %rdi
callq 0x26b0
jmp 0x8b7e
leaq -0x120(%rbp), %rdi
leaq -0x1b0(%rbp), %rsi
callq 0x2db0
jmp 0x8b93
movl -0x128(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x128(%rbp)
jmp 0x8b5e
movq -0x230(%rbp), %rax
movq 0x30(%rax), %rdi
movl -0x124(%rbp), %esi
movq (%rdi), %rax
movq 0x10(%rax), %rax
leaq -0x120(%rbp), %rdx
callq *%rax
jmp 0x8bc7
leaq -0x120(%rbp), %rdi
callq 0x9ae0
leaq -0xd0(%rbp), %rdi
callq 0x4cc0
movl -0xac(%rbp), %eax
addl $-0x1, %eax
movl %eax, -0xac(%rbp)
jmp 0x881f
leaq -0xd0(%rbp), %rdi
callq 0x4cc0
jmp 0x8ddc
jmp 0x8dc4
movq -0x230(%rbp), %rax
movq 0x38(%rax), %rdi
movq (%rdi), %rax
callq *(%rax)
movl %eax, -0xc(%rbp)
leaq -0x1c8(%rbp), %rdi
xorl %esi, %esi
movl $0x18, %edx
callq 0x20f0
leaq -0x1c8(%rbp), %rdi
callq 0x9d50
movl $0x0, -0x1cc(%rbp)
movq -0x230(%rbp), %rcx
movl -0x1cc(%rbp), %eax
cmpl 0xc(%rcx), %eax
jge 0x8d0f
movq -0x230(%rbp), %rdi
movq (%rdi), %rax
movq 0x30(%rdi), %rcx
movq %rcx, -0x2a0(%rbp)
movl -0xc(%rbp), %esi
movl -0x1cc(%rbp), %edx
movq 0x30(%rax), %rax
callq *%rax
movl %eax, -0x294(%rbp)
jmp 0x8c87
movl -0x294(%rbp), %edx
movq -0x2a0(%rbp), %rsi
movq (%rsi), %rax
movq 0x8(%rax), %rax
leaq -0x220(%rbp), %rdi
callq *%rax
jmp 0x8ca6
leaq -0x1c8(%rbp), %rdi
leaq -0x220(%rbp), %rsi
callq 0x9d70
jmp 0x8cbb
leaq -0x220(%rbp), %rdi
callq 0x9ae0
movl -0x1cc(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x1cc(%rbp)
jmp 0x8c45
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x80(%rbp)
movl %eax, -0x84(%rbp)
jmp 0x8db6
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x80(%rbp)
movl %eax, -0x84(%rbp)
leaq -0x220(%rbp), %rdi
callq 0x9ae0
jmp 0x8db6
movq -0x230(%rbp), %rax
movl 0xc(%rax), %eax
subl $0x1, %eax
movl %eax, -0x224(%rbp)
cmpl $0x0, -0x224(%rbp)
jl 0x8da8
movq -0x230(%rbp), %rdi
movq (%rdi), %rax
movq 0x30(%rdi), %rcx
movq %rcx, -0x2b0(%rbp)
movl -0xc(%rbp), %esi
movl -0x224(%rbp), %edx
movq 0x30(%rax), %rax
callq *%rax
movl %eax, -0x2a4(%rbp)
jmp 0x8d57
movslq -0x224(%rbp), %rsi
leaq -0x1c8(%rbp), %rdi
callq 0x9da0
movq %rax, -0x2b8(%rbp)
jmp 0x8d73
movq -0x2b8(%rbp), %rdx
movl -0x2a4(%rbp), %esi
movq -0x2b0(%rbp), %rdi
movq (%rdi), %rax
movq 0x10(%rax), %rax
callq *%rax
jmp 0x8d92
jmp 0x8d94
movl -0x224(%rbp), %eax
addl $-0x1, %eax
movl %eax, -0x224(%rbp)
jmp 0x8d22
leaq -0x1c8(%rbp), %rdi
callq 0x9de0
jmp 0x8dc4
leaq -0x1c8(%rbp), %rdi
callq 0x9de0
jmp 0x8ddc
movq -0x230(%rbp), %rdi
movl -0xc(%rbp), %esi
callq 0x9090
addq $0x2c0, %rsp            # imm = 0x2C0
popq %rbp
retq
movq -0x80(%rbp), %rdi
callq 0x22a0
nopw %cs:(%rax,%rax)