// File: /workspace/github_cpp_makefile_star2_O1/bhhbazinga[P]LockFreeHashTable/./lockfree_hashtable.h
// Function: LockFreeHashTable<int, int, std::hash<int>>::InitializeBucket(unsigned long)
typename LockFreeHashTable<K, V, Hash>::DummyNode*
LockFreeHashTable<K, V, Hash>::InitializeBucket(BucketIndex bucket_index) {
  BucketIndex parent_index = GetBucketParent(bucket_index);
  DummyNode* parent_head = GetBucketHeadByIndex(parent_index);
  if (nullptr == parent_head) {
    parent_head = InitializeBucket(parent_index);
  }

  int level = 1;
  Segment* segments = segments_;  // Point to current segment.
  while (level++ <= kMaxLevel - 2) {
    Segment& cur_segment =
        segments[(bucket_index / static_cast<SegmentIndex>(pow(
                                     kSegmentSize, kMaxLevel - level + 1))) %
                 kSegmentSize];
    Segment* sub_segments = cur_segment.get_sub_segments();
    if (nullptr == sub_segments) {
      // Try allocate segments.
      sub_segments = NewSegments(level);
      void* expected = nullptr;
      if (!cur_segment.data.compare_exchange_strong(
              expected, sub_segments, std::memory_order_release)) {
        delete[] sub_segments;
        sub_segments = static_cast<Segment*>(expected);
      }
    }
    segments = sub_segments;
  }

  Segment& cur_segment = segments[(bucket_index / kSegmentSize) % kSegmentSize];
  Bucket* buckets = cur_segment.get_sub_buckets();
  if (nullptr == buckets) {
    // Try allocate buckets.
    void* expected = nullptr;
    buckets = NewBuckets();
    if (!cur_segment.data.compare_exchange_strong(expected, buckets,
                                                  std::memory_order_release)) {
      delete[] buckets;
      buckets = static_cast<Bucket*>(expected);
    }
  }

  Bucket& bucket = buckets[bucket_index % kSegmentSize];
  DummyNode* head = bucket.load(std::memory_order_consume);
  if (nullptr == head) {
    // Try allocate dummy head.
    head = new DummyNode(bucket_index);
    DummyNode* real_head;  // If insert failed, real_head is the head of bucket.
    if (InsertDummyNode(parent_head, head, &real_head)) {
      // Dummy head must be inserted into the list before storing into bucket.
      bucket.store(head, std::memory_order_release);
    } else {
      delete head;
      head = real_head;
    }
  }
  return head;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x28, %rsp
movq %rsi, %r14
bsrq %rsi, %rcx
notl %ecx
movabsq $-0x8000000000000000, %r15 # imm = 0x8000000000000000
shrq %cl, %r15
movq %rdi, %rbp
notq %r15
andq %rsi, %r15
movq %r15, %rsi
callq 0x4592
testq %rax, %rax
jne 0x466f
movq %rbp, %rdi
movq %r15, %rsi
callq 0x462a
movq %rax, 0x10(%rsp)
leaq 0x18(%rbp), %r13
movl $0x1, %r12d
movl $0x2, %eax
movq %r14, 0x18(%rsp)
movq %rbp, 0x8(%rsp)
movq %r13, %r15
movl $0x4, %edx
subl %r12d, %edx
movl %eax, %r12d
addl %edx, %edx
leal (%rdx,%rdx,2), %eax
xorps %xmm0, %xmm0
cvtsi2sd %eax, %xmm0
callq 0x20f0
cvttsd2si %xmm0, %rax
movq %rax, %rcx
sarq $0x3f, %rcx
subsd 0x1950(%rip), %xmm0     # 0x6010
cvttsd2si %xmm0, %rsi
andq %rcx, %rsi
orq %rax, %rsi
movq %r14, %rax
xorl %edx, %edx
divq %rsi
andl $0x3f, %eax
shll $0x4, %eax
movq 0x8(%r13,%rax), %r13
testq %r13, %r13
jne 0x475c
leaq (%r15,%rax), %rbx
addq $0x8, %rbx
movq %rbp, %rdi
movl %r12d, %esi
callq 0x4186
movq %rax, %rbp
xorl %eax, %eax
lock
cmpxchgq %rbp, (%rbx)
movq %rax, %r13
movl $0x0, %eax
cmoveq %rax, %r13
jne 0x4713
movq %rbp, %r13
jmp 0x4757
testq %rbp, %rbp
je 0x4757
movq -0x8(%rbp), %rbx
testq %rbx, %rbx
je 0x473b
leaq -0x10(%rbp), %r14
movq %rbx, %r15
shlq $0x4, %r15
leaq (%r14,%r15), %rdi
callq 0x410c
addq $-0x10, %r15
jne 0x472c
addq $-0x8, %rbp
shlq $0x4, %rbx
orq $0x8, %rbx
movq %rbp, %rdi
movq %rbx, %rsi
callq 0x2240
movq 0x18(%rsp), %r14
movq 0x8(%rsp), %rbp
leal 0x1(%r12), %eax
cmpl $0x4, %eax
jne 0x468d
movl %r14d, %eax
shrl $0x2, %eax
andl $0x3f0, %eax            # imm = 0x3F0
movq 0x8(%r13,%rax), %r12
testq %r12, %r12
jne 0x47be
leaq (%rax,%r13), %r15
addq $0x8, %r15
movl $0x200, %edi            # imm = 0x200
callq 0x2030
movq %rax, %r12
xorl %eax, %eax
movq $0x0, (%r12,%rax,8)
incq %rax
cmpq $0x40, %rax
jne 0x4796
xorl %eax, %eax
lock
cmpxchgq %r12, (%r15)
je 0x47be
movq %rax, %r15
movq %r12, %rdi
callq 0x2160
movq %r15, %r12
movl %r14d, %r15d
andl $0x3f, %r15d
movl %r15d, %eax
movq (%r12,%rax,8), %r13
testq %r13, %r13
jne 0x483d
movl $0x20, %edi
callq 0x2130
movq %rax, %r13
leaq 0x54b3(%rip), %rax      # 0x9c98
movq %rax, (%r13)
movq %r14, 0x8(%r13)
movq %r13, %rdi
movq %r14, %rsi
callq 0x41fe
movq %rax, 0x10(%r13)
movq $0x0, 0x18(%r13)
leaq 0x5435(%rip), %rax      # 0x9c40
movq %rax, (%r13)
leaq 0x20(%rsp), %rcx
movq %rbp, %rdi
movq 0x10(%rsp), %rsi
movq %r13, %rdx
callq 0x4850
testb %al, %al
je 0x482e
movq %r13, (%r12,%r15,8)
jmp 0x483d
movq (%r13), %rax
movq %r13, %rdi
callq *0x10(%rax)
movq 0x20(%rsp), %r13
movq %r13, %rax
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
nop