// File: /workspace/github_cpp_makefile_star2_O3/splatlab[P]debgr/threadsafe-gqf/gqf.c
// Function: qf_init
void qf_init(QF *qf, uint64_t nslots, uint64_t key_bits, uint64_t value_bits,
						 bool mem, const char * path, uint32_t seed)
{
	uint64_t num_slots, xnslots, nblocks;
	uint64_t key_remainder_bits, bits_per_slot;
	uint64_t size;

	assert(popcnt(nslots) == 1); /* nslots must be a power of 2 */
	num_slots = nslots;
	assert(popcnt(nslots) == 1); /* nslots must be a power of 2 */
	xnslots = nslots + 10*sqrt((double)nslots);
	nblocks = (xnslots + SLOTS_PER_BLOCK - 1) / SLOTS_PER_BLOCK;
	key_remainder_bits = key_bits;
	while (nslots > 1) {
		assert(key_remainder_bits > 0);
		key_remainder_bits--;
		nslots >>= 1;
	}

	bits_per_slot = key_remainder_bits + value_bits;
	assert (BITS_PER_SLOT == 0 || BITS_PER_SLOT == qf->metadata->bits_per_slot);
	assert(bits_per_slot > 1);
#if BITS_PER_SLOT == 8 || BITS_PER_SLOT == 16 || BITS_PER_SLOT == 32 || BITS_PER_SLOT == 64
	size = nblocks * sizeof(qfblock);
#else
	size = nblocks * (sizeof(qfblock) + SLOTS_PER_BLOCK * bits_per_slot / 8);
#endif

	qf->mem = (qfmem *)calloc(sizeof(qfmem), 1);
	
	if (mem) {
		qf->metadata = (qfmetadata *)calloc(sizeof(qfmetadata), 1);

		qf->metadata->size = size;
		qf->metadata->seed = seed;
		qf->metadata->nslots = num_slots;
		qf->metadata->xnslots = qf->metadata->nslots +
			10*sqrt((double)qf->metadata->nslots);
		qf->metadata->key_bits = key_bits;
		qf->metadata->value_bits = value_bits;
		qf->metadata->key_remainder_bits = key_remainder_bits;
		qf->metadata->bits_per_slot = bits_per_slot;

		qf->metadata->range = qf->metadata->nslots;
		qf->metadata->range <<= qf->metadata->bits_per_slot;
		qf->metadata->nblocks = (qf->metadata->xnslots + SLOTS_PER_BLOCK - 1) /
			SLOTS_PER_BLOCK;
		qf->metadata->nelts = 0;
		qf->metadata->ndistinct_elts = 0;
		qf->metadata->noccupied_slots = 0;
		qf->metadata->num_locks = (qf->metadata->xnslots/NUM_SLOTS_TO_LOCK)+2;

		qf->blocks = (qfblock *)calloc(size, 1);

	} else {
		int ret;

		qf->mem->fd = open(path, O_RDWR | O_CREAT | O_TRUNC, S_IRWXU);
		if (qf->mem->fd < 0) {
			perror("Couldn't open file:\n");
			exit(EXIT_FAILURE);
		}
		ret = fallocate(qf->mem->fd, 0, 0, size+sizeof(qfmetadata));
		if (ret < 0) {
			perror("Couldn't fallocate file:\n");
			exit(EXIT_FAILURE);
		}
		qf->metadata = (qfmetadata *)mmap(NULL, size+sizeof(qfmetadata), PROT_READ |
																			PROT_WRITE, MAP_SHARED, qf->mem->fd, 0);

		qf->metadata->seed = seed;
		qf->metadata->nslots = num_slots;
		qf->metadata->xnslots = qf->metadata->nslots +
														10*sqrt((double)qf->metadata->nslots);
		qf->metadata->key_bits = key_bits;
		qf->metadata->value_bits = value_bits;
		qf->metadata->key_remainder_bits = key_remainder_bits;
		qf->metadata->bits_per_slot = bits_per_slot;

		qf->metadata->range = qf->metadata->nslots;
		qf->metadata->range <<= qf->metadata->bits_per_slot;
		qf->metadata->nblocks = (qf->metadata->xnslots + SLOTS_PER_BLOCK - 1) /
			SLOTS_PER_BLOCK;
		qf->metadata->nelts = 0;
		qf->metadata->ndistinct_elts = 0;
		qf->metadata->noccupied_slots = 0;
		qf->metadata->num_locks = (qf->metadata->xnslots/NUM_SLOTS_TO_LOCK)+2;

		qf->blocks = (qfblock *)(qf->metadata + sizeof(qfmetadata));
	}
	
	/* initialize all the locks to 0 */
	qf->mem->metadata_lock = 0;
	qf->mem->locks = (volatile int *)calloc(qf->metadata->num_locks,
																					sizeof(volatile int));
#ifdef LOG_WAIT_TIME
	qf->wait_times = (wait_time_data* )calloc(qf->metadata->num_locks+1,
																						sizeof(wait_time_data));
#endif
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x38, %rsp
movq %r9, 0x30(%rsp)
movl %r8d, 0x14(%rsp)
movq %rsi, %r15
movq %rsi, %xmm0
punpckldq 0x4ddc(%rip), %xmm0 # xmm0 = xmm0[0],mem[0],xmm0[1],mem[1]
subpd 0x4de4(%rip), %xmm0     # 0x14a60
movapd %xmm0, %xmm1
unpckhpd %xmm0, %xmm1            # xmm1 = xmm1[1],xmm0[1]
addsd %xmm0, %xmm1
xorps %xmm0, %xmm0
sqrtsd %xmm1, %xmm0
mulsd 0x4de9(%rip), %xmm0     # 0x14a80
movq %rdi, 0x8(%rsp)
addsd %xmm1, %xmm0
cvttsd2si %xmm0, %rax
movq %rax, %rsi
sarq $0x3f, %rsi
subsd 0x4dd4(%rip), %xmm0     # 0x14a88
cvttsd2si %xmm0, %rbx
andq %rsi, %rbx
orq %rax, %rbx
leaq 0x3f(%rbx), %r8
shrq $0x6, %r8
movq %rdx, %r14
cmpq $0x2, %r15
jb 0xfce8
movq %r15, %rax
movq %rdx, %r14
movq %r15, %rsi
decq %r14
shrq %rsi
cmpq $0x3, %rax
movq %rsi, %rax
ja 0xfcd9
movq %rdx, 0x18(%rsp)
leaq (%r14,%rcx), %rbp
movabsq $0x3ffffffffffffff, %rax # imm = 0x3FFFFFFFFFFFFFF
andq %rbp, %rax
leaq 0x11(,%rax,8), %r12
imulq %r8, %r12
movl $0x18, %edi
movl $0x1, %esi
movq %r8, 0x28(%rsp)
movq %rcx, 0x20(%rsp)
callq 0x2130
movq %rax, %r13
movq 0x8(%rsp), %rax
movq %r13, (%rax)
cmpb $0x0, 0x14(%rsp)
je 0xfdce
movl $0x80, %edi
movl $0x1, %esi
callq 0x2130
movq 0x8(%rsp), %rcx
movq %rax, 0x8(%rcx)
movq %r12, (%rax)
movl 0x70(%rsp), %ecx
movl %ecx, 0x8(%rax)
movq %r15, 0x10(%rax)
movq %rbx, 0x18(%rax)
movq 0x18(%rsp), %rcx
movq %rcx, 0x20(%rax)
movq 0x20(%rsp), %rcx
movq %rcx, 0x28(%rax)
movq %r14, 0x30(%rax)
movq %rbp, 0x38(%rax)
xorl %edx, %edx
movl %ebp, %ecx
shldq %cl, %r15, %rdx
shlq %cl, %r15
xorl %ecx, %ecx
testb $0x40, %bpl
cmovneq %r15, %rdx
cmovneq %rcx, %r15
movq %r15, 0x40(%rax)
movq %rdx, 0x48(%rax)
movq 0x28(%rsp), %rcx
movq %rcx, 0x50(%rax)
shrq $0xc, %rbx
addq $0x2, %rbx
movq %rbx, 0x70(%rax)
movl $0x1, %esi
movq %r12, %rdi
callq 0x2130
movq 0x8(%rsp), %rcx
movq %rax, 0x10(%rcx)
jmp 0xfeb6
movq 0x30(%rsp), %rdi
movl $0x242, %esi            # imm = 0x242
movl $0x1c0, %edx            # imm = 0x1C0
xorl %eax, %eax
callq 0x2190
movq 0x8(%rsp), %r13
movq (%r13), %rcx
movl %eax, (%rcx)
testl %eax, %eax
js 0xfede
subq $-0x80, %r12
movl %eax, %edi
xorl %esi, %esi
xorl %edx, %edx
movq %r12, %rcx
callq 0x21b0
testl %eax, %eax
js 0xfee3
movq (%r13), %rax
movl (%rax), %r8d
xorl %edi, %edi
movq %r12, %rsi
movl $0x3, %edx
movl $0x1, %ecx
xorl %r9d, %r9d
callq 0x23c0
movq %rax, 0x8(%r13)
movl 0x70(%rsp), %ecx
movl %ecx, 0x8(%rax)
movq %r15, 0x10(%rax)
movq %rbx, 0x18(%rax)
movq 0x18(%rsp), %rcx
movq %rcx, 0x20(%rax)
xorl %edx, %edx
movl %ebp, %ecx
shldq %cl, %r15, %rdx
movq 0x20(%rsp), %rcx
movq %rcx, 0x28(%rax)
movq %r14, 0x30(%rax)
movq %rbp, 0x38(%rax)
movl %ebp, %ecx
shlq %cl, %r15
testb $0x40, %bpl
cmovneq %r15, %rdx
movl $0x0, %ecx
cmovneq %rcx, %r15
movq %r15, 0x40(%rax)
movq %rdx, 0x48(%rax)
movq 0x28(%rsp), %rcx
movq %rcx, 0x50(%rax)
shrq $0xc, %rbx
addq $0x2, %rbx
xorpd %xmm0, %xmm0
movupd %xmm0, 0x58(%rax)
movq $0x0, 0x68(%rax)
movq %rbx, 0x70(%rax)
addq $0x4000, %rax           # imm = 0x4000
movq %rax, 0x10(%r13)
movq (%r13), %r13
movl $0x0, 0x4(%r13)
movl $0x4, %esi
movq %rbx, %rdi
callq 0x2130
movq %rax, 0x8(%r13)
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
callq 0x2499
callq 0x2484