// File: deepaktabraham[P]BPlus-Tree/src/main.cpp
// Function: main
int main(int argc, char* argv[])
{
	int m = ERROR, pos = ERROR;
	float key = ERROR, key1 = ERROR, key2 = ERROR;
	string line, value;
	class BPlusTree tree;

	// check command-line arguments
	if(NUM_ARGS != argc)
	{
		cout<<"Invalid argument!"<<endl;
		cout<<"Usage: ./treesearch <input_filename>"<<endl;
		exit(-1);
	}

	// check if input file is valid
	ifstream file(argv[1]);
	if(!file)
	{
		cout<<"Invalid input file!"<<endl;
		exit(-1);
	}

	// get the B+ tree order
	getline(file, line);
	try
	{
		m = stoi(line);
	}
	catch(...)
	{
		cout<<"Invalid B+ tree order!"<<endl;
		exit(-1);
	}

	// check if order is atleast 3
	if(m < MIN_ORDER)
	{
		cout<<"Invalid B+ tree order!"<<endl;
		exit(-1);
	}

	// initialize the B+ tree of order m
	tree.Initialize(m);

	// open the output file for writing results
	tree.Open_Output_File();

	// read the input file and perform the corresponding operations
	while (getline(file, line))
	{
		pos   = ERROR;
		key   = ERROR;
		value = ERROR;
		key1  = ERROR;
		key2  = ERROR;

		// operation: Insert(key, value)
		if(0 == line.compare(0, 6, "Insert"))
		{
			pos = line.find(",");
			key = atof(line.substr(7, pos - 7).c_str());
			value = line.substr(pos + 1, line.size() - pos - 2);

			// insert the key-value pair
			tree.Insert(key, value);		
		}

		// if it is a search operation
		else if (0 == line.compare(0, 6, "Search"))
		{
			// operation: Search(key)
			pos = line.find(",");
			if(ERROR == pos)
			{
				key = atof(line.substr(7, line.size() - 8).c_str());

				// search for the key and display the correpsonding value(s)
				tree.Search(key);
			}

			// operation: Search(key1, key2)
			else
			{
				key1 = atof(line.substr(7, pos - 7).c_str());
				key2 = atof(line.substr(pos + 1, line.size() - pos -2).c_str());

				// search for keys between key1 and key2, and display the corresponding value(s)
				tree.Search(key1, key2);	
			}
		}
	}

	// close the output file
	tree.Close_Output_File();

#ifdef DEBUG
	// print the current state of the B+ tree
	tree.Print_Tree();
#endif

	cout<<endl<<"Check "<<OUTPUT_FILE<<" for results!"<<endl<<endl;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x630, %rsp            # imm = 0x630
movl $0x0, -0x4(%rbp)
movl %edi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movl $0xffffffff, -0x14(%rbp) # imm = 0xFFFFFFFF
movl $0xffffffff, -0x18(%rbp) # imm = 0xFFFFFFFF
movl $0xbf800000, -0x1c(%rbp) # imm = 0xBF800000
movl $0xbf800000, -0x20(%rbp) # imm = 0xBF800000
movl $0xbf800000, -0x24(%rbp) # imm = 0xBF800000
leaq -0x48(%rbp), %rdi
callq 0x2230
leaq -0x68(%rbp), %rdi
callq 0x2230
leaq -0x278(%rbp), %rdi
callq 0x2cc0
jmp 0x259c
movl $0x2, %eax
cmpl -0x8(%rbp), %eax
je 0x2644
movq 0x15a1f(%rip), %rdi     # 0x17fd0
leaq 0xda4c(%rip), %rsi      # 0x10004
callq 0x2190
movq %rax, -0x558(%rbp)
jmp 0x25c6
movq -0x558(%rbp), %rdi
movq 0x159ec(%rip), %rsi     # 0x17fc0
callq 0x21c0
jmp 0x25db
movq 0x159ee(%rip), %rdi     # 0x17fd0
leaq 0xda2d(%rip), %rsi      # 0x10016
callq 0x2190
movq %rax, -0x560(%rbp)
jmp 0x25f7
movq -0x560(%rbp), %rdi
movq 0x159bb(%rip), %rsi     # 0x17fc0
callq 0x21c0
jmp 0x260c
movl $0xffffffff, %edi       # imm = 0xFFFFFFFF
callq 0x21d0
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x280(%rbp)
movl %eax, -0x284(%rbp)
jmp 0x2c99
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x280(%rbp)
movl %eax, -0x284(%rbp)
jmp 0x2c8d
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rsi
leaq -0x490(%rbp), %rdi
movl $0x8, %edx
callq 0x22e0
jmp 0x265f
movq -0x490(%rbp), %rax
movq -0x18(%rax), %rax
leaq -0x490(%rbp,%rax), %rdi
callq 0x20d0
movb %al, -0x561(%rbp)
jmp 0x267f
movb -0x561(%rbp), %al
testb $0x1, %al
jne 0x268b
jmp 0x26dd
movq 0x1593e(%rip), %rdi     # 0x17fd0
leaq 0xd9a2(%rip), %rsi      # 0x1003b
callq 0x2190
movq %rax, -0x570(%rbp)
jmp 0x26a7
movq -0x570(%rbp), %rdi
movq 0x1590b(%rip), %rsi     # 0x17fc0
callq 0x21c0
jmp 0x26bc
movl $0xffffffff, %edi       # imm = 0xFFFFFFFF
callq 0x21d0
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x280(%rbp)
movl %eax, -0x284(%rbp)
jmp 0x2c81
leaq -0x490(%rbp), %rdi
leaq -0x48(%rbp), %rsi
callq 0x2060
jmp 0x26ef
xorl %eax, %eax
movl %eax, %esi
leaq -0x48(%rbp), %rdi
movl $0xa, %edx
callq 0x2ce0
movl %eax, -0x574(%rbp)
jmp 0x2709
movl -0x574(%rbp), %eax
movl %eax, -0x14(%rbp)
jmp 0x278b
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x280(%rbp)
movl %eax, -0x284(%rbp)
movq -0x280(%rbp), %rdi
callq 0x20a0
movq 0x15897(%rip), %rdi     # 0x17fd0
leaq 0xd90f(%rip), %rsi      # 0x1004f
callq 0x2190
movq %rax, -0x580(%rbp)
jmp 0x274e
movq -0x580(%rbp), %rdi
movq 0x15864(%rip), %rsi     # 0x17fc0
callq 0x21c0
jmp 0x2763
movl $0xffffffff, %edi       # imm = 0xFFFFFFFF
callq 0x21d0
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x280(%rbp)
movl %eax, -0x284(%rbp)
callq 0x22a0
jmp 0x2786
jmp 0x2c81
cmpl $0x3, -0x14(%rbp)
jge 0x27cc
movq 0x15838(%rip), %rdi     # 0x17fd0
leaq 0xd8b0(%rip), %rsi      # 0x1004f
callq 0x2190
movq %rax, -0x588(%rbp)
jmp 0x27ad
movq -0x588(%rbp), %rdi
movq 0x15805(%rip), %rsi     # 0x17fc0
callq 0x21c0
jmp 0x27c2
movl $0xffffffff, %edi       # imm = 0xFFFFFFFF
callq 0x21d0
movl -0x14(%rbp), %esi
leaq -0x278(%rbp), %rdi
callq 0x3190
jmp 0x27dd
leaq -0x278(%rbp), %rdi
callq 0x4020
jmp 0x27eb
jmp 0x27ed
leaq -0x490(%rbp), %rdi
leaq -0x48(%rbp), %rsi
callq 0x2060
movq %rax, -0x590(%rbp)
jmp 0x2806
movq -0x590(%rbp), %rdi
movq (%rdi), %rax
movq -0x18(%rax), %rax
addq %rax, %rdi
callq 0x2200
movb %al, -0x591(%rbp)
jmp 0x2824
movb -0x591(%rbp), %al
testb $0x1, %al
jne 0x2833
jmp 0x2b9c
movl $0xffffffff, -0x18(%rbp) # imm = 0xFFFFFFFF
movl $0xbf800000, -0x1c(%rbp) # imm = 0xBF800000
leaq -0x68(%rbp), %rdi
movl $0xffffffff, %esi       # imm = 0xFFFFFFFF
callq 0x22b0
jmp 0x2851
movl $0xbf800000, -0x20(%rbp) # imm = 0xBF800000
movl $0xbf800000, -0x24(%rbp) # imm = 0xBF800000
leaq 0xd800(%rip), %rcx      # 0x10066
xorl %eax, %eax
movl %eax, %esi
leaq -0x48(%rbp), %rdi
movl $0x6, %edx
callq 0x2220
movl %eax, -0x598(%rbp)
jmp 0x2880
movl -0x598(%rbp), %ecx
xorl %eax, %eax
cmpl %ecx, %eax
jne 0x29e6
leaq 0xd80f(%rip), %rsi      # 0x100a6
xorl %eax, %eax
movl %eax, %edx
leaq -0x48(%rbp), %rdi
movq %rdi, -0x5a0(%rbp)
callq 0x22f0
movq -0x5a0(%rbp), %rsi
movl %eax, -0x18(%rbp)
movl -0x18(%rbp), %eax
addl $-0x7, %eax
movslq %eax, %rcx
leaq -0x4b0(%rbp), %rdi
movl $0x7, %edx
callq 0x21b0
jmp 0x28d1
leaq -0x4b0(%rbp), %rdi
movq %rdi, -0x5b8(%rbp)
callq 0x20b0
movq %rax, %rdi
callq 0x21f0
movq -0x5b8(%rbp), %rdi
cvtsd2ss %xmm0, %xmm0
movss %xmm0, -0x1c(%rbp)
callq 0x2120
movl -0x18(%rbp), %eax
incl %eax
cltq
movq %rax, -0x5a8(%rbp)
leaq -0x48(%rbp), %rdi
movq %rdi, -0x5b0(%rbp)
callq 0x2130
movq -0x5b0(%rbp), %rsi
movq -0x5a8(%rbp), %rdx
movq %rax, %rcx
movslq -0x18(%rbp), %rax
subq %rax, %rcx
addq $-0x2, %rcx
leaq -0x4d0(%rbp), %rdi
callq 0x21b0
jmp 0x2949
leaq -0x68(%rbp), %rdi
movq %rdi, -0x5c8(%rbp)
leaq -0x4d0(%rbp), %rsi
movq %rsi, -0x5d0(%rbp)
callq 0x21e0
movq -0x5d0(%rbp), %rdi
callq 0x2120
movq -0x5c8(%rbp), %rsi
movss -0x1c(%rbp), %xmm0
movss %xmm0, -0x5bc(%rbp)
leaq -0x4f0(%rbp), %rdi
callq 0x20c0
jmp 0x2995
movss -0x5bc(%rbp), %xmm0
leaq -0x278(%rbp), %rdi
leaq -0x4f0(%rbp), %rsi
callq 0x31b0
jmp 0x29b2
leaq -0x4f0(%rbp), %rdi
callq 0x2120
jmp 0x2b97
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x280(%rbp)
movl %eax, -0x284(%rbp)
leaq -0x4f0(%rbp), %rdi
callq 0x2120
jmp 0x2c81
leaq 0xd680(%rip), %rcx      # 0x1006d
xorl %eax, %eax
movl %eax, %esi
leaq -0x48(%rbp), %rdi
movl $0x6, %edx
callq 0x2220
movl %eax, -0x5d4(%rbp)
jmp 0x2a07
movl -0x5d4(%rbp), %ecx
xorl %eax, %eax
cmpl %ecx, %eax
jne 0x2b95
leaq -0x48(%rbp), %rdi
leaq 0xd684(%rip), %rsi      # 0x100a6
xorl %eax, %eax
movl %eax, %edx
callq 0x22f0
movl %eax, -0x18(%rbp)
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
cmpl -0x18(%rbp), %eax
jne 0x2ab1
leaq -0x48(%rbp), %rdi
movq %rdi, -0x5e0(%rbp)
callq 0x2130
movq -0x5e0(%rbp), %rsi
movq %rax, %rcx
addq $-0x8, %rcx
leaq -0x510(%rbp), %rdi
movl $0x7, %edx
callq 0x21b0
jmp 0x2a69
leaq -0x510(%rbp), %rdi
movq %rdi, -0x5e8(%rbp)
callq 0x20b0
movq %rax, %rdi
callq 0x21f0
movq -0x5e8(%rbp), %rdi
cvtsd2ss %xmm0, %xmm0
movss %xmm0, -0x1c(%rbp)
callq 0x2120
movss -0x1c(%rbp), %xmm0
leaq -0x278(%rbp), %rdi
callq 0x3550
jmp 0x2aac
jmp 0x2b93
movl -0x18(%rbp), %eax
addl $-0x7, %eax
movslq %eax, %rcx
leaq -0x530(%rbp), %rdi
leaq -0x48(%rbp), %rsi
movl $0x7, %edx
callq 0x21b0
jmp 0x2ad1
leaq -0x530(%rbp), %rdi
movq %rdi, -0x600(%rbp)
callq 0x20b0
movq %rax, %rdi
callq 0x21f0
movq -0x600(%rbp), %rdi
cvtsd2ss %xmm0, %xmm0
movss %xmm0, -0x20(%rbp)
callq 0x2120
movl -0x18(%rbp), %eax
incl %eax
cltq
movq %rax, -0x5f0(%rbp)
leaq -0x48(%rbp), %rdi
movq %rdi, -0x5f8(%rbp)
callq 0x2130
movq -0x5f8(%rbp), %rsi
movq -0x5f0(%rbp), %rdx
movq %rax, %rcx
movslq -0x18(%rbp), %rax
subq %rax, %rcx
addq $-0x2, %rcx
leaq -0x550(%rbp), %rdi
callq 0x21b0
jmp 0x2b49
leaq -0x550(%rbp), %rdi
movq %rdi, -0x608(%rbp)
callq 0x20b0
movq %rax, %rdi
callq 0x21f0
movq -0x608(%rbp), %rdi
cvtsd2ss %xmm0, %xmm0
movss %xmm0, -0x24(%rbp)
callq 0x2120
movss -0x20(%rbp), %xmm0
movss -0x24(%rbp), %xmm1
leaq -0x278(%rbp), %rdi
callq 0x38f0
jmp 0x2b91
jmp 0x2b93
jmp 0x2b95
jmp 0x2b97
jmp 0x27ed
leaq -0x278(%rbp), %rdi
callq 0x4060
jmp 0x2baa
movq 0x1541f(%rip), %rdi     # 0x17fd0
movq 0x15408(%rip), %rsi     # 0x17fc0
callq 0x21c0
movq %rax, -0x610(%rbp)
jmp 0x2bc6
movq -0x610(%rbp), %rdi
leaq 0xd4a0(%rip), %rsi      # 0x10074
callq 0x2190
movq %rax, -0x618(%rbp)
jmp 0x2be2
movq -0x618(%rbp), %rdi
leaq 0xd48b(%rip), %rsi      # 0x1007b
callq 0x2190
movq %rax, -0x620(%rbp)
jmp 0x2bfe
movq -0x620(%rbp), %rdi
leaq 0xd47f(%rip), %rsi      # 0x1008b
callq 0x2190
movq %rax, -0x628(%rbp)
jmp 0x2c1a
movq -0x628(%rbp), %rdi
movq 0x15398(%rip), %rsi     # 0x17fc0
callq 0x21c0
movq %rax, -0x630(%rbp)
jmp 0x2c36
movq -0x630(%rbp), %rdi
movq 0x1537c(%rip), %rsi     # 0x17fc0
callq 0x21c0
jmp 0x2c4b
leaq -0x490(%rbp), %rdi
callq 0x2070
leaq -0x278(%rbp), %rdi
callq 0x4080
leaq -0x68(%rbp), %rdi
callq 0x2120
leaq -0x48(%rbp), %rdi
callq 0x2120
movl -0x4(%rbp), %eax
addq $0x630, %rsp            # imm = 0x630
popq %rbp
retq
leaq -0x490(%rbp), %rdi
callq 0x2070
leaq -0x278(%rbp), %rdi
callq 0x4080
leaq -0x68(%rbp), %rdi
callq 0x2120
leaq -0x48(%rbp), %rdi
callq 0x2120
movq -0x280(%rbp), %rdi
callq 0x22d0
movq %rax, %rdi
callq 0x2d20
nop