// File: /workspace/github_cpp_makefile_star2_O1/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, %rbp
movq %rsi, 0x18(%rsp)
movq %rdi, %rsi
testq %rcx, %rcx
je 0x3ae1
movq %rcx, %r13
movq %r14, 0x20(%rsp)
movq %rbp, 0x8(%rsp)
testq %r13, %r13
sete %al
movb %al, 0x7(%rsp)
je 0x3bc3
leaq -0x1(%r13), %rax
movq %rax, 0x10(%rsp)
shlq $0x5, %rax
leaq (%rax,%rbp), %r14
movq %r13, %rcx
shlq $0x5, %rcx
leaq (%rcx,%rbp), %r12
movq 0x8(%rbp,%rax), %rbx
movq 0x8(%rbp,%rcx), %rbp
cmpq $0x1, %r13
jne 0x39bb
movq 0x20(%rsp), %rax
movq (%rax), %rcx
movq 0x8(%rax), %r8
movq (%r12), %r9
leaq 0x28(%rsp), %rdi
movq 0x18(%rsp), %rdx
movq %rsi, %r15
callq 0x3f36
movups 0x28(%rsp), %xmm0
movaps %xmm0, 0x50(%rsp)
movq 0x38(%rsp), %rax
movq 0x40(%rsp), %rdx
movq 0x48(%rsp), %rcx
jmp 0x39ea
movq (%r14), %rcx
movq (%r12), %r8
leaq 0x28(%rsp), %rdi
movq 0x18(%rsp), %rdx
movq %rsi, %r15
callq 0x2f2c
movups 0x28(%rsp), %xmm0
movaps %xmm0, 0x50(%rsp)
movq 0x38(%rsp), %rax
movq 0x40(%rsp), %rdx
xorl %ecx, %ecx
movq 0x18(%r15), %rdi
movq (%r12), %rsi
leaq (%rsi,%rsi,4), %rsi
leaq (%rdi,%rsi,8), %r9
cmpb $0x0, 0x24(%rbp,%r9)
movq %r15, %rsi
jne 0x3ab3
movq (%r14), %r8
leaq (%r8,%r8,4), %r8
leaq (%rdi,%r8,8), %rdi
cmpb $0x1, 0x24(%rdi,%rbx)
jne 0x3ab3
movl (%rdi,%rbx,8), %r8d
cmpq %r8, 0x10(%r14)
jne 0x3ab3
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 0x3bd6
leaq (%r9,%rdi,8), %rdi
addq $0x24, %rdi
movb $0x0, (%rdi,%rbx)
movb $0x1, %r9b
cmpq $0x1, %r13
movq 0x8(%rsp), %rbp
jne 0x3aac
movaps 0x50(%rsp), %xmm0
movq 0x20(%rsp), %r8
movups %xmm0, (%r8)
movq 0x10(%r8), %rdi
movq %rax, 0x10(%r8)
testq %rdi, %rdi
je 0x3a98
movb $0x0, (%rdi)
movq 0x18(%r8), %rax
movq %rdx, 0x18(%r8)
testq %rax, %rax
je 0x3aa8
movb $0x0, (%rax)
xorl %eax, %eax
xorl %edx, %edx
movq 0x10(%rsp), %r13
jmp 0x3abb
xorl %r9d, %r9d
movq 0x8(%rsp), %rbp
testq %rcx, %rcx
je 0x3ac3
movb $0x0, (%rcx)
testq %rdx, %rdx
je 0x3acb
movb $0x0, (%rdx)
testq %rax, %rax
je 0x3ad3
movb $0x0, (%rax)
testb %r9b, %r9b
jne 0x3942
jmp 0x3bc3
movq (%rbp), %rbx
movq (%r14), %rcx
movq 0x8(%r14), %r8
cmpq %rcx, %rbx
sete %al
cmpq %r8, %rbx
sete %dl
orb %al, %dl
je 0x3bf5
leaq 0x28(%rsp), %r13
movq %r13, %rdi
movq %rsi, %r15
movq 0x18(%rsp), %rdx
callq 0x2f2c
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 0x3b3a
movb $0x0, (%rax)
movq 0x40(%rsp), %rcx
movq $0x0, 0x40(%rsp)
movq 0x18(%r14), %rax
movq %rcx, 0x18(%r14)
testq %rax, %rax
je 0x3b58
movb $0x0, (%rax)
movq 0x40(%rsp), %rax
testq %rax, %rax
je 0x3b65
movb $0x0, (%rax)
movq $0x0, 0x40(%rsp)
movq 0x38(%rsp), %rax
testq %rax, %rax
je 0x3b7b
movb $0x0, (%rax)
movq 0x8(%rbp), %rax
leaq (%rbx,%rbx,4), %rcx
shlq $0x3, %rcx
addq 0x18(%r15), %rcx
movb 0x24(%rax,%rcx), %cl
cmpb $0x1, %cl
jne 0x3bbc
movq 0x10(%r14), %rax
movq $0x0, 0x10(%r14)
testq %rax, %rax
je 0x3ba8
movb $0x0, (%rax)
movq 0x18(%r14), %rax
movq $0x0, 0x18(%r14)
testq %rax, %rax
je 0x3bbc
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 0x2690(%rip), %rdi      # 0x626d
leaq 0x14f3(%rip), %rsi      # 0x50d7
leaq 0x150c(%rip), %rcx      # 0x50f7
movl $0xd6, %edx
callq 0x20f0
leaq 0x24dd(%rip), %rdi      # 0x60d9
leaq 0x167b(%rip), %rsi      # 0x527e
leaq 0x24f0(%rip), %rcx      # 0x60fa
movl $0x55a, %edx            # imm = 0x55A
callq 0x20f0