// File: /workspace/github_cpp_makefile_star2_O2/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, %rbx
bsrq %rsi, %rcx
notl %ecx
movabsq $-0x8000000000000000, %r15 # imm = 0x8000000000000000
shrq %cl, %r15
movq %rdi, %r13
notq %r15
andq %rsi, %r15
movq %r15, %rsi
callq 0x4336
testq %rax, %rax
jne 0x440b
movq %r13, %rdi
movq %r15, %rsi
callq 0x43c6
movq %rax, 0x18(%rsp)
leaq 0x18(%r13), %r14
pushq $0x1
popq %rbp
pushq $0x4
popq %r12
movq %r13, 0x10(%rsp)
movq %rbx, 0x20(%rsp)
movq %r14, %r15
cmpl $0x3, %ebp
je 0x4506
movl %r12d, %eax
subl %ebp, %eax
incl %ebp
imull $0x6, %eax, %eax
cvtsi2sd %eax, %xmm0
callq 0x2100
cvttsd2si %xmm0, %rax
movq %rax, %rcx
sarq $0x3f, %rcx
subsd 0x1bb8(%rip), %xmm0     # 0x6010
cvttsd2si %xmm0, %rsi
andq %rcx, %rsi
orq %rax, %rsi
movq %rbx, %rax
xorl %edx, %edx
divq %rsi
andl $0x3f, %eax
shll $0x4, %eax
movq 0x8(%r15,%rax), %r14
testq %r14, %r14
jne 0x4425
movl %r12d, %ebx
leaq (%r15,%rax), %r12
addq $0x8, %r12
movq %r13, %rdi
movl %ebp, %esi
callq 0x3f40
movq %rax, %r14
andq $0x0, 0x8(%rsp)
movq %r12, %rdi
leaq 0x8(%rsp), %rsi
movq %rax, %rdx
pushq $0x3
popq %rcx
callq 0x45e0
testb %al, %al
jne 0x44f9
testq %r14, %r14
je 0x44f4
movq -0x8(%r14), %r13
testq %r13, %r13
je 0x44d8
leaq -0x10(%r14), %r15
movq %r13, %r12
shlq $0x4, %r12
leaq (%r15,%r12), %rdi
callq 0x3ec6
addq $-0x10, %r12
jne 0x44c9
addq $-0x8, %r14
shlq $0x4, %r13
orq $0x8, %r13
movq %r14, %rdi
movq %r13, %rsi
callq 0x2240
movq 0x10(%rsp), %r13
movq 0x8(%rsp), %r14
movl %ebx, %r12d
movq 0x20(%rsp), %rbx
jmp 0x4425
movl %ebx, %eax
shrl $0x2, %eax
andl $0x3f0, %eax            # imm = 0x3F0
movq 0x8(%r15,%rax), %r12
testq %r12, %r12
jne 0x455f
addq %rax, %r15
addq $0x8, %r15
leaq 0x8(%rsp), %r13
andq $0x0, (%r13)
movq 0x10(%rsp), %rdi
callq 0x3f98
movq %rax, %r12
pushq $0x3
popq %rcx
movq %r15, %rdi
movq %r13, %rsi
movq %rax, %rdx
callq 0x45e0
testb %al, %al
jne 0x455f
testq %r12, %r12
je 0x455a
movq %r12, %rdi
callq 0x2170
movq 0x8(%rsp), %r12
movl %ebx, %r14d
andl $0x3f, %r14d
movl %r14d, %eax
movq (%r12,%rax,8), %r15
testq %r15, %r15
jne 0x45b7
pushq $0x20
popq %rdi
callq 0x2150
movq %rax, %r15
movq %rax, %rdi
movq %rbx, %rsi
callq 0x3fba
leaq 0x8(%rsp), %rcx
movq 0x10(%rsp), %rdi
movq 0x18(%rsp), %rsi
movq %r15, %rdx
callq 0x4638
testb %al, %al
je 0x45a9
movq %r15, (%r12,%r14,8)
jmp 0x45b7
movq (%r15), %rax
movq %r15, %rdi
callq *0x10(%rax)
movq 0x8(%rsp), %r15
movq %r15, %rax
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %rax, %rbx
pushq $0x20
popq %rsi
movq %r15, %rdi
callq 0x2160
movq %rbx, %rdi
callq 0x2230
nop