// File: /workspace/github_cpp_makefile_star2_O3/attractivechaos[P]udb2/libcuckoo/./cuckoohash_map.hh
// Function: bool cuckoohash_map<unsigned int, unsigned int, Hash32, std::equal_to<unsigned int>, std::allocator<std::pair<unsigned int const, unsigned int>>, 4ul>::cuckoopath_move<std::integral_constant<bool, false>>(unsigned long, std::array<cuckoohash_map<unsigned int, unsigned int, Hash32, std::equal_to<unsigned int>, std::allocator<std::pair<unsigned int const, unsigned int>>, 4ul>::CuckooRecord, 5ul>&, unsigned long, cuckoohash_map<unsigned int, unsigned int, Hash32, std::equal_to<unsigned int>, std::allocator<std::pair<unsigned int const, unsigned int>>, 4ul>::TwoBuckets&)
bool cuckoopath_move(const size_type hp, CuckooRecords &cuckoo_path,
                       size_type depth, TwoBuckets &b) {
    if (depth == 0) {
      // There is a chance that depth == 0, when try_add_to_bucket sees
      // both buckets as full and cuckoopath_search finds one empty. In
      // this case, we lock both buckets. If the slot that
      // cuckoopath_search found empty isn't empty anymore, we unlock them
      // and return false. Otherwise, the bucket is empty and insertable,
      // so we hold the locks and return true.
      const size_type bucket = cuckoo_path[0].bucket;
      assert(bucket == b.i1 || bucket == b.i2);
      b = lock_two(hp, b.i1, b.i2, TABLE_MODE());
      if (!buckets_[bucket].occupied(cuckoo_path[0].slot)) {
        return true;
      } else {
        b.unlock();
        return false;
      }
    }

    while (depth > 0) {
      CuckooRecord &from = cuckoo_path[depth - 1];
      CuckooRecord &to = cuckoo_path[depth];
      const size_type fs = from.slot;
      const size_type ts = to.slot;
      TwoBuckets twob;
      LockManager extra_manager;
      if (depth == 1) {
        // Even though we are only swapping out of one of the original
        // buckets, we have to lock both of them along with the slot we
        // are swapping to, since at the end of this function, they both
        // must be locked. We store tb inside the extrab container so it
        // is unlocked at the end of the loop.
        std::tie(twob, extra_manager) =
            lock_three(hp, b.i1, b.i2, to.bucket, TABLE_MODE());
      } else {
        twob = lock_two(hp, from.bucket, to.bucket, TABLE_MODE());
      }

      bucket &fb = buckets_[from.bucket];
      bucket &tb = buckets_[to.bucket];

      // We plan to kick out fs, but let's check if it is still there;
      // there's a small chance we've gotten scooped by a later cuckoo. If
      // that happened, just... try again. Also the slot we are filling in
      // may have already been filled in by another thread, or the slot we
      // are moving from may be empty, both of which invalidate the swap.
      // We only need to check that the hash value is the same, because,
      // even if the keys are different and have the same hash value, then
      // the cuckoopath is still valid.
      if (tb.occupied(ts) || !fb.occupied(fs) ||
          hashed_key_only_hash(fb.key(fs)) != from.hv.hash) {
        return false;
      }

      buckets_.setKV(to.bucket, ts, fb.partial(fs), fb.movable_key(fs),
                     std::move(fb.mapped(fs)));
      buckets_.eraseKV(from.bucket, fs);
      if (depth == 1) {
        // Hold onto the locks contained in twob
        b = std::move(twob);
      }
      depth--;
    }
    return true;
  }

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x68, %rsp
movq %r8, %r14
movq %rdx, %r12
movq %rsi, 0x10(%rsp)
movq %rdi, %rsi
testq %rcx, %rcx
je 0x3ab4
movq %rcx, %r13
movq %r14, 0x18(%rsp)
movq %r12, 0x8(%rsp)
testq %r13, %r13
sete %al
movb %al, 0x7(%rsp)
je 0x3b97
leaq -0x1(%r13), %rax
movq %rax, 0x48(%rsp)
shlq $0x5, %rax
leaq (%r12,%rax), %r14
movq %r13, %rcx
shlq $0x5, %rcx
leaq (%r12,%rcx), %r15
movq 0x8(%r12,%rax), %rbx
movq 0x8(%r12,%rcx), %rbp
cmpq $0x1, %r13
jne 0x398a
movq 0x18(%rsp), %rax
movq (%rax), %rcx
movq 0x8(%rax), %r8
movq (%r15), %r9
leaq 0x20(%rsp), %rdi
movq 0x10(%rsp), %rdx
movq %rsi, %r12
callq 0x3e62
movups 0x20(%rsp), %xmm0
movaps %xmm0, 0x50(%rsp)
movq 0x30(%rsp), %rcx
movq 0x38(%rsp), %rdx
movq 0x40(%rsp), %rax
jmp 0x39b8
movq (%r14), %rcx
movq (%r15), %r8
leaq 0x20(%rsp), %rdi
movq 0x10(%rsp), %rdx
movq %rsi, %r12
callq 0x2f46
movups 0x20(%rsp), %xmm0
movaps %xmm0, 0x50(%rsp)
movq 0x30(%rsp), %rcx
movq 0x38(%rsp), %rdx
xorl %eax, %eax
movq 0x18(%r12), %rdi
movq (%r15), %rsi
leaq (%rsi,%rsi,4), %rsi
leaq (%rdi,%rsi,8), %r9
cmpb $0x0, 0x24(%rbp,%r9)
movq %r12, %rsi
jne 0x3a7f
movq (%r14), %r8
leaq (%r8,%r8,4), %r8
leaq (%rdi,%r8,8), %rdi
cmpb $0x1, 0x24(%rdi,%rbx)
jne 0x3a7f
movl (%rdi,%rbx,8), %r8d
cmpq %r8, 0x10(%r14)
jne 0x3a7f
movb 0x20(%rdi,%rbx), %r8b
movb %r8b, 0x20(%r9,%rbp)
movq (%rdi,%rbx,8), %rdi
movq %rdi, (%r9,%rbp,8)
movb $0x1, 0x24(%r9,%rbp)
movq (%r14), %rdi
movq 0x18(%rsi), %r9
leaq (%rdi,%rdi,4), %rdi
leaq (%r9,%rdi,8), %r8
cmpb $0x0, 0x24(%rbx,%r8)
je 0x3baa
leaq (%r9,%rdi,8), %rdi
addq $0x24, %rdi
movb $0x0, (%rdi,%rbx)
movb $0x1, %r9b
cmpq $0x1, %r13
movq 0x8(%rsp), %r12
jne 0x3aad
movaps 0x50(%rsp), %xmm0
movq 0x18(%rsp), %r8
movups %xmm0, (%r8)
movq 0x10(%r8), %rdi
movq %rcx, 0x10(%r8)
testq %rdi, %rdi
je 0x3a66
movb $0x0, (%rdi)
movq 0x18(%r8), %rcx
movq %rdx, 0x18(%r8)
testq %rcx, %rcx
je 0x3a76
movb $0x0, (%rcx)
xorl %ecx, %ecx
xorl %edx, %edx
xorl %r13d, %r13d
jmp 0x3a87
xorl %r9d, %r9d
movq 0x8(%rsp), %r12
testq %rax, %rax
je 0x3a8f
movb $0x0, (%rax)
testq %rdx, %rdx
je 0x3a97
movb $0x0, (%rdx)
testq %rcx, %rcx
je 0x3a9f
movb $0x0, (%rcx)
testb %r9b, %r9b
jne 0x3912
jmp 0x3b97
movq 0x48(%rsp), %r13
jmp 0x3a87
movq (%r12), %rbx
movq (%r14), %rcx
movq 0x8(%r14), %r8
cmpq %rcx, %rbx
sete %al
cmpq %r8, %rbx
sete %dl
orb %al, %dl
je 0x3bc9
leaq 0x20(%rsp), %r13
movq %r13, %rdi
movq %rsi, %r15
movq 0x10(%rsp), %rdx
callq 0x2f46
movups (%r13), %xmm0
movups %xmm0, (%r14)
movq 0x10(%r13), %rcx
movq $0x0, 0x10(%r13)
movq 0x10(%r14), %rax
movq %rcx, 0x10(%r14)
testq %rax, %rax
je 0x3b0d
movb $0x0, (%rax)
movq 0x38(%rsp), %rcx
movq $0x0, 0x38(%rsp)
movq 0x18(%r14), %rax
movq %rcx, 0x18(%r14)
testq %rax, %rax
je 0x3b38
movb $0x0, (%rax)
movq 0x38(%rsp), %rax
testq %rax, %rax
je 0x3b38
movb $0x0, (%rax)
movq $0x0, 0x38(%rsp)
movq 0x30(%rsp), %rax
testq %rax, %rax
je 0x3b4e
movb $0x0, (%rax)
movq 0x8(%r12), %rax
leaq (%rbx,%rbx,4), %rcx
shlq $0x3, %rcx
addq 0x18(%r15), %rcx
movb 0x24(%rax,%rcx), %cl
cmpb $0x1, %cl
jne 0x3b90
movq 0x10(%r14), %rax
movq $0x0, 0x10(%r14)
testq %rax, %rax
je 0x3b7c
movb $0x0, (%rax)
movq 0x18(%r14), %rax
movq $0x0, 0x18(%r14)
testq %rax, %rax
je 0x3b90
movb $0x0, (%rax)
xorb $0x1, %cl
movb %cl, 0x7(%rsp)
movb 0x7(%rsp), %al
addq $0x68, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x2459(%rip), %rdi      # 0x600a
leaq 0x151f(%rip), %rsi      # 0x50d7
leaq 0x1538(%rip), %rcx      # 0x50f7
movl $0xd6, %edx
callq 0x20f0
leaq 0x22a6(%rip), %rdi      # 0x5e76
leaq 0x16a7(%rip), %rsi      # 0x527e
leaq 0x22b9(%rip), %rcx      # 0x5e97
movl $0x55a, %edx            # imm = 0x55A
callq 0x20f0