// File: /workspace/github_cpp_makefile_star2_O2/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, (%rsp)
movq %rcx, %rbx
movq %rdx, %r15
movq %rdi, %r13
movq %rsi, %xmm0
punpckldq 0x4433(%rip), %xmm0 # xmm0 = xmm0[0],mem[0],xmm0[1],mem[1]
subpd 0x443b(%rip), %xmm0     # 0x11a60
movapd %xmm0, %xmm1
unpckhpd %xmm0, %xmm1            # xmm1 = xmm1[1],xmm0[1]
addsd %xmm0, %xmm1
sqrtsd %xmm1, %xmm0
mulsd 0x4443(%rip), %xmm0     # 0x11a80
addsd %xmm1, %xmm0
cvttsd2si %xmm0, %rax
movq %rax, %rdx
subsd 0x4437(%rip), %xmm0     # 0x11a88
cvttsd2si %xmm0, %r14
sarq $0x3f, %rdx
andq %rdx, %r14
orq %rax, %r14
leaq 0x3f(%r14), %rdx
leaq (%rcx,%r15), %rbp
shlq $0x3, %rbp
movq %r15, 0x8(%rsp)
movq %rsi, 0x18(%rsp)
movq %rsi, %rax
cmpq $0x2, %rax
jb 0xd68b
decq %r15
shrq %rax
addq $-0x8, %rbp
jmp 0xd679
shrq $0x6, %rdx
movq %rdx, 0x10(%rsp)
leaq (%rbx,%r15), %rax
movq %rax, 0x20(%rsp)
movabsq $0x1ffffffffffffff8, %rax # imm = 0x1FFFFFFFFFFFFFF8
andq %rax, %rbp
addq $0x11, %rbp
imulq %rdx, %rbp
pushq $0x18
popq %rdi
pushq $0x1
popq %rsi
callq 0x2120
movq %rax, (%r13)
cmpb $0x0, (%rsp)
je 0xd75c
movq %rax, %r12
pushq $0x1
popq %rsi
movl $0x80, %edi
callq 0x2120
movq %r13, %rcx
movq %r13, 0x28(%rsp)
movq %rax, %r13
movq %rax, 0x8(%rcx)
movq %rbp, (%rax)
movl 0x70(%rsp), %eax
movl %eax, 0x8(%r13)
movq 0x18(%rsp), %rdi
movq %rdi, 0x10(%r13)
movq %r14, 0x18(%r13)
movq 0x8(%rsp), %rax
movq %rax, 0x20(%r13)
movq %rbx, 0x28(%r13)
movq %r15, 0x30(%r13)
movq 0x20(%rsp), %rax
movq %rax, 0x38(%r13)
movzbl %al, %edx
xorl %esi, %esi
callq 0x2360
movq %rax, 0x40(%r13)
movq %rdx, 0x48(%r13)
movq 0x10(%rsp), %rax
movq %rax, 0x50(%r13)
shrq $0xc, %r14
addq $0x2, %r14
movq %r14, 0x70(%r13)
movq %rbp, %rdi
pushq $0x1
popq %rsi
callq 0x2120
movq 0x28(%rsp), %rcx
movq %rax, 0x10(%rcx)
jmp 0xd847
movq 0x20(%rsp), %r12
movq %rbx, (%rsp)
movq 0x30(%rsp), %rdi
movl $0x242, %esi            # imm = 0x242
movl $0x1c0, %edx            # imm = 0x1C0
xorl %eax, %eax
callq 0x2170
movq (%r13), %rcx
movl %eax, (%rcx)
testl %eax, %eax
js 0xd86f
subq $-0x80, %rbp
movl %eax, %edi
xorl %esi, %esi
xorl %edx, %edx
movq %rbp, %rcx
callq 0x2190
testl %eax, %eax
js 0xd878
movq %r12, %rbx
movq (%r13), %rax
movl (%rax), %r8d
pushq $0x3
popq %rdx
pushq $0x1
popq %rcx
xorl %edi, %edi
movq %rbp, %rsi
xorl %r9d, %r9d
callq 0x23c0
movq %rax, %r12
movq %rax, 0x8(%r13)
movl 0x70(%rsp), %eax
movl %eax, 0x8(%r12)
movq 0x18(%rsp), %rdi
movq %rdi, 0x10(%r12)
movq %r14, 0x18(%r12)
movq 0x8(%rsp), %rax
movq %rax, 0x20(%r12)
movq (%rsp), %rax
movq %rax, 0x28(%r12)
movq %r15, 0x30(%r12)
movq %rbx, 0x38(%r12)
movzbl %bl, %edx
xorl %esi, %esi
callq 0x2360
movq %rax, 0x40(%r12)
movq %rdx, 0x48(%r12)
movq 0x10(%rsp), %rax
movq %rax, 0x50(%r12)
shrq $0xc, %r14
addq $0x2, %r14
xorpd %xmm0, %xmm0
movupd %xmm0, 0x58(%r12)
andq $0x0, 0x68(%r12)
movq %r14, 0x70(%r12)
addq $0x4000, %r12           # imm = 0x4000
movq %r12, 0x10(%r13)
movq (%r13), %r12
movl $0x0, 0x4(%r12)
pushq $0x4
popq %rsi
movq %r14, %rdi
callq 0x2120
movq %rax, 0x8(%r12)
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x4227(%rip), %rdi      # 0x11a9d
jmp 0xd87f
leaq 0x4233(%rip), %rdi      # 0x11ab2
callq 0x21c0
pushq $0x1
popq %rdi
callq 0x2290