// File: /workspace/github_cpp_makefile_star2_O3/Mengjintao[P]SWAPCounter/src/kmerGraph.cpp
// Function: kmerGraph::addKmers(char const*, char const*, unsigned long long*, unsigned char*, parameter*)
long long kmerGraph::addKmers(const char *s, const char *end, unsigned long long *kmers, unsigned char *arcs, parameter *parameters)
{
//	if(s>end || end-s <= parameters->hashLength)	return 0;
	unsigned long long curNodeID=0,     primeNodeID=0,   	twinNodeID=0;
	unsigned long long preNodeID=0,     prePrimeNodeID=0; 
	unsigned long long kmer_index=0;
//	for(int i=0; i<end-s; i++)	printf("%c", *(s+i));
//	printf("\n");
	
	curNodeID = this->stringToLongLong(s, 0, parameters->hashLength-1, parameters);
        for(int j=parameters->hashLength-1; s+j<end; j++) 
	{
		if(!(s[j]=='A'||s[j]=='T'||s[j]=='C'||s[j]=='G'))	continue;	
		assert(s[j]=='A'||s[j]=='T'||s[j]=='C'||s[j]=='G');
	       	curNodeID <<= 2;
               	curNodeID |= (parameters->nucleotideValue[(int) s[j]]&(3ull));
               	curNodeID &= parameters->MASK;
		
               	twinNodeID  = this->reverseComplement(curNodeID, parameters);
               	primeNodeID = max(curNodeID, twinNodeID);
//		cout<<longLongToString(curNodeID, parameters)<<" "<<longLongToString(primeNodeID, parameters)<<endl;
	
		if(j-parameters->hashLength+1==0)	{
			preNodeID = curNodeID;
			prePrimeNodeID = primeNodeID; 
			kmers[kmer_index] = primeNodeID;	arcs[kmer_index] = 0;
			kmer_index ++;
			continue;
		}
		kmers[kmer_index]  = primeNodeID;	arcs[kmer_index]  = 0;

		int pos_ret;
		//preNode -> curNode  add(A, B, +, +, last(B+))
		if( preNodeID == prePrimeNodeID && curNodeID == primeNodeID)
		{
			pos_ret = arcPos(prePrimeNodeID, primeNodeID, '+', '+', parameters->hashLength);	
			assert(kmer_index-1>=0);
			arcs[kmer_index-1] |= ((unsigned char) 1<<pos_ret);
				
			pos_ret = arcPos(primeNodeID, prePrimeNodeID, '-', '-', parameters->hashLength); 
			arcs[kmer_index] |=  ((unsigned char) 1<<pos_ret);
		}
		//preNode -> ~curNode
		else if(preNodeID == prePrimeNodeID && curNodeID != primeNodeID)
		{
			pos_ret = arcPos(prePrimeNodeID, primeNodeID, '+', '-', parameters->hashLength);	
			assert(kmer_index-1>=0);
			arcs[kmer_index-1] |= ((unsigned char) 1<<pos_ret);
				
			pos_ret = arcPos(primeNodeID, prePrimeNodeID, '+', '-', parameters->hashLength); 
			arcs[kmer_index] |= ((unsigned char) 1<<pos_ret);
		}
		//~preNode -> curNode
		else if(preNodeID != prePrimeNodeID && curNodeID == primeNodeID)
		{
			pos_ret = arcPos(prePrimeNodeID, primeNodeID, '-', '+', parameters->hashLength);	
			assert(kmer_index-1>=0);
			arcs[kmer_index-1] |= ((unsigned char) 1<<pos_ret);
				
			pos_ret = arcPos(primeNodeID, prePrimeNodeID, '-', '+', parameters->hashLength); 
			arcs[kmer_index] |= ((unsigned char) 1<<pos_ret);
		}			
		//~preNode -> ~curNode
		else if(preNodeID != prePrimeNodeID && curNodeID != primeNodeID)
		{
			pos_ret = arcPos(prePrimeNodeID, primeNodeID, '-', '-', parameters->hashLength);	
			assert(kmer_index-1>=0);
			arcs[kmer_index-1] |= ((unsigned char) 1<<pos_ret);
				
			pos_ret = arcPos(primeNodeID, prePrimeNodeID, '+', '+', parameters->hashLength); 
			arcs[kmer_index] |=  ((unsigned char) 1<<pos_ret);
		}
		preNodeID = curNodeID;
		prePrimeNodeID = primeNodeID;
		kmer_index++;
	}
	return (long long int) kmer_index;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
pushq %rax
movq %r9, %rbx
movq %r8, %r14
movq %rcx, %r15
movq %rdx, %r12
movq %rsi, %r13
movl 0xaf8(%r9), %edx
decl %edx
xorl %ebp, %ebp
movq %rsi, %rdi
xorl %esi, %esi
movq %r9, %rcx
callq 0x262e
movslq 0xaf8(%rbx), %rsi
leaq (%rsi,%r13), %rcx
decq %rcx
cmpq %r12, %rcx
jae 0x29e9
movq %rax, %rdi
decq %rsi
xorl %ebp, %ebp
xorl %r9d, %r9d
xorl %edx, %edx
movzbl (%rcx), %ecx
leal -0x41(%rcx), %r8d
cmpl $0x13, %r8d
ja 0x2975
movl $0x80045, %eax          # imm = 0x80045
btl %r8d, %eax
jae 0x2975
movzbl 0xb38(%rbx,%rcx), %ecx
andl $0x3, %ecx
leaq (%rcx,%rdi,4), %rdi
andq 0xb00(%rbx), %rdi
movl 0xaf8(%rbx), %r10d
testl %r10d, %r10d
jle 0x28c8
movl %r10d, %r8d
xorl %ecx, %ecx
movq %rdi, %rax
movl %eax, %r11d
andl $0x3, %r11d
leaq (%r11,%rcx,4), %rcx
xorq $0x3, %rcx
shrq $0x2, %rax
decl %r8d
jne 0x28ae
jmp 0x28ca
xorl %ecx, %ecx
cmpq %rcx, %rdi
movq %rcx, %r8
cmovaq %rdi, %r8
movl %esi, %eax
subl %r10d, %eax
movq %r8, (%r15,%rbp,8)
movb $0x0, (%r14,%rbp)
cmpl $-0x1, %eax
je 0x29cd
cmpq %rdx, %r9
jne 0x293b
cmpq %rcx, %rdi
jae 0x297a
movb 0xaf8(%rbx), %cl
addb %cl, %cl
addb $-0x2, %cl
movq %r8, %rax
shrq %cl, %rax
movl $0x3, %ecx
subl %eax, %ecx
cmpl $0x8, %ecx
jae 0x29fb
movl $0x1, %eax
shll %cl, %eax
orb %al, -0x1(%r14,%rbp)
movb 0xaf8(%rbx), %cl
addb %cl, %cl
addb $-0x2, %cl
shrq %cl, %r9
movl $0x3, %ecx
jmp 0x299c
cmpq %rcx, %rdi
jae 0x29af
movb 0xaf8(%rbx), %cl
addb %cl, %cl
addb $-0x2, %cl
movq %r8, %rax
shrq %cl, %rax
movl $0x7, %ecx
subl %eax, %ecx
cmpl $0x8, %ecx
jae 0x29fb
movl $0x1, %eax
shll %cl, %eax
orb %al, -0x1(%r14,%rbp)
andb $0x3, %dl
movb $0x1, %r9b
jmp 0x29c4
movq %rdx, %r8
jmp 0x29d3
movl %r8d, %ecx
andb $0x3, %cl
movb $0x1, %al
shlb %cl, %al
orb %al, -0x1(%r14,%rbp)
movb 0xaf8(%rbx), %cl
addb %cl, %cl
addb $-0x2, %cl
shrq %cl, %r9
movl $0x7, %ecx
subl %r9d, %ecx
cmpl $0x8, %ecx
jae 0x29fb
movl $0x1, %r9d
shll %cl, %r9d
jmp 0x29c9
movl %r8d, %ecx
andb $0x3, %cl
movb $0x10, %al
shlb %cl, %al
orb %al, -0x1(%r14,%rbp)
andb $0x3, %dl
movb $0x10, %r9b
movl %edx, %ecx
shlb %cl, %r9b
movb %r9b, (%r14,%rbp)
incq %rbp
movq %rdi, %r9
leaq (%rsi,%r13), %rcx
incq %rcx
incq %rsi
movq %r8, %rdx
cmpq %r12, %rcx
jb 0x2864
movq %rbp, %rax
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x36ae(%rip), %rdi      # 0x60b0
leaq 0x363a(%rip), %rsi      # 0x6043
leaq 0x36b2(%rip), %rcx      # 0x60c2
movl $0x30, %edx
callq 0x2170