// File: /workspace/github_cpp_makefile_star2_O2/splatlab[P]debgr/threadsafe-gqf/gqf.c
// Function: run_end(quotient_filter const*, unsigned long)
static inline uint64_t run_end(const QF *qf, uint64_t hash_bucket_index)
{
	uint64_t bucket_block_index       = hash_bucket_index / SLOTS_PER_BLOCK;
	uint64_t bucket_intrablock_offset = hash_bucket_index % SLOTS_PER_BLOCK;
	uint64_t bucket_blocks_offset = block_offset(qf, bucket_block_index);

	// uint64_t bucket_intrablock_rank   = bitrankv(get_block(qf, bucket_block_index)->occupieds, METADATA_WORDS_PER_BLOCK, bucket_intrablock_offset);
	uint64_t bucket_intrablock_rank   = bitrank(get_block(qf,
																												bucket_block_index)->occupieds[0],
																							bucket_intrablock_offset);

	if (bucket_intrablock_rank == 0) {
		if (bucket_blocks_offset <= bucket_intrablock_offset)
			return hash_bucket_index;
		else
			return SLOTS_PER_BLOCK * bucket_block_index + bucket_blocks_offset - 1;
	}

	/* FIXME: Should handle offset overflow  --- Ah screw it, just use 16-bit offset.  That'll never overflow.  */
	uint64_t runend_block_index  = bucket_block_index + bucket_blocks_offset /
		SLOTS_PER_BLOCK;
	uint64_t runend_ignore_bits  = bucket_blocks_offset % SLOTS_PER_BLOCK;
	uint64_t runend_rank         = bucket_intrablock_rank - 1;
	// uint64_t runend_block_offset = bitselectv(get_block(qf, runend_block_index)->runends, METADATA_WORDS_PER_BLOCK, runend_ignore_bits, runend_rank);
	uint64_t runend_block_offset = bitselectv(get_block(qf,
																											runend_block_index)->runends[0],
																						runend_ignore_bits, runend_rank);
	if (runend_block_offset == SLOTS_PER_BLOCK) {
		if (bucket_blocks_offset == 0 && bucket_intrablock_rank == 0) {
			/* The block begins in empty space, and this bucket is in that region of empty space */
			return hash_bucket_index;
		} else {
			do {
				// runend_rank        -= popcntv(get_block(qf, runend_block_index)->runends, METADATA_WORDS_PER_BLOCK, runend_ignore_bits);
				runend_rank        -= popcntv(get_block(qf,
																								runend_block_index)->runends[0],
																			runend_ignore_bits);
				runend_block_index++;
				runend_ignore_bits  = 0;
				// runend_block_offset = bitselectv(get_block(qf, runend_block_index)->runends, METADATA_WORDS_PER_BLOCK, runend_ignore_bits, runend_rank);
				runend_block_offset = bitselectv(get_block(qf,
																									 runend_block_index)->runends[0],
																				 runend_ignore_bits, runend_rank);
			} while (runend_block_offset == SLOTS_PER_BLOCK);
		}
	}

	uint64_t runend_index = SLOTS_PER_BLOCK * runend_block_index + runend_block_offset;
	if (runend_index < hash_bucket_index)
		return hash_bucket_index;
	else
		return runend_index;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x18, %rsp
movq %rsi, %r8
shrq $0x6, %r8
movl %esi, %ecx
andl $0x3f, %ecx
movq 0x8(%rdi), %rax
movq 0x10(%rdi), %r13
movabsq $0x3ffffffffffffff, %rdx # imm = 0x3FFFFFFFFFFFFFF
andq 0x38(%rax), %rdx
leaq 0x11(,%rdx,8), %rbx
movq %rbx, %rdx
imulq %r8, %rdx
movzbl (%r13,%rdx), %r12d
pushq $0x2
popq %rax
shlq %cl, %rax
decq %rax
andq 0x1(%r13,%rdx), %rax
popcntq %rax, %rax
testl %eax, %eax
je 0xed64
movq %rsi, 0x8(%rsp)
movslq %eax, %r15
movl %r12d, %ebp
shrl $0x6, %ebp
movq %r8, (%rsp)
leaq (%r8,%rbp), %r14
decq %r15
movq %r14, %rax
imulq %rbx, %rax
movq %rax, 0x10(%rsp)
movq 0x9(%r13,%rax), %rdi
andl $0x3f, %r12d
movl %r12d, %esi
movl %r15d, %edx
callq 0x10071
cmpq $0x40, %rax
jne 0xed4c
addq $0x9, %r13
movq (%rsp), %rax
addq %rax, %rbp
incq %rbp
imulq %rbx, %rbp
movq 0x10(%rsp), %rax
movq (%r13,%rax), %rax
testl %r12d, %r12d
je 0xed26
movl %r12d, %ecx
shrq %cl, %rax
shlq %cl, %rax
popcntq %rax, %rax
jmp 0xed2b
popcntq %rax, %rax
cltq
subq %rax, %r15
incq %r14
movq (%r13,%rbp), %rdi
movl %r15d, %esi
callq 0xf088
addq %rbx, %r13
xorl %r12d, %r12d
cmpq $0x40, %rax
je 0xed07
shlq $0x6, %r14
addq %rax, %r14
movq 0x8(%rsp), %rax
cmpq %rax, %r14
cmovbeq %rax, %r14
movq %r14, %rax
jmp 0xed76
cmpl %r12d, %ecx
jae 0xed73
andq $-0x40, %rsi
addq %r12, %rsi
decq %rsi
movq %rsi, %rax
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq