// File: /workspace/github_cpp_makefile_star2_O2/ChnMasterOG[P]KmerGO2/kmc_api/kmc_file.cpp
// Function: CKMCFile::GetSuperKmers(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, std::vector<std::tuple<unsigned int, unsigned int, unsigned int>, std::allocator<std::tuple<unsigned int, unsigned int, unsigned int>>>&)
void CKMCFile::GetSuperKmers(const std::string& transformed_read, super_kmers_t& super_kmers)
{
	uint32 i = 0;
	uint32 len = 0; //length of super k-mer
	uint32 signature_start_pos;
	CMmer current_signature(signature_len), end_mmer(signature_len);

	while (i + kmer_length - 1 < transformed_read.length())
	{
		bool contains_N = false;
		//building first signature after 'N' or at the read beginning
		for (uint32 j = 0; j < signature_len; ++j, ++i)
		{
			if (transformed_read[i] < 0)//'N'
			{
				contains_N = true;
				break;
			}
		}
		//signature must be shorter than k-mer so if signature contains 'N', k-mer will contains it also
		if (contains_N)
		{
			++i;
			continue;
		}
		len = signature_len;
		signature_start_pos = i - signature_len;
		current_signature.insert(transformed_read.c_str() + signature_start_pos);
		end_mmer.set(current_signature);

		for (; i < transformed_read.length(); ++i)
		{
			if (transformed_read[i] < 0)//'N'
			{
				if (len >= kmer_length)
				{
					super_kmers.push_back(std::make_tuple(i - len, len, signature_map[current_signature.get()]));
				}
				len = 0;
				++i;
				break;
			}
			end_mmer.insert(transformed_read[i]);
			if (end_mmer < current_signature)//signature at the end of current k-mer is lower than current
			{
				if (len >= kmer_length)
				{
					super_kmers.push_back(std::make_tuple(i - len, len, signature_map[current_signature.get()]));
					len = kmer_length - 1;
				}
				current_signature.set(end_mmer);
				signature_start_pos = i - signature_len + 1;
			}
			else if (end_mmer == current_signature)
			{
				current_signature.set(end_mmer);
				signature_start_pos = i - signature_len + 1;
			}
			else if (signature_start_pos + kmer_length - 1 < i)//need to find new signature
			{
				super_kmers.push_back(std::make_tuple(i - len, len, signature_map[current_signature.get()]));
				len = kmer_length - 1;
				//looking for new signature
				++signature_start_pos;
				//building first signature in current k-mer
				end_mmer.insert(transformed_read.c_str() + signature_start_pos);
				current_signature.set(end_mmer);
				for (uint32 j = signature_start_pos + signature_len; j <= i; ++j)
				{
					end_mmer.insert(transformed_read[j]);
					if (end_mmer <= current_signature)
					{
						current_signature.set(end_mmer);
						signature_start_pos = j - signature_len + 1;
					}
				}
			}
			++len;
		}
	}
	if (len >= kmer_length)//last one in read
	{
		super_kmers.push_back(std::make_tuple(i - len, len, signature_map[current_signature.get()]));
	}
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x58, %rsp
movq %rdx, %rbx
movq %rsi, %r15
movq %rdi, %r14
movl 0x88(%rdi), %esi
leaq 0x30(%rsp), %rdi
callq 0x40fd44
movl 0x88(%r14), %esi
leaq 0x10(%rsp), %rdi
callq 0x40fd44
xorl %eax, %eax
xorl %r13d, %r13d
movq %rbx, 0x50(%rsp)
movl 0x78(%r14), %ecx
movl 0x88(%r14), %r12d
movq (%r15), %rsi
movq 0x8(%r15), %rdx
movl %r13d, %ebp
leal (%rcx,%rbp), %edi
decl %edi
cmpq %rdi, %rdx
jbe 0x4122f8
xorl %edi, %edi
cmpl %edi, %r12d
je 0x41211e
leal (%rdi,%rbp), %r8d
movl %r8d, %r8d
cmpb $0x0, (%rsi,%r8)
js 0x412118
incl %edi
jmp 0x412101
addl %edi, %ebp
incl %ebp
jmp 0x4120f1
leal (%r12,%rbp), %r13d
movl %ebp, %eax
addq %rax, %rsi
leaq 0x30(%rsp), %rdi
callq 0x41251e
movl 0x30(%rsp), %eax
movl 0x38(%rsp), %ecx
movl %eax, 0x10(%rsp)
movl %ecx, 0x18(%rsp)
movl %r13d, %edx
cmpq %rdx, 0x8(%r15)
jbe 0x4122b9
movq (%r15), %rsi
movsbl (%rsi,%rdx), %esi
movl %ecx, %edx
testl %esi, %esi
js 0x4122c1
leal (%rsi,%rax,4), %eax
andl 0x14(%rsp), %eax
movl %eax, 0x10(%rsp)
movq 0x20(%rsp), %rsi
movl (%rsi,%rax,4), %esi
movl %esi, 0x18(%rsp)
cmpl %ecx, %esi
jae 0x4121d1
cmpl 0x78(%r14), %r12d
jb 0x4121b6
movl %r13d, %eax
subl %r12d, %eax
movq 0x50(%r14), %rcx
movl (%rcx,%rdx,4), %ecx
movl %ecx, 0x4(%rsp)
movl %r12d, 0x8(%rsp)
movl %eax, 0xc(%rsp)
movq %rbx, %rdi
leaq 0x4(%rsp), %rsi
callq 0x412ab4
movl 0x78(%r14), %r12d
decl %r12d
movl 0x10(%rsp), %eax
movl 0x18(%rsp), %esi
movl %eax, 0x30(%rsp)
movl %esi, 0x38(%rsp)
movl %r13d, %ebp
subl 0x88(%r14), %ebp
incl %ebp
movl %esi, %ecx
jmp 0x4122ae
jne 0x4121ec
movl %eax, 0x30(%rsp)
movl %ecx, 0x38(%rsp)
movl %r13d, %ebp
subl 0x88(%r14), %ebp
incl %ebp
jmp 0x4122ae
movl 0x78(%r14), %esi
addl %ebp, %esi
decl %esi
cmpl %r13d, %esi
jae 0x4122ae
movl %r13d, %eax
subl %r12d, %eax
movq 0x50(%r14), %rcx
movl (%rcx,%rdx,4), %ecx
movl %ecx, 0x4(%rsp)
movl %r12d, 0x8(%rsp)
movl %eax, 0xc(%rsp)
movq %rbx, %rdi
leaq 0x4(%rsp), %rsi
callq 0x412ab4
movl 0x78(%r14), %r12d
leal 0x1(%rbp), %ebx
movq (%r15), %rsi
addq %rbx, %rsi
leaq 0x10(%rsp), %rdi
callq 0x41251e
movl 0x10(%rsp), %eax
movl 0x14(%rsp), %edx
movl %eax, 0x30(%rsp)
movl 0x18(%rsp), %ecx
movl %ecx, 0x38(%rsp)
movl 0x88(%r14), %esi
movq (%r15), %rdi
movq 0x20(%rsp), %r8
addl $0x2, %ebp
movl %ebp, %r9d
movl %ebx, %ebp
leal (%rsi,%r9), %r10d
decl %r10d
cmpl %r13d, %r10d
ja 0x4122a6
movl %r10d, %r10d
movzbl (%rdi,%r10), %r10d
leal (%r10,%rax,4), %eax
andl %edx, %eax
movl %eax, 0x10(%rsp)
movl (%r8,%rax,4), %r10d
movl %r10d, 0x18(%rsp)
cmpl %ecx, %r10d
ja 0x4122a1
movl %eax, 0x30(%rsp)
movl %r10d, 0x38(%rsp)
movl %r10d, %ecx
movl %r9d, %ebp
incl %r9d
jmp 0x412266
decl %r12d
movq 0x50(%rsp), %rbx
incl %r12d
incl %r13d
jmp 0x412141
movl %r12d, %eax
jmp 0x4120dc
cmpl 0x78(%r14), %r12d
jb 0x4122ee
movl %r13d, %eax
subl %r12d, %eax
movq 0x50(%r14), %rcx
movl (%rcx,%rdx,4), %ecx
movl %ecx, 0x4(%rsp)
movl %r12d, 0x8(%rsp)
movl %eax, 0xc(%rsp)
movq %rbx, %rdi
leaq 0x4(%rsp), %rsi
callq 0x412ab4
incl %r13d
xorl %eax, %eax
jmp 0x4120dc
cmpl %ecx, %eax
jb 0x41231e
subl %eax, %ebp
movq 0x50(%r14), %rcx
movl 0x38(%rsp), %edx
movl (%rcx,%rdx,4), %ecx
leaq 0x4(%rsp), %rsi
movl %ecx, (%rsi)
movl %eax, 0x4(%rsi)
movl %ebp, 0x8(%rsi)
movq %rbx, %rdi
callq 0x412ab4
addq $0x58, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
nop