// File: /workspace/github_cpp_makefile_star2_O2/ratulSharker[P]Havec/src/vector_with_rehash_8_hash_with_N_detection_6_bytes.cpp
// Function: populateBlock6Byte(khmerInfo6Byte*, unsigned long long, char*, unsigned short)
void populateBlock6Byte(struct khmerInfo6Byte * memBlock, unsigned long long blockSize, char *fileName,unsigned short int khmerSize){

	//opening the given file
	std::ifstream inputFile;
	inputFile.open(fileName,std::fstream::in);
	std::string buf,temp="";
	bool isFirstKhmer = true;
	unsigned long long * lastFoundKHashVal;
	lastFoundKHashVal=new unsigned long long[LAST_HASH_FUNC+1];
	
	bool n_found = false;//if n found in the read, then the read processing is left inactive 
						 // till the next new read sequence is found !!!
	
	unsigned long long consumedRead = 0;
	unsigned int lastHashFuncUsed = 0;//containe the value that is last used to store last khmer
	
	//for stat purpose use only:)
	unsigned long mem_block_occupied_stat = 0,mem_block_found_stat=0;
	unsigned long list_occupied_stat = 0,list_occupied_found=0;
	unsigned long mem_block_total_number_of_occupied = 0; //exact number of khmer stored in the memblock
	unsigned long vector_total_number_of_occupied = 0; //exact number of khmer stored in the vector 
	
	//ofstream myfile;
	//myfile.open("firstKmers.txt");
	//error log if can't be opened
	if(inputFile.fail() == true){
		/*
		 * if fail to load the file -- return
		 */
		std::cout<<"Fail to open the "<<fileName << std::endl;
		return;
	}


	//if successfull then log it !!!
	std::cout<<"Consuming... "<<fileName<<std::endl;

	//parsing the fasta file
	while(getline(inputFile,buf)){//reading a line

			if(buf[0] == '>'){
				//its a sequence name -- omit it !!! -- before omit clear the temp
				
				n_found = false; //new sequence found so i can't tell that exactly that, this new read sequence is bad or not -- time to consume
				
				temp = ""; //cleaning the old remaining khmer
				
				isFirstKhmer = true;
				consumedRead++;
				if(consumedRead%1000000==0){
					std::cout<<consumedRead/1000000<<" million read consumed..."<<std::endl;
					currentDateTime();
					/*show_vect_status_6_byte();
						std::cout<<"stat from consume function :: "<<std::endl
							<<"khmer in memBlock :: "<<mem_block_occupied_stat<<std::endl
							<<"khmer in list :: "<<list_occupied_stat<<std::endl<<std::endl;
							cout<<"*********************************"<<endl;
					*/	double vm, rss;
						process_mem_usage(vm, rss);
						cout << "Memory used (GB):  " << ((vm)/1024)/1024 <<endl;
				}
				//std::cout<<buf<<std::endl;
				continue;
			}
			else if(n_found == false){//if read sequence is not bad, consume it
									//if it is bad, then just omit consuming :) till a new read sequence found
									
				//here come the one sequnece of read
				buf = temp.append(buf);//no new read sequnence is found so the next line of read must be appended to the last
				unsigned int i;
				unsigned int bufSize = buf.size();//for optimization purpose only
				unsigned int loopTime = bufSize - khmerSize;//for optimization purpose only
				unsigned int addResult; //for optimization only

				if(isFirstKhmer == true){
					//its the first read line of the multiple read lines
					i = 1;
				}
				else{
					//its not the first line of the multiple read line
					i= 0;
				}

				//if it the first line then consume it explicitly by using fullHasher
				if(isFirstKhmer == true){
				
					if(bufSize < khmerSize){
						/*cout<<"**************************************************"<<endl;						
						cout<<"Problem detected !!!"<<endl;
						cout<<"read sequence size is less then the khmer size -- processing next read :("<<endl;
						cout<<"seq :: "<<buf<<endl;
						cout<<"**************************************************"<<endl;
						*/
						continue;						
					}
					//start of a new read detected
					temp = buf.substr(0,khmerSize); //here temp denote the string khmer
					
					//std::cout<<"khmer's in the read (first):: "<<temp<<std::endl;
					
					if(bufSize > khmerSize){
						//khmer has a neighbour :) -- so put the khmer in the blockArray
						
						//saving the first khmer
						//myfile<<temp<<endl;//_revhash(lastFoundKHashVal,khmerSize)<<endl; //saving the first khmer -- revhash isn't working right now
						
						// hash function trying formation 0th->1th->2th->3th
						bool stored = false;
						for(int ii=0;ii<=LAST_HASH_FUNC;ii++){
						
							//for the first khmer all the 
							//saving signature that which hash function is being used for the first khmer
							lastFoundKHashVal[ii] = fullHasher(temp,ii); //saving the hash
							
							if(buf.length() > khmerSize ){//checking that next khmer is not invalid
								switch(toupper(buf[khmerSize])){
									case 'A':
									case 'T':
									case 'G':
									case 'C':
									break;
									
									default:
									neucleotide_status = N_FOUND_IN_NEUCLEOTIDE;
									break;
								}
							}
							
							if(neucleotide_status == N_FOUND_IN_NEUCLEOTIDE){
								n_found = true;
								break;
							}
							
							//std::cout<<"store try ("<<ii<<")"<<endl;
							
							//cout<<"trying to store-"<<temp<<" hashfunc-"<<ii<<" hashed value-"<<lastFoundKHashVal[ii]<<" neighbour "<<buf[khmerSize]<<endl;
							switch(storeKhmerInMemBlock6Byte(temp,memBlock,blockSize,lastFoundKHashVal[ii],buf[khmerSize],ii)){
							
							case MEM_BLOCK:
								mem_block_occupied_stat++;
								mem_block_total_number_of_occupied++;
								lastHashFuncUsed = ii;
								stored = true;
								break;
							case MEM_BLOCK_FOUND:
								//cout<<"mem_block_found :: "<<temp<<endl;
								mem_block_found_stat++;
								mem_block_total_number_of_occupied++;
								lastHashFuncUsed = ii;
								stored=true;
								break;
							case LIST:
								list_occupied_stat++; //this will happen only for the las time (hash Func 3)
								lastHashFuncUsed = ii;
								vector_total_number_of_occupied++;
								stored = true;
								break;
							case LIST_FOUND:
								//cout<<"list_found :: "<<temp<<endl;
								list_occupied_found++;
								vector_total_number_of_occupied++;
								lastHashFuncUsed = ii;
								stored=true;
								break;
							case ERROR:
								//std::cout<<"ERROR OCCURED"<<std::endl;
								//return;
								break;
							}
							if(stored){
								break; //break out from the for loop
							}
						}
						//for debug purpose
						//std::cout<<"inside firstkhmer "<<std::endl;
						//std::cout<<temp<<std::endl;
					}

					isFirstKhmer = false;
				}
				
				if(n_found == true){ //in the first khmer N found so abort consuming using continue statement
					continue;
				}
				
				
				
				for( ; i <= loopTime && n_found == false; i++){
					temp = buf.substr(i,khmerSize);

					//std::cout<<"khmer's in the read (intermediate) :: "<<temp<<std::endl;

					addResult = i + khmerSize;

					if(bufSize > addResult){
						
						bool stored = false;
						for(int ii=0;ii<=LAST_HASH_FUNC;ii++){
							
							if(ii<=lastHashFuncUsed){
								//last used hash func & current hashfunc is same -- so partial hasher would do the job
								
								//neighbour left so put it into the memBlock
								//cout<<"using partial hash func with last hash func value "<<lastFoundKHashVal[ii]<<" and next neighbour "<<temp[khmerSize - 1]<<endl;
								lastFoundKHashVal[ii] = partialHasher(lastFoundKHashVal[ii],temp[khmerSize - 1],khmerSize,ii);
								//lastFoundKHashVal = fullHasher(temp,ii); //saving the hash
							}  
							else{
								lastFoundKHashVal[ii] = fullHasher(temp,ii); //saving the hash
							}
							
							if(buf.length() >= addResult + 1){//checking that next khmer is not invalid
								switch(toupper(buf[addResult])){
									case 'A':
									case 'T':
									case 'G':
									case 'C':
									break;
									
									default:
									neucleotide_status = N_FOUND_IN_NEUCLEOTIDE;
									break;
								}
							}
							
							if(neucleotide_status == N_FOUND_IN_NEUCLEOTIDE){//N found in the middle of consuming
								n_found = true;
								break;
							}
							
							//std::cout<<"store try ("<<ii<<")"<<endl;
							
							//cout<<"trying to store-"<<temp<<" neighbour "<<buf[addResult]<<" hashfunc-"<<ii<<" last found hashed value "<<lastFoundKHashVal[ii]<<endl;
							//cout<<"Hash "<<temp<<" "<<buf[addResult]<<endl;
							
							switch(storeKhmerInMemBlock6Byte(temp,memBlock, blockSize, lastFoundKHashVal[ii], buf[addResult],ii)){

								case MEM_BLOCK:
									mem_block_occupied_stat++;
									mem_block_total_number_of_occupied++;
									lastHashFuncUsed = ii;
									stored = true;
									break;
								case MEM_BLOCK_FOUND:
									//cout<<"mem_block_found:: "<<temp<<endl;
									mem_block_found_stat++;
									mem_block_total_number_of_occupied++;
									lastHashFuncUsed = ii;
									stored=true;
									break;
								case LIST:
									list_occupied_stat++;
									vector_total_number_of_occupied++;
									lastHashFuncUsed = ii;
									stored = true;
									break;
								case LIST_FOUND:
									//cout<<"list_found:: "<<temp<<endl;
									list_occupied_found++;
									vector_total_number_of_occupied++;
									lastHashFuncUsed = ii;
									stored=true;
									break;
								case ERROR:
									//std::cout<<"ERROR OCCURED"<<std::endl;
									break;
								
							}

							if(stored == true){
								//if stored then just end the loop
								break;
							}
							
							//for debug purpose
							//std::cout<<"\tinside loop "<<std::endl;
							//std::cout<<"\t\t"<<temp<<std::endl;
						}
					}

				}

				//temp = temp.substr(1,khmerSize-1);//advance to next khmer one time of ahead
			}
		}

	//myfile.close();

	//spit out the stats
	std::cout<<"stat from consume function :: "<<std::endl
			<<"khmer in memBlock (distinct):: "<<mem_block_occupied_stat<<std::endl
			<<"khmer in list (distinct):: "<<list_occupied_stat<<std::endl<<std::endl;
			/*<<"khmer in memBlock (found):: "<<mem_block_found_stat<<std::endl
			<<"khmer in list (found):: "<<list_occupied_found<<std::endl<<std::endl
			<<"Khmer in memBlock(total) "<<mem_block_total_number_of_occupied<<std::endl
			<<"khmer in vector(total) "<<vector_total_number_of_occupied<<endl;*/
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x358, %rsp            # imm = 0x358
movl %ecx, %ebx
movq %rdx, %r15
movq %rsi, 0x78(%rsp)
movq %rdi, 0x70(%rsp)
leaq 0x150(%rsp), %r14
movq %r14, %rdi
callq 0x22b0
pushq $0x8
popq %rdx
movq %r14, %rdi
movq %r15, %rsi
callq 0x2140
leaq 0x50(%rsp), %rax
movq %rax, -0x10(%rax)
andq $0x0, -0x8(%rax)
movb $0x0, (%rax)
leaq 0x37ec(%rip), %rsi      # 0x85c8
leaq 0x88(%rsp), %rdi
leaq 0xa8(%rsp), %rdx
callq 0x421e
leaq 0x649c(%rip), %rax      # 0xb294
movl (%rax), %edi
incl %edi
shlq $0x3, %rdi
callq 0x2030
movq %rax, 0x28(%rsp)
movq 0x150(%rsp), %rax
movq -0x18(%rax), %rax
testb $0x5, 0x170(%rsp,%rax)
je 0x4e43
movq 0x61a9(%rip), %rdi      # 0xafd0
leaq 0x32bb(%rip), %rsi      # 0x80e9
callq 0x2220
movq %rax, %rdi
movq %r15, %rsi
callq 0x2220
jmp 0x5379
movq 0x6186(%rip), %rdi      # 0xafd0
leaq 0x32aa(%rip), %rsi      # 0x80fb
callq 0x2220
movq %rax, %rdi
movq %r15, %rsi
callq 0x2220
movq %rax, %rdi
callq 0x20e0
movzwl %bx, %r15d
movq $0x0, 0x68(%rsp)
movl $0x0, 0xc(%rsp)
movq $0x0, 0x38(%rsp)
movq $0x0, 0x30(%rsp)
movq %r15, 0x18(%rsp)
movb $0x1, %al
xorl %ebp, %ebp
movl %eax, %r13d
leaq 0x150(%rsp), %rdi
leaq 0x40(%rsp), %rsi
callq 0x2050
movq (%rax), %rcx
movq -0x18(%rcx), %rcx
testb $0x5, 0x20(%rax,%rcx)
jne 0x5316
movq 0x40(%rsp), %rax
cmpb $0x3e, (%rax)
je 0x5261
testb $0x1, %bpl
jne 0x4e9c
leaq 0x88(%rsp), %rdi
leaq 0x40(%rsp), %rsi
callq 0x2460
leaq 0x40(%rsp), %rdi
movq %rax, %rsi
callq 0x2100
movl 0x48(%rsp), %eax
testb $0x1, %r13b
je 0x5047
cmpl %r15d, %eax
jb 0x4e9c
movl %eax, 0x14(%rsp)
leaq 0xa8(%rsp), %rbx
movq %rbx, %rdi
leaq 0x40(%rsp), %rsi
xorl %edx, %edx
movq %r15, %rcx
callq 0x2270
leaq 0x88(%rsp), %rdi
movq %rbx, %rsi
callq 0x22e0
movq %rbx, %rdi
callq 0x20c0
cmpl %r15d, 0x14(%rsp)
jbe 0x5060
xorl %ebx, %ebx
leaq 0x6344(%rip), %rax      # 0xb294
movl (%rax), %eax
cmpq %rax, %rbx
ja 0x5060
leaq 0x130(%rsp), %rdi
leaq 0x88(%rsp), %rsi
callq 0x2340
leaq 0x130(%rsp), %r12
movq %r12, %rdi
movl %ebx, %esi
callq 0x76af
movq %rax, %r14
movq 0x28(%rsp), %rax
movq %r14, (%rax,%rbx,8)
movq %r12, %rdi
callq 0x20c0
cmpq %r15, 0x48(%rsp)
jbe 0x4fbe
movq 0x40(%rsp), %rax
movsbl (%rax,%r15), %edi
callq 0x2430
addl $-0x41, %eax
cmpl $0x13, %eax
ja 0x502f
movl $0x80045, %ecx          # imm = 0x80045
btl %eax, %ecx
jae 0x502f
leaq 0x62f3(%rip), %rax      # 0xb2b8
cmpl $0x7, (%rax)
je 0x503c
leaq 0x110(%rsp), %rdi
leaq 0x88(%rsp), %rsi
callq 0x2340
movq 0x40(%rsp), %rax
movsbl (%rax,%r15), %r8d
movq 0x70(%rsp), %rsi
movq 0x78(%rsp), %rdx
movq %r14, %rcx
movl %ebx, %r9d
callq 0x4a9b
movl %eax, %r14d
leaq 0x110(%rsp), %rdi
callq 0x20c0
cmpl $0x6, %r14d
ja 0x5027
movl %r14d, %eax
leaq 0x3442(%rip), %rcx      # 0x8460
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
incq %rbx
jmp 0x4f49
leaq 0x6282(%rip), %rax      # 0xb2b8
movl $0x7, (%rax)
movb $0x1, %bpl
xorl %r13d, %r13d
jmp 0x4e9c
movl %eax, 0x14(%rsp)
movl %r13d, %eax
jmp 0x5062
incq 0x30(%rsp)
jmp 0x505c
incq 0x38(%rsp)
movl %ebx, 0xc(%rsp)
xorl %eax, %eax
movl %eax, 0x24(%rsp)
andb $0x1, %r13b
movzbl %r13b, %ecx
movl 0x14(%rsp), %eax
subl 0x18(%rsp), %eax
movl %eax, 0x64(%rsp)
movl %ebp, %eax
andb $0x1, %al
movq %rcx, 0x80(%rsp)
cmpl 0x64(%rsp), %ecx
ja 0x5253
testb %al, %al
jne 0x5253
movq 0x80(%rsp), %r15
movl %r15d, %edx
leaq 0xa8(%rsp), %r14
movq %r14, %rdi
leaq 0x40(%rsp), %rsi
movq 0x18(%rsp), %rbx
movq %rbx, %rcx
callq 0x2270
leaq 0x88(%rsp), %rdi
movq %r14, %rsi
callq 0x22e0
movq %r14, %rdi
callq 0x20c0
leal (%r15,%rbx), %eax
cmpl 0x14(%rsp), %eax
jae 0x5232
movl %ebp, 0x10(%rsp)
leal 0x1(%rax), %r12d
movl %eax, %r13d
movl 0xc(%rsp), %ebp
xorl %ebx, %ebx
leaq 0x6196(%rip), %rax      # 0xb294
movl (%rax), %eax
cmpq %rax, %rbx
ja 0x522e
cmpq %rbp, %rbx
jbe 0x514b
leaq 0xf0(%rsp), %rdi
leaq 0x88(%rsp), %rsi
callq 0x2340
leaq 0xf0(%rsp), %r15
movq %r15, %rdi
movl %ebx, %esi
callq 0x76af
movq %rax, %r14
movq 0x28(%rsp), %rax
movq %r14, (%rax,%rbx,8)
movq %r15, %rdi
callq 0x20c0
jmp 0x5179
movq 0x28(%rsp), %rax
movq (%rax,%rbx,8), %rdi
movq 0x88(%rsp), %rax
movq 0x18(%rsp), %rdx
movsbl -0x1(%rax,%rdx), %esi
movl %ebx, %ecx
callq 0x7760
movq %rax, %r14
movq 0x28(%rsp), %rax
movq %r14, (%rax,%rbx,8)
cmpq %r12, 0x48(%rsp)
jb 0x51a9
movq 0x40(%rsp), %rax
movsbl (%rax,%r13), %edi
callq 0x2430
addl $-0x41, %eax
cmpl $0x13, %eax
ja 0x5241
movl $0x80045, %ecx          # imm = 0x80045
btl %eax, %ecx
jae 0x5241
leaq 0x6108(%rip), %rax      # 0xb2b8
cmpl $0x7, (%rax)
je 0x524e
leaq 0xd0(%rsp), %rdi
leaq 0x88(%rsp), %rsi
callq 0x2340
movq 0x40(%rsp), %rax
movsbl (%rax,%r13), %r8d
movq 0x70(%rsp), %rsi
movq 0x78(%rsp), %rdx
movq %r14, %rcx
movl %ebx, %r9d
callq 0x4a9b
movl %eax, %r14d
leaq 0xd0(%rsp), %rdi
callq 0x20c0
cmpl $0x6, %r14d
ja 0x5216
movl %r14d, %eax
leaq 0x326f(%rip), %rcx      # 0x847c
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
incq %rbx
jmp 0x50f7
incq 0x30(%rsp)
jmp 0x522a
incq 0x38(%rsp)
movl %ebx, 0xc(%rsp)
movl 0x10(%rsp), %ebp
movq 0x80(%rsp), %rcx
incl %ecx
jmp 0x507a
leaq 0x6070(%rip), %rax      # 0xb2b8
movl $0x7, (%rax)
movb $0x1, %bpl
jmp 0x5232
movq 0x18(%rsp), %r15
movl 0x24(%rsp), %eax
jmp 0x4e99
leaq 0x88(%rsp), %rdi
leaq 0x3358(%rip), %rsi      # 0x85c8
callq 0x2450
movq 0x68(%rsp), %rax
incq %rax
movq %rax, 0x68(%rsp)
xorl %edx, %edx
movl $0xf4240, %ecx          # imm = 0xF4240
divq %rcx
testq %rdx, %rdx
jne 0x4e95
movq 0x5d34(%rip), %rdi      # 0xafd0
movq %rax, %rsi
callq 0x2160
movq %rax, %rdi
leaq 0x2e5b(%rip), %rsi      # 0x8109
callq 0x2220
movq %rax, %rdi
callq 0x20e0
callq 0x7610
leaq 0xa8(%rsp), %rdi
leaq 0xc8(%rsp), %rsi
callq 0x6f54
movq 0x5cf4(%rip), %rdi      # 0xafd0
leaq 0x2e40(%rip), %rsi      # 0x8123
callq 0x2220
movsd 0xa8(%rsp), %xmm0
movsd 0x2d17(%rip), %xmm1     # 0x8010
mulsd %xmm1, %xmm0
mulsd %xmm1, %xmm0
movq %rax, %rdi
callq 0x23c0
movq %rax, %rdi
callq 0x20e0
jmp 0x4e95
movq 0x5cb3(%rip), %rdi      # 0xafd0
leaq 0x2e13(%rip), %rsi      # 0x8137
callq 0x2220
movq %rax, %rdi
callq 0x20e0
leaq 0x2e1e(%rip), %rsi      # 0x8156
movq %rax, %rdi
callq 0x2220
movq %rax, %rdi
movq 0x38(%rsp), %rsi
callq 0x2170
movq %rax, %rdi
callq 0x20e0
leaq 0x2e1a(%rip), %rsi      # 0x8176
movq %rax, %rdi
callq 0x2220
movq %rax, %rdi
movq 0x30(%rsp), %rsi
callq 0x2170
movq %rax, %rdi
callq 0x20e0
movq %rax, %rdi
callq 0x20e0
leaq 0x88(%rsp), %rdi
callq 0x20c0
leaq 0x40(%rsp), %rdi
callq 0x20c0
leaq 0x150(%rsp), %rdi
callq 0x2070
addq $0x358, %rsp            # imm = 0x358
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0x540a
jmp 0x540a
jmp 0x540a
jmp 0x540a
movq %rax, %rbx
jmp 0x541a
movq %rax, %rbx
jmp 0x5424
movq %rax, %rbx
leaq 0x110(%rsp), %rdi
jmp 0x5403
movq %rax, %rbx
leaq 0x130(%rsp), %rdi
jmp 0x5403
jmp 0x540a
jmp 0x540a
jmp 0x540a
movq %rax, %rbx
leaq 0xf0(%rsp), %rdi
jmp 0x5403
jmp 0x540a
movq %rax, %rbx
leaq 0xd0(%rsp), %rdi
callq 0x20c0
jmp 0x540d
movq %rax, %rbx
leaq 0x88(%rsp), %rdi
callq 0x20c0
leaq 0x40(%rsp), %rdi
callq 0x20c0
leaq 0x150(%rsp), %rdi
callq 0x2070
movq %rbx, %rdi
callq 0x2400