// File: /workspace/github_cpp_makefile_star2_O3/BU-DiSC[P]BF-Shared-Hashing/db.cpp
// Function: db::split_keys(std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>>, std::vector<std::vector<std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>>, std::allocator<std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>>>>, std::allocator<std::vector<std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>>, std::allocator<std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>>>>>>&)
void db::split_keys( vector<string> table_in, vector<vector<vector<string> > > & reallocated_keys )
{
	// calculate how many keys assigned in each level
	int num_keys = table_in.size();
	int level = 1;
	vector<int> bf_num_keys;
	if(num_keys < buffer_size){
		bf_num_keys.push_back(num_keys);	
	}else{
		num_sst = ceil((float)num_keys/(float)buffer_size);
		int tmp_num_keys = num_keys;
		level = (int) ceil(log(num_keys*1.0*(size_ratio - 1)/buffer_size + 1)/log(size_ratio));
		bf_num_keys = vector<int> (level, 0);
		// build the tree bottom-to-up
		for(int i = level - 1; i >= 1; i--){
			int sst_previous_levels = pow(size_ratio, i)/(size_ratio-1);
			int capacity_previous_levels = buffer_size * sst_previous_levels;
			if(capacity_previous_levels > tmp_num_keys) continue;
			int num_keys_curr_level = tmp_num_keys - capacity_previous_levels;
			bf_num_keys[i] = num_keys_curr_level;
			tmp_num_keys -= num_keys_curr_level;
		}
		bf_num_keys[0] = tmp_num_keys;
		
		int sum_keys = 0;
		for(int i = 0; i < level; i++){
			sum_keys += bf_num_keys[i];
		}
	}
	num_levels = level;
	num_sstPerLevel.resize( num_levels, 0);

	// allocate keys in each level
	vector<vector<string> > reversed_leveled_keys; // store the keys in each level reversely
	int start_index = 0;
	for(int i = level - 1; i >= 0; i--){
		int end_index = bf_num_keys[i] + start_index;
		if(end_index >= num_keys){
			reversed_leveled_keys.push_back(vector<string> (table_in.begin() + start_index, table_in.end()));
		}else{
			reversed_leveled_keys.push_back(vector<string> (table_in.begin() + start_index, table_in.begin() + end_index));
		}
		start_index = end_index;
	}	
	// split keys into equal-size sstables
	reallocated_keys.clear();
	fence_pointers.clear();
	for(int i = level - 1; i >= 0; i--){
		vector<vector<string> > sst_keys_one_level;
		vector<string> fence_pointer_one_level;
		split_keys_sst(buffer_size, reversed_leveled_keys[i], sst_keys_one_level, fence_pointer_one_level);

		num_sstPerLevel[(level-1)-i] = sst_keys_one_level.size();
		reallocated_keys.push_back(sst_keys_one_level);
		fence_pointers.push_back(fence_pointer_one_level);
		if(i == level - 1){
			last_sst_keys = sst_keys_one_level.back().size();
		}
	}
	SetTreeParam();
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0xc8, %rsp
movq %rdx, 0x38(%rsp)
movq %rsi, %r15
movq 0x8(%rsi), %rbx
subq (%rsi), %rbx
movq %rdi, %r13
shrq $0x5, %rbx
movl %ebx, 0xc(%rsp)
xorpd %xmm0, %xmm0
movapd %xmm0, 0x60(%rsp)
movq $0x0, 0x70(%rsp)
movl 0xd8(%rdi), %ebp
cmpl %ebx, %ebp
jle 0xadab
movl $0x1, %ebp
leaq 0x60(%rsp), %rdi
leaq 0xc(%rsp), %rdx
xorl %esi, %esi
callq 0x104ac
jmp 0xaef9
xorps %xmm0, %xmm0
cvtsi2ss %ebx, %xmm0
cvtsi2ss %ebp, %xmm1
divss %xmm1, %xmm0
callq 0x5250
cvttss2si %xmm0, %eax
movl %eax, 0xe0(%r13)
xorps %xmm1, %xmm1
cvtsi2sd %ebx, %xmm1
movl 0xd4(%r13), %eax
decl %eax
xorps %xmm0, %xmm0
cvtsi2sd %eax, %xmm0
cvtsi2sd %ebp, %xmm2
mulsd %xmm1, %xmm0
divsd %xmm2, %xmm0
addsd 0x1e343(%rip), %xmm0    # 0x29138
callq 0x5320
movsd %xmm0, (%rsp)
xorps %xmm0, %xmm0
cvtsi2sdl 0xd4(%r13), %xmm0
callq 0x5320
movsd (%rsp), %xmm1
divsd %xmm0, %xmm1
movapd %xmm1, %xmm0
callq 0x50b0
cvttsd2si %xmm0, %ebp
movslq %ebp, %rsi
leaq 0x40(%rsp), %rdx
movl $0x0, (%rdx)
leaq 0x10(%rsp), %rdi
leaq 0x80(%rsp), %rcx
callq 0xd926
movq 0x60(%rsp), %rdi
movapd 0x10(%rsp), %xmm0
movapd %xmm0, 0x60(%rsp)
movq 0x20(%rsp), %rax
movq %rax, 0x70(%rsp)
xorpd %xmm0, %xmm0
movapd %xmm0, 0x10(%rsp)
movq $0x0, 0x20(%rsp)
testq %rdi, %rdi
je 0xae8d
callq 0x53d0
movq 0x10(%rsp), %rdi
testq %rdi, %rdi
je 0xae8d
callq 0x53d0
cmpl $0x2, %ebp
jl 0xaef2
movl %ebp, %r14d
leaq -0x1(%r14), %r12
xorps %xmm0, %xmm0
cvtsi2sdl 0xd4(%r13), %xmm0
xorps %xmm1, %xmm1
cvtsi2sd %r12d, %xmm1
callq 0x56a0
movl 0xd4(%r13), %eax
decl %eax
xorps %xmm1, %xmm1
cvtsi2sd %eax, %xmm1
divsd %xmm1, %xmm0
cvttsd2si %xmm0, %eax
imull 0xd8(%r13), %eax
movl %ebx, %ecx
subl %eax, %ecx
jl 0xaee4
movq 0x60(%rsp), %rdx
movl %ecx, -0x4(%rdx,%r14,4)
movl %eax, %ebx
leaq 0x1(%r12), %rax
movq %r12, %r14
cmpq $0x2, %rax
ja 0xae95
movq 0x60(%rsp), %rax
movl %ebx, (%rax)
movl %ebp, 0xdc(%r13)
movq %r13, (%rsp)
leaq 0xe8(%r13), %rdi
movslq %ebp, %rsi
leaq 0x10(%rsp), %rdx
movl $0x0, (%rdx)
movq %rdi, 0xa8(%rsp)
movq %rsi, 0xa0(%rsp)
callq 0xd1f0
xorpd %xmm0, %xmm0
movapd %xmm0, 0x10(%rsp)
movq $0x0, 0x20(%rsp)
leal -0x1(%rbp), %eax
movl %eax, %r14d
movq %rbp, 0x30(%rsp)
testl %ebp, %ebp
jle 0xafde
leaq 0x1(%r14), %r12
xorl %ebp, %ebp
leaq 0x40(%rsp), %rbx
leaq 0x10(%rsp), %r13
movq 0x60(%rsp), %rax
movslq %ebp, %rsi
movslq -0x4(%rax,%r12,4), %rbp
addq %rsi, %rbp
cmpl 0xc(%rsp), %ebp
jge 0xafab
movq (%r15), %rax
shlq $0x5, %rsi
addq %rax, %rsi
movq %rbp, %rdx
shlq $0x5, %rdx
addq %rax, %rdx
movq %rbx, %rdi
leaq 0x80(%rsp), %rcx
callq 0xdaa2
movq %r13, %rdi
movq %rbx, %rsi
callq 0x10696
jmp 0xafd1
shlq $0x5, %rsi
addq (%r15), %rsi
movq 0x8(%r15), %rdx
movq %rbx, %rdi
leaq 0x80(%rsp), %rcx
callq 0xdaa2
movq %r13, %rdi
movq %rbx, %rsi
callq 0x10696
movq %rbx, %rdi
callq 0x698e
decq %r12
jg 0xaf64
movq 0x38(%rsp), %rax
movq (%rax), %r15
movq 0x8(%rax), %r12
cmpq %r15, %r12
movq (%rsp), %r13
je 0xb010
movq %r15, %rbx
movq %rbx, %rdi
callq 0x6bc8
addq $0x18, %rbx
cmpq %r12, %rbx
jne 0xaff6
movq 0x38(%rsp), %rax
movq %r15, 0x8(%rax)
movq 0x140(%r13), %r15
movq 0x148(%r13), %r12
cmpq %r15, %r12
movq 0x30(%rsp), %rbp
je 0xb043
movq %r15, %rbx
movq %rbx, %rdi
callq 0x698e
addq $0x18, %rbx
cmpq %r12, %rbx
jne 0xb02b
movq %r15, 0x148(%r13)
testl %ebp, %ebp
jle 0xb169
movq (%rsp), %rax
addq $0x140, %rax            # imm = 0x140
movq %rax, 0x30(%rsp)
movq 0xa0(%rsp), %rax
leaq 0x1(%rax), %r15
subq %rax, %r14
incq %r14
leaq (%rax,%rax,2), %rax
leaq -0x18(,%rax,8), %r13
leaq 0x40(%rsp), %rbp
leaq 0x80(%rsp), %rbx
xorpd %xmm0, %xmm0
movapd %xmm0, 0x40(%rsp)
xorl %eax, %eax
movq %rax, 0x50(%rsp)
movq %rax, 0x90(%rsp)
movapd %xmm0, 0x80(%rsp)
movq (%rsp), %rax
movl 0xd8(%rax), %r12d
movq 0x10(%rsp), %rsi
addq %r13, %rsi
leaq 0xb0(%rsp), %rdi
callq 0x690a
movl %r12d, %esi
leaq 0xb0(%rsp), %r12
movq %r12, %rdx
movq %rbp, %rcx
movq %rbx, %r8
callq 0xb20e
movq %r12, %rdi
callq 0x698e
movq 0x48(%rsp), %rax
subq 0x40(%rsp), %rax
shrq $0x3, %rax
imull $0xaaaaaaab, %eax, %eax # imm = 0xAAAAAAAB
movq 0xa8(%rsp), %rcx
movq (%rcx), %rcx
movl %eax, (%rcx,%r14,4)
movq 0x38(%rsp), %rdi
movq %rbp, %rsi
callq 0xdadc
movq 0x30(%rsp), %rdi
movq %rbx, %rsi
callq 0xdb08
testq %r14, %r14
jne 0xb145
movq 0x48(%rsp), %rax
movq -0x10(%rax), %rcx
subq -0x18(%rax), %rcx
shrq $0x5, %rcx
movq (%rsp), %rax
movl %ecx, 0x100(%rax)
movq %rbx, %rdi
callq 0x698e
movq %rbp, %rdi
callq 0x6bc8
decq %r15
incq %r14
addq $-0x18, %r13
cmpq $0x1, %r15
jg 0xb085
movq (%rsp), %rdi
callq 0xb3a0
leaq 0x10(%rsp), %rdi
callq 0x6bc8
movq 0x60(%rsp), %rdi
testq %rdi, %rdi
je 0xb18b
callq 0x53d0
addq $0xc8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0xb1a3
jmp 0xb1a3
jmp 0xb1aa
movq %rax, %rbx
jmp 0xb1f6
jmp 0xb1aa
movq %rax, %rbx
jmp 0xb1ec
jmp 0xb1b1
movq %rax, %rbx
leaq 0x40(%rsp), %rdi
callq 0x698e
jmp 0xb1ec
movq %rax, %rbx
leaq 0xb0(%rsp), %rdi
callq 0x698e
jmp 0xb1d5
movq %rax, %rbx
leaq 0x80(%rsp), %rdi
callq 0x698e
leaq 0x40(%rsp), %rdi
callq 0x6bc8
leaq 0x10(%rsp), %rdi
callq 0x6bc8
movq 0x60(%rsp), %rdi
testq %rdi, %rdi
je 0xb205
callq 0x53d0
movq %rbx, %rdi
callq 0x56b0
nop