// File: /workspace/github_cpp_makefile_star2_O3/giovannarosone[P]BCR_LCP_GSA/BCRexternalBWT.cpp
// Function: BCRexternalBWT::storeEntireBWTFilePartial(char const*)
void BCRexternalBWT::storeEntireBWTFilePartial( const char* fn ) {

	static FILE *OutFileBWT, *InFileBWT;                  // output and input file BWT;
	char *filenameIn = new char[strlen(fn)+100];
	char *filename = new char[strlen(fn)+100];
	
	#if USE_QS == 1
		static FILE *OutFileBWTQS, *InFileBWTQS;                  // output and input file BWT;
		char *filenameInQS = new char[120];
		char *filenameQS = new char[120];
		char *fnQS = new char[strlen(fn)+100];
		sprintf (fnQS,"%s%s",fn,".ebwt.qs");
	#endif
	
	dataTypeNChar numchar=0;
	dataTypeNChar numcharWrite=0;

	uchar *buffer = new uchar[SIZEBUFFER];
	std::cerr << "storeEntireBWTFilePartial:SIZEBUFFER is " << SIZEBUFFER << std::endl;

	dataTypeNChar *freqOut = new dataTypeNChar [SIZE_ALPHA];
	for (dataTypedimAlpha i = 0; i < SIZE_ALPHA-1; ++i)
        freqOut[i] = 0;
	freqOut[SIZE_ALPHA-1] = 0;

	char *fnBWT = new char[strlen(fn)+100];
	numchar=sprintf (fnBWT,"%s%s",fn,".ebwt");		
	OutFileBWT = fopen(fnBWT, "wb");
	if (OutFileBWT==NULL) {
		std::cerr << "storeEntireBWTFilePartial: Entire BWT file: Error opening " << std::endl;
		exit (EXIT_FAILURE);
	}
	
	#if USE_QS == 1
		OutFileBWTQS = fopen(fnQS, "wb");
		if (OutFileBWTQS==NULL) {
			std::cerr << "storeEntireBWTFilePartial: Entire BWT QS file: Error opening " << std::endl;
			exit (EXIT_FAILURE);
		}
	#endif

	std::cerr << "storeEntireBWTFilePartial: Build the entire BWT file and compute the distribution of chars.\n";

	for (dataTypedimAlpha g = 0 ; g < sizeAlpha; g++) {
		numchar=sprintf (filename, "bwt_%d", g);
		numchar=sprintf (filenameIn,"%s%s",filename,ext);
		InFileBWT = fopen(filenameIn, "rb");
		if (InFileBWT==NULL) {
			std::cerr << "storeEntireBWTFilePartial: BWT file " << (unsigned int)g <<": Error opening " << std::endl;
			exit (EXIT_FAILURE);
		}

		#if USE_QS == 1
			numchar=sprintf (filenameQS, "bwt.qs_%d", g);
			numchar=sprintf (filenameInQS,"%s%s",filenameQS,ext);
			InFileBWTQS = fopen(filenameInQS, "rb");
			if (InFileBWTQS==NULL) {
				std::cerr << "storeEntireBWTFilePartial: BWT QS file " << (unsigned int)g <<": Error opening " << std::endl;
				exit (EXIT_FAILURE);
			}
		#endif

		//std::cerr << "BWT file " << (unsigned int)g << "= ";
		numchar = fread(buffer,sizeof(uchar),SIZEBUFFER,InFileBWT);
		numcharWrite = fwrite (buffer, sizeof(uchar), numchar , OutFileBWT);
		//std::cerr << "numchar= " << numchar << std::endl;
		//std::cerr << "numcharWrite= " << numcharWrite << std::endl;
		assert(numchar == numcharWrite); // we should always read/write the same number of characters

		for (dataTypeNChar j = 0 ; j < numchar; j++)
	        freqOut[(unsigned int)(buffer[j])]++;

		#if USE_QS == 1
			numchar = fread(buffer,sizeof(uchar),SIZEBUFFER,InFileBWTQS);
			numcharWrite = fwrite (buffer, sizeof(uchar), numchar , OutFileBWTQS);
			assert(numchar == numcharWrite);
		#endif

		while (numchar!=0) {
			numchar = fread(buffer,sizeof(uchar),SIZEBUFFER,InFileBWT);
			numcharWrite = fwrite (buffer, sizeof(uchar), numchar , OutFileBWT);
			assert(numchar == numcharWrite); // we should always read/write the same number of characters

			for (dataTypeNChar j = 0 ; j < numchar; j++)
				freqOut[(unsigned int)(buffer[j])]++;
			
			#if USE_QS == 1
				numchar = fread(buffer,sizeof(uchar),SIZEBUFFER,InFileBWTQS);
				numcharWrite = fwrite (buffer, sizeof(uchar), numchar , OutFileBWTQS);
				assert(numchar == numcharWrite);
			#endif

		}

		fclose(InFileBWT);		
		#if USE_QS==1
			fclose(InFileBWTQS);
		#endif
			
	}
	fclose(OutFileBWT);

	#if verboseEncode==1
		std::cerr << "\nThe Entire BWT:"<< std::endl;
		fnBWT = new char[strlen(fn) + 7];
		sprintf (fnBWT,"%s%s",fn,".ebwt");
		OutFileBWT = fopen(fnBWT, "rb");
		if (OutFileBWT==NULL) {
			std::cerr << "storeEntireBWTFilePartial: Entire BWT file: Error opening " << std::endl;
			exit (EXIT_FAILURE);
		}

		numchar = 1;
		for (dataTypeNSeq g = 0 ; g < SIZEBUFFER; g++)
			buffer[g] = '\0';
		numchar = fread(buffer,sizeof(uchar),SIZEBUFFER,OutFileBWT);
   		if (numchar==0)
			   std::cerr  << "empty\n";
		else
			    std::cerr  << buffer;
       	while (numchar!=0) {
	     		for (dataTypeNChar g = 0 ; g < SIZEBUFFER; g++)
		     		buffer[g] = '\0';
			   numchar = fread(buffer,sizeof(uchar),SIZEBUFFER,OutFileBWT);
			   if (numchar!=0)
			      std::cerr  << buffer;
        }
		std::cerr << std::endl;
		fclose(OutFileBWT);
	#endif

	delete [] buffer;

	
	
	int check=0;
	std::cerr << "Distribution in BWT\n";
	for (dataTypedimAlpha g = 0 ; g < SIZE_ALPHA-1; g++) {
		if (freqOut[g] > 0){
			InFileBWT = openFilePartialIn(alpha[(unsigned int)g]);
			fseek(InFileBWT,0,SEEK_END);
			dataTypeNChar lengthBWTPartial=ftell(InFileBWT);
			if (freqOut[g] == lengthBWTPartial)
				std::cerr << (unsigned int)g << " freq: " << freqOut[g] << "\n";
			else {
				std::cerr << (unsigned int)g << " freq: " << freqOut[g] << " freq in BWT: " << lengthBWTPartial << "***********************\n";
				check = 1;
			}
			closeFilePartial(InFileBWT);
			
			#if deletePartialBWT == 1
				sprintf (filename, "bwt_%d", alpha[(unsigned int)g]);
				sprintf (filenameIn,"%s%s",filename,ext);
				if (remove(filenameIn)!=0)
					std::cerr << "storeEntireBWTFilePartial: Error deleting (bwt aux): " << filenameIn << std::endl;
			#endif
			
			#if ((deletePartialQS == 1) && (USE_QS==1))
				sprintf (filename, "bwt.qs_%d", alpha[(unsigned int)g]);
				sprintf (filenameInQS,"%s%s",filename,ext);
				if (remove(filenameInQS)!=0)
					std::cerr << "storeEntireBWTFilePartial: Error deleting (qs aux): " << filenameInQS << std::endl;
			#endif
			
		}
	}
	if (freqOut[(SIZE_ALPHA-1)] > 0){
		InFileBWT = openFilePartialIn(alpha[(unsigned int)(SIZE_ALPHA-1)]);
		fseek(InFileBWT,0,SEEK_END);
		dataTypeNChar lengthBWTPartial=ftell(InFileBWT);
		if (freqOut[(SIZE_ALPHA-1)] == lengthBWTPartial)
			std::cerr << (unsigned int)(SIZE_ALPHA-1) << " freq: " << freqOut[(SIZE_ALPHA-1)] << "\n";
		else {
			std::cerr << (unsigned int)(SIZE_ALPHA-1) << " freq: " << freqOut[(SIZE_ALPHA-1)] << " freq in BWT: " << lengthBWTPartial << "***********************\n";
			check = 1;
		}
		closeFilePartial(InFileBWT);
		#if deletePartialBWT == 1
			sprintf (filename, "bwt_%d", alpha[(unsigned int)(SIZE_ALPHA-1)] );
			sprintf (filenameIn,"%s%s",filename,ext);
			if (remove(filenameIn)!=0)
				std::cerr << "storeEntireBWTFilePartial: Error deleting (bwt aux): " << filenameIn << std::endl;
		#endif
		
		#if ((deletePartialQS == 1) && (USE_QS==1))
			sprintf (filename, "bwt.qs_%d", alpha[(unsigned int)SIZE_ALPHA-1]);
			sprintf (filenameInQS,"%s%s",filename,ext);
			if (remove(filenameInQS)!=0)
				std::cerr << "storeEntireBWTFilePartial: Error deleting (qs aux): " << filenameInQS << std::endl;
		#endif
		
	}

	if (check == 1) {
		std::cerr << "storeEntireBWTFilePartial: WARNING! Some length partial BWT != the number of occorrences! " << std::endl;
		exit (EXIT_FAILURE);
	}
	else
		std::cerr << "storeEntireBWTFilePartial: test ok! " << std::endl;

	delete [] freqOut;
	delete [] filenameIn;
	delete [] filename;

	#if USE_QS == 1
		delete [] filenameInQS;
		delete [] filenameQS;
		delete [] fnQS;
	#endif
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x18, %rsp
movq %rsi, %r13
movq %rdi, %r12
movq %rsi, %rdi
callq 0x3120
leaq 0x64(%rax), %rbx
movq %rbx, %rdi
callq 0x3040
movq %rax, 0x8(%rsp)
movq %rbx, %rdi
callq 0x3040
movq %rax, 0x10(%rsp)
movl $0x400, %edi            # imm = 0x400
callq 0x3040
movq %rax, %rbp
movq 0xaee0(%rip), %rbx      # 0x10ff0
leaq 0x6b40(%rip), %rsi      # 0xcc57
movl $0x28, %edx
movq %rbx, %rdi
callq 0x32d0
movq %rbx, %rdi
movl $0x400, %esi            # imm = 0x400
callq 0x3440
movq %rax, %rbx
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x3280
movsbl %al, %esi
movq %rbx, %rdi
callq 0x3050
movq %rax, %rdi
callq 0x31e0
movl $0x800, %edi            # imm = 0x800
callq 0x3040
movq %rax, %r15
movl $0x800, %edx            # imm = 0x800
movq %rax, %rdi
xorl %esi, %esi
callq 0x3170
movq %r13, %rdi
callq 0x3120
leaq 0x64(%rax), %rdi
callq 0x3040
movq %rax, %rbx
leaq 0x6972(%rip), %rsi      # 0xcb04
leaq 0x6a5c(%rip), %rcx      # 0xcbf5
movq %rax, %rdi
movq %r13, %rdx
xorl %eax, %eax
callq 0x3070
leaq 0x695c(%rip), %rsi      # 0xcb09
movq %rbx, %rdi
callq 0x32e0
movq %rax, 0xb10c(%rip)      # 0x112c8
movq 0xae2d(%rip), %rdi      # 0x10ff0
testq %rax, %rax
je 0x675e
leaq 0x6ae8(%rip), %rsi      # 0xccbb
movl $0x5c, %edx
callq 0x32d0
cmpb $0x0, 0x148(%r12)
movq 0x8(%rsp), %rbx
je 0x630e
xorl %r13d, %r13d
movq 0x10(%rsp), %r14
movq %r14, %rdi
leaq 0x6dc5(%rip), %rsi      # 0xcfc8
movl %r13d, %edx
xorl %eax, %eax
callq 0x3070
movq %rbx, %rdi
leaq 0x68ed(%rip), %rsi      # 0xcb04
movq %r14, %rdx
leaq 0x6836(%rip), %rcx      # 0xca57
xorl %eax, %eax
callq 0x3070
movq %rbx, %rdi
leaq 0x6721(%rip), %rsi      # 0xc953
callq 0x32e0
movq %rax, 0xb092(%rip)      # 0x112d0
testq %rax, %rax
je 0x6700
movl $0x1, %esi
movl $0x400, %edx            # imm = 0x400
movq %rbp, %rdi
movq %rax, %rcx
callq 0x3390
movq %rax, %r14
movq 0xb062(%rip), %rcx      # 0x112c8
movl $0x1, %esi
movq %rbp, %rdi
movq %rax, %rdx
callq 0x34c0
cmpq %rax, %r14
jne 0x673f
testq %r14, %r14
je 0x62ed
xorl %eax, %eax
movzbl (%rbp,%rax), %ecx
incq (%r15,%rcx,8)
incq %rax
cmpq %rax, %r14
jne 0x6286
jmp 0x62ac
xorl %eax, %eax
movzbl (%rbp,%rax), %ecx
incq (%r15,%rcx,8)
incq %rax
cmpq %rax, %r14
jne 0x629b
movq 0xb01d(%rip), %rcx      # 0x112d0
movl $0x1, %esi
movl $0x400, %edx            # imm = 0x400
movq %rbp, %rdi
callq 0x3390
movq %rax, %r14
movq 0xaff9(%rip), %rcx      # 0x112c8
movl $0x1, %esi
movq %rbp, %rdi
movq %rax, %rdx
callq 0x34c0
cmpq %rax, %r14
jne 0x66e1
testq %r14, %r14
jne 0x6299
movq 0xafdc(%rip), %rdi      # 0x112d0
callq 0x32a0
incl %r13d
movzbl 0x148(%r12), %eax
cmpl %eax, %r13d
jb 0x61f4
movq 0xafb3(%rip), %rdi      # 0x112c8
callq 0x32a0
movq %rbp, %rdi
callq 0x3330
leaq 0x6a59(%rip), %rsi      # 0xcd82
movl $0x14, %edx
movq 0xacbb(%rip), %rdi      # 0x10ff0
callq 0x32d0
xorl %ebp, %ebp
movl $0x0, 0x4(%rsp)
movq (%r15,%rbp,8), %r14
testq %r14, %r14
je 0x64c4
movzbl 0x48(%r12,%rbp), %esi
movq (%r12), %rax
movq %r12, %rdi
callq *0x70(%rax)
movq %rax, 0xaf68(%rip)      # 0x112d0
movq %rax, %rdi
xorl %esi, %esi
movl $0x2, %edx
callq 0x32c0
movq 0xaf52(%rip), %rdi      # 0x112d0
callq 0x3030
movq %rax, %r13
movq 0xac63(%rip), %rdi      # 0x10ff0
movq %rbp, %rsi
callq 0x31d0
movq %rax, %rbx
movl $0x7, %edx
movq %rax, %rdi
leaq 0x69f0(%rip), %rsi      # 0xcd97
callq 0x32d0
movq %rbx, %rdi
movq %r14, %rsi
callq 0x31d0
movq %rax, %rbx
cmpq %r13, %r14
jne 0x63d5
movl $0x1, %edx
movq %rbx, %rdi
leaq 0x6668(%rip), %rsi      # 0xca36
callq 0x32d0
jmp 0x6410
movl $0xe, %edx
movq %rbx, %rdi
leaq 0x69bb(%rip), %rsi      # 0xcd9f
callq 0x32d0
movq %rbx, %rdi
movq %r13, %rsi
callq 0x31d0
movl $0x18, %edx
movq %rax, %rdi
leaq 0x69ab(%rip), %rsi      # 0xcdae
callq 0x32d0
movl $0x1, 0x4(%rsp)
movq 0xaeb9(%rip), %rsi      # 0x112d0
movq (%r12), %rax
movq %r12, %rdi
callq *0x80(%rax)
movzbl 0x48(%r12,%rbp), %edx
movq 0x10(%rsp), %r14
movq %r14, %rdi
leaq 0x6b8f(%rip), %rsi      # 0xcfc8
xorl %eax, %eax
callq 0x3070
movq 0x8(%rsp), %rbx
movq %rbx, %rdi
leaq 0x66b5(%rip), %rsi      # 0xcb04
movq %r14, %rdx
leaq 0x65fe(%rip), %rcx      # 0xca57
xorl %eax, %eax
callq 0x3070
movq %rbx, %rdi
callq 0x3480
testl %eax, %eax
je 0x64c4
movl $0x35, %edx
movq 0xab78(%rip), %r14      # 0x10ff0
movq %r14, %rdi
leaq 0x6945(%rip), %rsi      # 0xcdc7
callq 0x32d0
movq %rbx, %rdi
callq 0x3120
movq %r14, %rdi
movq %rbx, %rsi
movq %rax, %rdx
callq 0x32d0
movq (%r14), %rax
movq -0x18(%rax), %rdi
addq %r14, %rdi
movl $0xa, %esi
callq 0x3280
movsbl %al, %esi
movq %r14, %rdi
callq 0x3050
movq %rax, %rdi
callq 0x31e0
incq %rbp
cmpq $0xff, %rbp
jne 0x6344
movq 0x7f8(%r15), %r14
testq %r14, %r14
je 0x6576
movzbl 0x147(%r12), %esi
movq (%r12), %rax
movq %r12, %rdi
callq *0x70(%rax)
movq %rax, 0xadd2(%rip)      # 0x112d0
movq %rax, %rdi
xorl %esi, %esi
movl $0x2, %edx
callq 0x32c0
movq 0xadbc(%rip), %rdi      # 0x112d0
callq 0x3030
movq %rax, %rbp
movq 0xaacd(%rip), %rdi      # 0x10ff0
movl $0xff, %esi
callq 0x31d0
movq %rax, %rbx
leaq 0x6860(%rip), %rsi      # 0xcd97
movl $0x7, %edx
movq %rax, %rdi
callq 0x32d0
movq %rbx, %rdi
movq %r14, %rsi
callq 0x31d0
movq %rax, %r13
cmpq %rbp, %r14
jne 0x657f
leaq 0x64d8(%rip), %rsi      # 0xca36
movl $0x1, %edx
movq %r13, %rdi
callq 0x32d0
movq 0x8(%rsp), %rbx
movl 0x4(%rsp), %ebp
jmp 0x65bc
movl 0x4(%rsp), %ebp
jmp 0x666e
leaq 0x6819(%rip), %rsi      # 0xcd9f
movl $0xe, %edx
movq %r13, %rdi
callq 0x32d0
movq %r13, %rdi
movq %rbp, %rsi
callq 0x31d0
leaq 0x6809(%rip), %rsi      # 0xcdae
movl $0x18, %edx
movq %rax, %rdi
callq 0x32d0
movl $0x1, %ebp
movq 0x8(%rsp), %rbx
movq 0xad0d(%rip), %rsi      # 0x112d0
movq (%r12), %rax
movq %r12, %rdi
callq *0x80(%rax)
movzbl 0x147(%r12), %edx
leaq 0x69e8(%rip), %rsi      # 0xcfc8
movq 0x10(%rsp), %r14
movq %r14, %rdi
xorl %eax, %eax
callq 0x3070
leaq 0x650e(%rip), %rsi      # 0xcb04
leaq 0x645a(%rip), %rcx      # 0xca57
movq %rbx, %rdi
movq %r14, %rdx
xorl %eax, %eax
callq 0x3070
movq %rbx, %rdi
callq 0x3480
testl %eax, %eax
je 0x666e
leaq 0x67aa(%rip), %rsi      # 0xcdc7
movl $0x35, %edx
movq 0xa9c7(%rip), %r14      # 0x10ff0
movq %r14, %rdi
callq 0x32d0
movq %rbx, %rdi
callq 0x3120
movq %r14, %rdi
movq %rbx, %rsi
movq %rax, %rdx
callq 0x32d0
movq (%r14), %rax
movq -0x18(%rax), %rdi
addq %r14, %rdi
movl $0xa, %esi
callq 0x3280
movsbl %al, %esi
movq %r14, %rdi
callq 0x3050
movq %rax, %rdi
callq 0x31e0
cmpl $0x1, %ebp
je 0x6767
leaq 0x67da(%rip), %rsi      # 0xce58
movl $0x24, %edx
movq 0xa966(%rip), %r14      # 0x10ff0
movq %r14, %rdi
callq 0x32d0
movq (%r14), %rax
movq -0x18(%rax), %rdi
addq %r14, %rdi
movl $0xa, %esi
callq 0x3280
movsbl %al, %esi
movq %r14, %rdi
callq 0x3050
movq %rax, %rdi
callq 0x31e0
movq %r15, %rdi
callq 0x3330
movq %rbx, %rdi
callq 0x3330
movq 0x10(%rsp), %rdi
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x3330
leaq 0x6492(%rip), %rdi      # 0xcb7a
leaq 0x5cee(%rip), %rsi      # 0xc3dd
leaq 0x6647(%rip), %rcx      # 0xcd3d
movl $0x1392, %edx           # imm = 0x1392
callq 0x31a0
movq 0xa8e9(%rip), %rdi      # 0x10ff0
leaq 0x660a(%rip), %rsi      # 0xcd18
callq 0x3290
movq %rax, %rdi
movl %r13d, %esi
callq 0x3350
leaq 0x623a(%rip), %rsi      # 0xc95f
movq %rax, %rdi
callq 0x3290
movq %rax, %rdi
callq 0x3140
movl $0x1, %edi
callq 0x3300
leaq 0x6434(%rip), %rdi      # 0xcb7a
leaq 0x5c90(%rip), %rsi      # 0xc3dd
leaq 0x65e9(%rip), %rcx      # 0xcd3d
movl $0x1384, %edx           # imm = 0x1384
callq 0x31a0
leaq 0x651b(%rip), %rsi      # 0xcc80
jmp 0x6728
movq 0xa882(%rip), %rdi      # 0x10ff0
leaq 0x6688(%rip), %rsi      # 0xcdfd
jmp 0x6728
nop