// File: /workspace/github_cpp_makefile_star2_O2/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, 0x58(%rsp)
movq %rsi, %r15
movq %rdi, %r12
movq 0x8(%rsi), %r13
subq (%rsi), %r13
shrq $0x5, %r13
movl %r13d, 0xc(%rsp)
andq $0x0, 0x50(%rsp)
xorpd %xmm0, %xmm0
movapd %xmm0, 0x40(%rsp)
movl 0xd8(%rdi), %ebx
cmpl %r13d, %ebx
jle 0x9e54
leaq 0x40(%rsp), %rdi
leaq 0xc(%rsp), %rsi
callq 0xb962
pushq $0x1
popq %rbp
jmp 0x9f61
cvtsi2ss %r13d, %xmm0
cvtsi2ss %ebx, %xmm1
divss %xmm1, %xmm0
callq 0x6270
cvttss2si %xmm0, %eax
movl %eax, 0xe0(%r12)
cvtsi2sd %r13d, %xmm1
movl 0xd4(%r12), %eax
decl %eax
cvtsi2sd %eax, %xmm0
cvtsi2sd %ebx, %xmm2
mulsd %xmm1, %xmm0
divsd %xmm2, %xmm0
addsd 0x18267(%rip), %xmm0    # 0x22100
callq 0x6340
movsd %xmm0, 0x10(%rsp)
movl 0xd4(%r12), %edi
callq 0xb980
movsd 0x10(%rsp), %xmm1
divsd %xmm0, %xmm1
movapd %xmm1, %xmm0
callq 0x60a0
cvttsd2si %xmm0, %ebp
movslq %ebp, %rsi
leaq 0x20(%rsp), %rdx
andl $0x0, (%rdx)
leaq 0x60(%rsp), %rdi
leaq 0x80(%rsp), %rcx
callq 0xb98a
leaq 0x40(%rsp), %rdi
leaq 0x60(%rsp), %r14
movq %r14, %rsi
callq 0xddf8
movq %r14, %rdi
callq 0x751c
movl %ebp, %ebx
leal -0x1(%rbx), %r14d
cmpl $0x1, %ebx
jle 0x9f59
decq %rbx
cvtsi2sdl 0xd4(%r12), %xmm0
cvtsi2sd %r14d, %xmm1
callq 0x66a0
movl 0xd4(%r12), %eax
decl %eax
cvtsi2sd %eax, %xmm1
divsd %xmm1, %xmm0
cvttsd2si %xmm0, %eax
imull 0xd8(%r12), %eax
decq %r14
movl %r13d, %ecx
subl %eax, %ecx
jl 0x9f05
movq 0x40(%rsp), %rdx
movl %ecx, 0x4(%rdx,%r14,4)
movl %eax, %r13d
jmp 0x9f01
movq 0x40(%rsp), %rax
movl %r13d, (%rax)
movl %ebp, 0xdc(%r12)
movq %r12, 0x10(%rsp)
leaq 0xe8(%r12), %rdi
movslq %ebp, %rsi
leaq 0x60(%rsp), %rdx
andl $0x0, (%rdx)
movq %rdi, 0xa8(%rsp)
callq 0xb398
xorpd %xmm0, %xmm0
leaq 0x60(%rsp), %r14
movapd %xmm0, (%r14)
andq $0x0, 0x10(%r14)
decl %ebp
xorl %ebx, %ebx
leaq 0x20(%rsp), %r13
movl %ebp, %r12d
leaq 0x80(%rsp), %rbp
movl %r12d, 0x1c(%rsp)
testl %r12d, %r12d
js 0xa031
movl %r12d, %eax
movq 0x40(%rsp), %rcx
movslq %ebx, %rsi
movslq (%rcx,%rax,4), %rbx
addq %rsi, %rbx
cmpl 0xc(%rsp), %ebx
jge 0xa003
movq (%r15), %rax
shlq $0x5, %rsi
addq %rax, %rsi
movq %rbx, %rdx
shlq $0x5, %rdx
addq %rax, %rdx
movq %r13, %rdi
movq %rbp, %rcx
callq 0xb9e0
movq %r14, %rdi
movq %r13, %rsi
callq 0xdf12
jmp 0xa024
shlq $0x5, %rsi
addq (%r15), %rsi
movq 0x8(%r15), %rdx
movq %r13, %rdi
movq %rbp, %rcx
callq 0xb9e0
movq %r14, %rdi
movq %r13, %rsi
callq 0xdf12
movq %r13, %rdi
callq 0x739e
decl %r12d
jmp 0x9fba
movq 0x58(%rsp), %rdi
callq 0xba12
movq 0x10(%rsp), %r12
leaq 0x140(%r12), %rdi
movq %rdi, 0xa0(%rsp)
callq 0xba1a
movslq 0x1c(%rsp), %rbx
imulq $0x18, %rbx, %r15
xorl %r13d, %r13d
leaq 0x20(%rsp), %rbp
leaq 0x80(%rsp), %r14
testq %rbx, %rbx
js 0xa157
andq $0x0, 0x30(%rsp)
xorpd %xmm0, %xmm0
movapd %xmm0, 0x20(%rsp)
andq $0x0, 0x90(%rsp)
movapd %xmm0, 0x80(%rsp)
movl 0xd8(%r12), %r12d
movq 0x60(%rsp), %rsi
addq %r15, %rsi
leaq 0xb0(%rsp), %rdi
callq 0x734a
movl %r12d, %esi
leaq 0xb0(%rsp), %r12
movq %r12, %rdx
movq %rbp, %rcx
movq %r14, %r8
callq 0xa1f0
movq %r12, %rdi
callq 0x739e
movq 0x28(%rsp), %rax
subq 0x20(%rsp), %rax
cqto
pushq $0x18
popq %rcx
idivq %rcx
movq 0xa8(%rsp), %rcx
movq (%rcx), %rcx
movl %eax, (%rcx,%r13,4)
movq 0x58(%rsp), %rdi
movq %rbp, %rsi
callq 0xba22
movq 0xa0(%rsp), %rdi
movq %r14, %rsi
callq 0xba4e
testq %r13, %r13
movq 0x10(%rsp), %r12
jne 0xa138
movq 0x28(%rsp), %rax
movq -0x10(%rax), %rcx
subq -0x18(%rax), %rcx
shrq $0x5, %rcx
movl %ecx, 0x100(%r12)
movq %r14, %rdi
callq 0x739e
movq %rbp, %rdi
callq 0x74f0
decq %rbx
incq %r13
addq $-0x18, %r15
jmp 0xa06e
movq %r12, %rdi
callq 0xa31c
leaq 0x60(%rsp), %rdi
callq 0x74f0
leaq 0x40(%rsp), %rdi
callq 0x751c
addq $0xc8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0xa18b
jmp 0xa18b
jmp 0xa194
movq %rax, %rbx
jmp 0xa1de
jmp 0xa199
jmp 0xa194
movq %rax, %rbx
jmp 0xa1d4
movq %rax, %rbx
leaq 0x20(%rsp), %rdi
callq 0x739e
jmp 0xa1d4
movq %rax, %rbx
leaq 0xb0(%rsp), %rdi
callq 0x739e
jmp 0xa1bd
movq %rax, %rbx
leaq 0x80(%rsp), %rdi
callq 0x739e
leaq 0x20(%rsp), %rdi
callq 0x74f0
leaq 0x60(%rsp), %rdi
callq 0x74f0
leaq 0x40(%rsp), %rdi
callq 0x751c
movq %rbx, %rdi
callq 0x66b0