// File: 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:
subq $0x1e8, %rsp            # imm = 0x1E8
movq %rsi, 0x60(%rsp)
movq %rdi, %rax
movq 0x60(%rsp), %rdi
movq %rdi, 0x68(%rsp)
movq %rax, 0x1e0(%rsp)
movq %rdi, 0x1d8(%rsp)
movq %rdx, 0x1d0(%rsp)
movq 0x1e0(%rsp), %rax
movq %rax, 0x70(%rsp)
callq 0x8020
movl %eax, 0x1cc(%rsp)
movl $0x1, 0x1c8(%rsp)
leaq 0x1b0(%rsp), %rdi
callq 0x10ef0
movq 0x70(%rsp), %rcx
movl 0x1cc(%rsp), %eax
cmpl 0xd8(%rcx), %eax
jge 0xe72b
leaq 0x1b0(%rsp), %rdi
leaq 0x1cc(%rsp), %rsi
callq 0x12290
jmp 0xe70d
jmp 0xe9ff
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1a8(%rsp)
movl %eax, 0x1a4(%rsp)
jmp 0xef0b
movq 0x70(%rsp), %rax
cvtsi2ssl 0x1cc(%rsp), %xmm0
cvtsi2ssl 0xd8(%rax), %xmm1
divss %xmm1, %xmm0
callq 0x111f0
movss %xmm0, 0x5c(%rsp)
jmp 0xe752
movq 0x70(%rsp), %rax
movss 0x5c(%rsp), %xmm0
cvttss2si %xmm0, %ecx
movl %ecx, 0xe0(%rax)
movl 0x1cc(%rsp), %ecx
movl %ecx, 0x1a0(%rsp)
cvtsi2sdl 0x1cc(%rsp), %xmm0
movl 0xd4(%rax), %ecx
decl %ecx
cvtsi2sd %ecx, %xmm1
mulsd %xmm1, %xmm0
cvtsi2sdl 0xd8(%rax), %xmm1
divsd %xmm1, %xmm0
movsd 0x55956(%rip), %xmm1    # 0x640f8
addsd %xmm1, %xmm0
callq 0x6430
movq 0x70(%rsp), %rax
movsd %xmm0, 0x48(%rsp)
movl 0xd4(%rax), %edi
callq 0x12300
movsd %xmm0, 0x50(%rsp)
jmp 0xe7c9
movsd 0x50(%rsp), %xmm1
movsd 0x48(%rsp), %xmm0
divsd %xmm1, %xmm0
callq 0x60e0
cvttsd2si %xmm0, %eax
movl %eax, 0x1c8(%rsp)
movslq 0x1c8(%rsp), %rax
movq %rax, 0x38(%rsp)
movl $0x0, 0x184(%rsp)
leaq 0x183(%rsp), %rdi
movq %rdi, 0x40(%rsp)
callq 0x12320
movq 0x38(%rsp), %rsi
movq 0x40(%rsp), %rcx
leaq 0x188(%rsp), %rdi
leaq 0x184(%rsp), %rdx
callq 0x12330
jmp 0xe834
leaq 0x1b0(%rsp), %rdi
leaq 0x188(%rsp), %rsi
callq 0x123b0
leaq 0x188(%rsp), %rdi
callq 0x84a0
leaq 0x183(%rsp), %rdi
callq 0x8740
movl 0x1c8(%rsp), %eax
subl $0x1, %eax
movl %eax, 0x17c(%rsp)
cmpl $0x1, 0x17c(%rsp)
jl 0xe97d
movq 0x70(%rsp), %rax
movl 0xd4(%rax), %edi
movl 0x17c(%rsp), %esi
callq 0x123f0
movsd %xmm0, 0x30(%rsp)
jmp 0xe8a1
movq 0x70(%rsp), %rax
movsd 0x30(%rsp), %xmm0
movl 0xd4(%rax), %ecx
subl $0x1, %ecx
cvtsi2sd %ecx, %xmm1
divsd %xmm1, %xmm0
cvttsd2si %xmm0, %ecx
movl %ecx, 0x178(%rsp)
movl 0xd8(%rax), %eax
imull 0x178(%rsp), %eax
movl %eax, 0x174(%rsp)
movl 0x174(%rsp), %eax
cmpl 0x1a0(%rsp), %eax
jle 0xe915
jmp 0xe967
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1a8(%rsp)
movl %eax, 0x1a4(%rsp)
leaq 0x183(%rsp), %rdi
callq 0x8740
jmp 0xef0b
movl 0x1a0(%rsp), %eax
subl 0x174(%rsp), %eax
movl %eax, 0x170(%rsp)
movl 0x170(%rsp), %eax
movl %eax, 0x2c(%rsp)
movslq 0x17c(%rsp), %rsi
leaq 0x1b0(%rsp), %rdi
callq 0x113c0
movl 0x2c(%rsp), %ecx
movl %ecx, (%rax)
movl 0x170(%rsp), %ecx
movl 0x1a0(%rsp), %eax
subl %ecx, %eax
movl %eax, 0x1a0(%rsp)
movl 0x17c(%rsp), %eax
addl $-0x1, %eax
movl %eax, 0x17c(%rsp)
jmp 0xe874
movl 0x1a0(%rsp), %eax
movl %eax, 0x28(%rsp)
leaq 0x1b0(%rsp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x113c0
movl 0x28(%rsp), %ecx
movl %ecx, (%rax)
movl $0x0, 0x16c(%rsp)
movl $0x0, 0x168(%rsp)
movl 0x168(%rsp), %eax
cmpl 0x1c8(%rsp), %eax
jge 0xe9fd
movslq 0x168(%rsp), %rsi
leaq 0x1b0(%rsp), %rdi
callq 0x113c0
movl (%rax), %eax
addl 0x16c(%rsp), %eax
movl %eax, 0x16c(%rsp)
movl 0x168(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x168(%rsp)
jmp 0xe9b5
jmp 0xe9ff
movq 0x70(%rsp), %rax
movl 0x1c8(%rsp), %ecx
movl %ecx, 0xdc(%rax)
movq %rax, %rdi
addq $0xe8, %rdi
movslq 0xdc(%rax), %rsi
movl $0x0, 0x164(%rsp)
leaq 0x164(%rsp), %rdx
callq 0x11260
jmp 0xea3c
leaq 0x148(%rsp), %rdi
callq 0x10f00
movl $0x0, 0x144(%rsp)
movl 0x1c8(%rsp), %eax
subl $0x1, %eax
movl %eax, 0x140(%rsp)
cmpl $0x0, 0x140(%rsp)
jl 0xecd6
movslq 0x140(%rsp), %rsi
leaq 0x1b0(%rsp), %rdi
callq 0x113c0
movl (%rax), %eax
addl 0x144(%rsp), %eax
movl %eax, 0x13c(%rsp)
movl 0x13c(%rsp), %eax
cmpl 0x1cc(%rsp), %eax
jl 0xeba2
movq 0x68(%rsp), %rdi
callq 0xa460
movq %rax, 0x110(%rsp)
movslq 0x144(%rsp), %rsi
leaq 0x110(%rsp), %rdi
callq 0x12440
movq 0x68(%rsp), %rdi
movq %rax, 0x118(%rsp)
callq 0xa2d0
movq %rax, 0x108(%rsp)
leaq 0x107(%rsp), %rdi
movq %rdi, 0x20(%rsp)
callq 0x81f0
movq 0x20(%rsp), %rcx
movq 0x118(%rsp), %rsi
movq 0x108(%rsp), %rdx
leaq 0x120(%rsp), %rdi
callq 0x12480
jmp 0xeb23
leaq 0x148(%rsp), %rdi
leaq 0x120(%rsp), %rsi
callq 0x12410
jmp 0xeb3a
leaq 0x120(%rsp), %rdi
callq 0x7e60
leaq 0x107(%rsp), %rdi
callq 0x8f60
jmp 0xecb2
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1a8(%rsp)
movl %eax, 0x1a4(%rsp)
jmp 0xeb90
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1a8(%rsp)
movl %eax, 0x1a4(%rsp)
leaq 0x120(%rsp), %rdi
callq 0x7e60
leaq 0x107(%rsp), %rdi
callq 0x8f60
jmp 0xeefe
movq 0x68(%rsp), %rdi
callq 0xa460
movq %rax, 0xd8(%rsp)
movslq 0x144(%rsp), %rsi
leaq 0xd8(%rsp), %rdi
callq 0x12440
movq 0x68(%rsp), %rdi
movq %rax, 0xe0(%rsp)
callq 0xa460
movq %rax, 0xc8(%rsp)
movslq 0x13c(%rsp), %rsi
leaq 0xc8(%rsp), %rdi
callq 0x12440
movq %rax, 0xd0(%rsp)
leaq 0xc7(%rsp), %rdi
movq %rdi, 0x18(%rsp)
callq 0x81f0
movq 0x18(%rsp), %rcx
movq 0xe0(%rsp), %rsi
movq 0xd0(%rsp), %rdx
leaq 0xe8(%rsp), %rdi
callq 0x12480
jmp 0xec36
leaq 0x148(%rsp), %rdi
leaq 0xe8(%rsp), %rsi
callq 0x12410
jmp 0xec4d
leaq 0xe8(%rsp), %rdi
callq 0x7e60
leaq 0xc7(%rsp), %rdi
callq 0x8f60
jmp 0xecb2
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1a8(%rsp)
movl %eax, 0x1a4(%rsp)
jmp 0xeca0
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1a8(%rsp)
movl %eax, 0x1a4(%rsp)
leaq 0xe8(%rsp), %rdi
callq 0x7e60
leaq 0xc7(%rsp), %rdi
callq 0x8f60
jmp 0xeefe
movl 0x13c(%rsp), %eax
movl %eax, 0x144(%rsp)
movl 0x140(%rsp), %eax
addl $-0x1, %eax
movl %eax, 0x140(%rsp)
jmp 0xea65
movq 0x1d0(%rsp), %rdi
callq 0x12510
movq 0x70(%rsp), %rdi
addq $0x140, %rdi            # imm = 0x140
callq 0x12530
movl 0x1c8(%rsp), %eax
subl $0x1, %eax
movl %eax, 0xc0(%rsp)
cmpl $0x0, 0xc0(%rsp)
jl 0xeebc
leaq 0xa8(%rsp), %rdi
callq 0x10f00
leaq 0x90(%rsp), %rdi
callq 0x7a20
movq 0x70(%rsp), %rax
movl 0xd8(%rax), %eax
movl %eax, 0x14(%rsp)
movslq 0xc0(%rsp), %rsi
leaq 0x148(%rsp), %rdi
callq 0x11460
movq %rax, %rsi
leaq 0x78(%rsp), %rdi
callq 0x7d60
jmp 0xed60
movl 0x14(%rsp), %esi
movq 0x70(%rsp), %rdi
leaq 0x78(%rsp), %rdx
leaq 0xa8(%rsp), %rcx
leaq 0x90(%rsp), %r8
callq 0xef30
jmp 0xed85
leaq 0x78(%rsp), %rdi
callq 0x7e60
leaq 0xa8(%rsp), %rdi
movq %rdi, 0x8(%rsp)
callq 0x9a50
movq 0x70(%rsp), %rdi
movl %eax, 0x4(%rsp)
addq $0xe8, %rdi
movl 0x1c8(%rsp), %ecx
movl 0xc0(%rsp), %eax
notl %eax
addl %ecx, %eax
movslq %eax, %rsi
callq 0x113c0
movl 0x4(%rsp), %ecx
movq 0x8(%rsp), %rsi
movl %ecx, (%rax)
movq 0x1d0(%rsp), %rdi
callq 0x12550
jmp 0xede5
movq 0x70(%rsp), %rdi
addq $0x140, %rdi            # imm = 0x140
leaq 0x90(%rsp), %rsi
callq 0x125c0
jmp 0xee00
movl 0xc0(%rsp), %eax
movl 0x1c8(%rsp), %ecx
subl $0x1, %ecx
cmpl %ecx, %eax
jne 0xee70
leaq 0xa8(%rsp), %rdi
callq 0x12630
movq %rax, %rdi
callq 0x8020
movq %rax, %rcx
movq 0x70(%rsp), %rax
movl %ecx, 0x100(%rax)
jmp 0xee70
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1a8(%rsp)
movl %eax, 0x1a4(%rsp)
jmp 0xeea0
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1a8(%rsp)
movl %eax, 0x1a4(%rsp)
leaq 0x78(%rsp), %rdi
callq 0x7e60
jmp 0xeea0
leaq 0x90(%rsp), %rdi
callq 0x7e60
leaq 0xa8(%rsp), %rdi
callq 0x8560
movl 0xc0(%rsp), %eax
addl $-0x1, %eax
movl %eax, 0xc0(%rsp)
jmp 0xed05
leaq 0x90(%rsp), %rdi
callq 0x7e60
leaq 0xa8(%rsp), %rdi
callq 0x8560
jmp 0xeefe
movq 0x70(%rsp), %rdi
callq 0xf270
jmp 0xeec8
leaq 0x148(%rsp), %rdi
callq 0x8560
leaq 0x1b0(%rsp), %rdi
callq 0x84a0
addq $0x1e8, %rsp            # imm = 0x1E8
retq
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x1a8(%rsp)
movl %eax, 0x1a4(%rsp)
leaq 0x148(%rsp), %rdi
callq 0x8560
leaq 0x1b0(%rsp), %rdi
callq 0x84a0
movq 0x1a8(%rsp), %rdi
callq 0x6850
nopw %cs:(%rax,%rax)