// File: 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
movq %rsp, %rbp
subq $0x110, %rsp            # imm = 0x110
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0xc0(%rbp)
movl $0x0, -0x1c(%rbp)
movl $0x0, -0x20(%rbp)
movl 0x88(%rax), %esi
leaq -0x48(%rbp), %rdi
callq 0x4233c0
movq -0xc0(%rbp), %rax
movl 0x88(%rax), %esi
leaq -0x68(%rbp), %rdi
callq 0x4233c0
movq -0xc0(%rbp), %rcx
movl -0x1c(%rbp), %eax
addl 0x78(%rcx), %eax
subl $0x1, %eax
movl %eax, %eax
movq %rax, -0xc8(%rbp)
movq -0x10(%rbp), %rdi
callq 0x49f200
movq %rax, %rcx
movq -0xc8(%rbp), %rax
cmpq %rcx, %rax
jae 0x428065
movb $0x0, -0x69(%rbp)
movl $0x0, -0x70(%rbp)
movq -0xc0(%rbp), %rcx
movl -0x70(%rbp), %eax
cmpl 0x88(%rcx), %eax
jae 0x427cb9
movq -0x10(%rbp), %rdi
movl -0x1c(%rbp), %eax
movl %eax, %esi
callq 0x49f500
movsbl (%rax), %eax
cmpl $0x0, %eax
jge 0x427ca3
movb $0x1, -0x69(%rbp)
jmp 0x427cb9
jmp 0x427ca5
movl -0x70(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x70(%rbp)
movl -0x1c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x1c(%rbp)
jmp 0x427c75
testb $0x1, -0x69(%rbp)
je 0x427ccd
movl -0x1c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x1c(%rbp)
jmp 0x427c35
movq -0xc0(%rbp), %rcx
movl 0x88(%rcx), %eax
movl %eax, -0x20(%rbp)
movl -0x1c(%rbp), %eax
subl 0x88(%rcx), %eax
movl %eax, -0x24(%rbp)
movq -0x10(%rbp), %rdi
callq 0x4a0a10
movq %rax, %rsi
movl -0x24(%rbp), %eax
addq %rax, %rsi
leaq -0x48(%rbp), %rdi
callq 0x428730
leaq -0x68(%rbp), %rdi
leaq -0x48(%rbp), %rsi
callq 0x428a80
movl -0x1c(%rbp), %eax
movq %rax, -0xd0(%rbp)
movq -0x10(%rbp), %rdi
callq 0x49f200
movq %rax, %rcx
movq -0xd0(%rbp), %rax
cmpq %rcx, %rax
jae 0x428060
movq -0x10(%rbp), %rdi
movl -0x1c(%rbp), %eax
movl %eax, %esi
callq 0x49f500
movsbl (%rax), %eax
cmpl $0x0, %eax
jge 0x427dd5
movq -0xc0(%rbp), %rcx
movl -0x20(%rbp), %eax
cmpl 0x78(%rcx), %eax
jb 0x427dc0
movq -0xc0(%rbp), %rax
movq -0x18(%rbp), %rcx
movq %rcx, -0xd8(%rbp)
movl -0x1c(%rbp), %ecx
subl -0x20(%rbp), %ecx
movl %ecx, -0x80(%rbp)
movq 0x50(%rax), %rax
movq %rax, -0xe0(%rbp)
leaq -0x48(%rbp), %rdi
callq 0x428b20
movq -0xe0(%rbp), %rcx
movl %eax, %eax
shlq $0x2, %rax
addq %rax, %rcx
leaq -0x7c(%rbp), %rdi
leaq -0x80(%rbp), %rsi
leaq -0x20(%rbp), %rdx
callq 0x428ae0
movq -0xd8(%rbp), %rdi
leaq -0x7c(%rbp), %rsi
callq 0x428ab0
movl $0x0, -0x20(%rbp)
movl -0x1c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x1c(%rbp)
jmp 0x428060
movq -0x10(%rbp), %rdi
movl -0x1c(%rbp), %eax
movl %eax, %esi
callq 0x49f500
leaq -0x68(%rbp), %rdi
movzbl (%rax), %esi
callq 0x428b40
leaq -0x68(%rbp), %rdi
leaq -0x48(%rbp), %rsi
callq 0x428b80
testb $0x1, %al
jne 0x427e05
jmp 0x427eb8
movq -0xc0(%rbp), %rcx
movl -0x20(%rbp), %eax
cmpl 0x78(%rcx), %eax
jb 0x427e90
movq -0xc0(%rbp), %rax
movq -0x18(%rbp), %rcx
movq %rcx, -0xe8(%rbp)
movl -0x1c(%rbp), %ecx
subl -0x20(%rbp), %ecx
movl %ecx, -0x90(%rbp)
movq 0x50(%rax), %rax
movq %rax, -0xf0(%rbp)
leaq -0x48(%rbp), %rdi
callq 0x428b20
movq -0xf0(%rbp), %rcx
movl %eax, %eax
shlq $0x2, %rax
addq %rax, %rcx
leaq -0x8c(%rbp), %rdi
leaq -0x90(%rbp), %rsi
leaq -0x20(%rbp), %rdx
callq 0x428ae0
movq -0xe8(%rbp), %rdi
leaq -0x8c(%rbp), %rsi
callq 0x428ab0
movq -0xc0(%rbp), %rax
movl 0x78(%rax), %eax
subl $0x1, %eax
movl %eax, -0x20(%rbp)
leaq -0x48(%rbp), %rdi
leaq -0x68(%rbp), %rsi
callq 0x428a80
movq -0xc0(%rbp), %rcx
movl -0x1c(%rbp), %eax
subl 0x88(%rcx), %eax
addl $0x1, %eax
movl %eax, -0x24(%rbp)
jmp 0x428049
leaq -0x68(%rbp), %rdi
leaq -0x48(%rbp), %rsi
callq 0x428bb0
testb $0x1, %al
jne 0x427ecb
jmp 0x427ef3
leaq -0x48(%rbp), %rdi
leaq -0x68(%rbp), %rsi
callq 0x428a80
movq -0xc0(%rbp), %rcx
movl -0x1c(%rbp), %eax
subl 0x88(%rcx), %eax
addl $0x1, %eax
movl %eax, -0x24(%rbp)
jmp 0x428047
movq -0xc0(%rbp), %rcx
movl -0x24(%rbp), %eax
addl 0x78(%rcx), %eax
subl $0x1, %eax
cmpl -0x1c(%rbp), %eax
jae 0x428045
movq -0xc0(%rbp), %rax
movq -0x18(%rbp), %rcx
movq %rcx, -0xf8(%rbp)
movl -0x1c(%rbp), %ecx
subl -0x20(%rbp), %ecx
movl %ecx, -0xa0(%rbp)
movq 0x50(%rax), %rax
movq %rax, -0x100(%rbp)
leaq -0x48(%rbp), %rdi
callq 0x428b20
movq -0x100(%rbp), %rcx
movl %eax, %eax
shlq $0x2, %rax
addq %rax, %rcx
leaq -0x9c(%rbp), %rdi
leaq -0xa0(%rbp), %rsi
leaq -0x20(%rbp), %rdx
callq 0x428ae0
movq -0xf8(%rbp), %rdi
leaq -0x9c(%rbp), %rsi
callq 0x428ab0
movq -0xc0(%rbp), %rax
movl 0x78(%rax), %eax
subl $0x1, %eax
movl %eax, -0x20(%rbp)
movl -0x24(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x24(%rbp)
movq -0x10(%rbp), %rdi
callq 0x4a0a10
movq %rax, %rsi
movl -0x24(%rbp), %eax
addq %rax, %rsi
leaq -0x68(%rbp), %rdi
callq 0x428730
leaq -0x48(%rbp), %rdi
leaq -0x68(%rbp), %rsi
callq 0x428a80
movq -0xc0(%rbp), %rcx
movl -0x24(%rbp), %eax
addl 0x88(%rcx), %eax
movl %eax, -0xa4(%rbp)
movl -0xa4(%rbp), %eax
cmpl -0x1c(%rbp), %eax
ja 0x428043
movq -0x10(%rbp), %rdi
movl -0xa4(%rbp), %eax
movl %eax, %esi
callq 0x49f500
leaq -0x68(%rbp), %rdi
movzbl (%rax), %esi
callq 0x428b40
leaq -0x68(%rbp), %rdi
leaq -0x48(%rbp), %rsi
callq 0x428be0
testb $0x1, %al
jne 0x42800a
jmp 0x428030
leaq -0x48(%rbp), %rdi
leaq -0x68(%rbp), %rsi
callq 0x428a80
movq -0xc0(%rbp), %rcx
movl -0xa4(%rbp), %eax
subl 0x88(%rcx), %eax
addl $0x1, %eax
movl %eax, -0x24(%rbp)
jmp 0x428032
movl -0xa4(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xa4(%rbp)
jmp 0x427fcf
jmp 0x428045
jmp 0x428047
jmp 0x428049
movl -0x20(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x20(%rbp)
movl -0x1c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x1c(%rbp)
jmp 0x427d11
jmp 0x427c35
movq -0xc0(%rbp), %rcx
movl -0x20(%rbp), %eax
cmpl 0x78(%rcx), %eax
jb 0x4280e0
movq -0xc0(%rbp), %rax
movq -0x18(%rbp), %rcx
movq %rcx, -0x108(%rbp)
movl -0x1c(%rbp), %ecx
subl -0x20(%rbp), %ecx
movl %ecx, -0xb4(%rbp)
movq 0x50(%rax), %rax
movq %rax, -0x110(%rbp)
leaq -0x48(%rbp), %rdi
callq 0x428b20
movq -0x110(%rbp), %rcx
movl %eax, %eax
shlq $0x2, %rax
addq %rax, %rcx
leaq -0xb0(%rbp), %rdi
leaq -0xb4(%rbp), %rsi
leaq -0x20(%rbp), %rdx
callq 0x428ae0
movq -0x108(%rbp), %rdi
leaq -0xb0(%rbp), %rsi
callq 0x428ab0
addq $0x110, %rsp            # imm = 0x110
popq %rbp
retq
nopl (%rax)