// File: ChnMasterOG[P]KmerGO2/kmc_api/kmc_file.cpp
// Function: CKMCFile::GetCountersForRead_kmc1_both_strands(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, std::vector<unsigned int, std::allocator<unsigned int>>&)
bool CKMCFile::GetCountersForRead_kmc1_both_strands(const std::string& read, std::vector<uint32>& counters)
{
	uint32 read_len = static_cast<uint32>(read.length());
	counters.resize(read.length() - kmer_length + 1);
	std::string transformed_read = read;
	for (char& c : transformed_read)
		c = CKmerAPI::num_codes[(uchar)c];

	uint32 i = 0;
	CKmerAPI kmer(kmer_length), kmer_rev(kmer_length);
	uint32 pos = 0;
	uint32 rev_pos = kmer_length - 1;

	uint32 counters_pos = 0;

	while (i + kmer_length - 1 < read_len)
	{
		bool contains_N = false;
		while (i < read_len && pos < kmer_length)
		{
			if (CKmerAPI::num_codes[(uchar)read[i]] < 0)
			{
				pos = 0;
				rev_pos = kmer_length - 1;
				kmer.clear();
				kmer_rev.clear();
				++i;
				uint32 wrong_kmers = MIN(i - counters_pos, static_cast<uint32>(counters.size()) - counters_pos);
				fill_n(counters.begin() + counters_pos, wrong_kmers, 0);
				counters_pos += wrong_kmers;
				contains_N = true;
				break;
			}
			else
			{
				kmer_rev.insert2bits(rev_pos--, 3 - CKmerAPI::num_codes[(uchar)read[i]]);
				kmer.insert2bits(pos++, CKmerAPI::num_codes[(uchar)read[i++]]);
				
			}
		}
		if (contains_N)
			continue;
		if (pos == kmer_length)
		{
			if(kmer < kmer_rev)
				counters[counters_pos++] = count_for_kmer_kmc1(kmer);
			else
				counters[counters_pos++] = count_for_kmer_kmc1(kmer_rev);
		}
		else
			break;

		while (i < read_len)
		{
			if (CKmerAPI::num_codes[(uchar)read[i]] < 0)
			{
				pos = 0;
				break;
			}
			kmer_rev.SHR_insert2bits(3 - CKmerAPI::num_codes[(uchar)read[i]]);
			kmer.SHL_insert2bits(CKmerAPI::num_codes[(uchar)read[i++]]);
			if(kmer < kmer_rev)
				counters[counters_pos++] = count_for_kmer_kmc1(kmer);
			else
				counters[counters_pos++] = count_for_kmer_kmc1(kmer_rev);
		}
	}
	if (counters_pos < counters.size())
	{
		fill_n(counters.begin() + counters_pos, counters.size() - counters_pos, 0);
		counters_pos = static_cast<uint32>(counters.size());
	}
	return true;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x160, %rsp            # imm = 0x160
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x108(%rbp)
movq -0x10(%rbp), %rdi
callq 0x49f200
movl %eax, -0x1c(%rbp)
movq -0x18(%rbp), %rax
movq %rax, -0x110(%rbp)
movq -0x10(%rbp), %rdi
callq 0x49f200
movq -0x110(%rbp), %rdi
movq %rax, %rsi
movq -0x108(%rbp), %rax
movl 0x78(%rax), %eax
subq %rax, %rsi
addq $0x1, %rsi
callq 0x4282c0
movq -0x10(%rbp), %rsi
leaq -0x40(%rbp), %rdi
callq 0x4a15e0
leaq -0x40(%rbp), %rax
movq %rax, -0x48(%rbp)
movq -0x48(%rbp), %rdi
callq 0x49f100
movq %rax, -0x50(%rbp)
movq -0x48(%rbp), %rdi
callq 0x49f120
movq %rax, -0x58(%rbp)
leaq -0x50(%rbp), %rdi
leaq -0x58(%rbp), %rsi
callq 0x428350
testb $0x1, %al
jne 0x426cf4
jmp 0x426d25
leaq -0x50(%rbp), %rdi
callq 0x408440
movq %rax, -0x60(%rbp)
movq -0x60(%rbp), %rax
movzbl (%rax), %eax
movl %eax, %ecx
movq $0x1b8f8e0, %rax        # imm = 0x1B8F8E0
movb (%rax,%rcx), %cl
movq -0x60(%rbp), %rax
movb %cl, (%rax)
leaq -0x50(%rbp), %rdi
callq 0x428390
jmp 0x426ce1
movq -0x108(%rbp), %rax
movl $0x0, -0x64(%rbp)
movl 0x78(%rax), %esi
leaq -0x80(%rbp), %rdi
callq 0x40b540
jmp 0x426d41
movq -0x108(%rbp), %rax
movl 0x78(%rax), %esi
leaq -0xa8(%rbp), %rdi
callq 0x40b540
jmp 0x426d59
movq -0x108(%rbp), %rax
movl $0x0, -0xac(%rbp)
movl 0x78(%rax), %eax
subl $0x1, %eax
movl %eax, -0xb0(%rbp)
movl $0x0, -0xb4(%rbp)
movq -0x108(%rbp), %rcx
movl -0x64(%rbp), %eax
addl 0x78(%rcx), %eax
subl $0x1, %eax
cmpl -0x1c(%rbp), %eax
jae 0x427234
movb $0x0, -0xb5(%rbp)
movl -0x64(%rbp), %ecx
xorl %eax, %eax
cmpl -0x1c(%rbp), %ecx
movb %al, -0x111(%rbp)
jae 0x426dc9
movq -0x108(%rbp), %rcx
movl -0xac(%rbp), %eax
cmpl 0x78(%rcx), %eax
setb %al
movb %al, -0x111(%rbp)
movb -0x111(%rbp), %al
testb $0x1, %al
jne 0x426dd8
jmp 0x42700f
movq -0x10(%rbp), %rdi
movl -0x64(%rbp), %eax
movl %eax, %esi
callq 0x49f500
movzbl (%rax), %eax
movl %eax, %ecx
movq $0x1b8f8e0, %rax        # imm = 0x1B8F8E0
movsbl (%rax,%rcx), %eax
cmpl $0x0, %eax
jge 0x426f6e
movq -0x108(%rbp), %rax
movl $0x0, -0xac(%rbp)
movl 0x78(%rax), %eax
decl %eax
movl %eax, -0xb0(%rbp)
leaq -0x80(%rbp), %rdi
callq 0x4283b0
jmp 0x426e26
leaq -0xa8(%rbp), %rdi
callq 0x4283b0
jmp 0x426e34
movl -0x64(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x64(%rbp)
movl -0x64(%rbp), %eax
subl -0xb4(%rbp), %eax
movl %eax, -0x118(%rbp)
movq -0x18(%rbp), %rdi
callq 0x420d40
movq %rax, %rcx
movl -0x118(%rbp), %eax
subl -0xb4(%rbp), %ecx
cmpl %ecx, %eax
jae 0x426e79
movl -0x64(%rbp), %eax
subl -0xb4(%rbp), %eax
movl %eax, -0x11c(%rbp)
jmp 0x426e8e
movq -0x18(%rbp), %rdi
callq 0x420d40
subl -0xb4(%rbp), %eax
movl %eax, -0x11c(%rbp)
movl -0x11c(%rbp), %eax
movl %eax, -0xbc(%rbp)
movq -0x18(%rbp), %rdi
callq 0x420c40
movq %rax, -0xd0(%rbp)
movl -0xb4(%rbp), %eax
movl %eax, %esi
leaq -0xd0(%rbp), %rdi
callq 0x428440
movq %rax, -0xc8(%rbp)
movl -0xbc(%rbp), %esi
movl $0x0, -0xd4(%rbp)
movq -0xc8(%rbp), %rdi
leaq -0xd4(%rbp), %rdx
callq 0x4283e0
movq %rax, -0x128(%rbp)
jmp 0x426ef1
movq -0x128(%rbp), %rax
movq %rax, -0xe0(%rbp)
movl -0xbc(%rbp), %eax
addl -0xb4(%rbp), %eax
movl %eax, -0xb4(%rbp)
movb $0x1, -0xb5(%rbp)
jmp 0x42700f
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x88(%rbp)
movl %eax, -0x8c(%rbp)
jmp 0x427314
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x88(%rbp)
movl %eax, -0x8c(%rbp)
jmp 0x42730b
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x88(%rbp)
movl %eax, -0x8c(%rbp)
leaq -0xa8(%rbp), %rdi
callq 0x40bcf0
jmp 0x42730b
movl -0xb0(%rbp), %eax
movl %eax, -0x12c(%rbp)
decl %eax
movl %eax, -0xb0(%rbp)
movq -0x10(%rbp), %rdi
movl -0x64(%rbp), %eax
movl %eax, %esi
callq 0x49f500
movl -0x12c(%rbp), %esi
movzbl (%rax), %eax
movl %eax, %ecx
movq $0x1b8f8e0, %rax        # imm = 0x1B8F8E0
movzbl (%rax,%rcx), %ecx
movl $0x3, %eax
subl %ecx, %eax
movzbl %al, %edx
leaq -0xa8(%rbp), %rdi
callq 0x428480
jmp 0x426fbe
movl -0xac(%rbp), %eax
movl %eax, -0x130(%rbp)
incl %eax
movl %eax, -0xac(%rbp)
movq -0x10(%rbp), %rdi
movl -0x64(%rbp), %eax
movl %eax, %esi
movl %esi, %eax
incl %eax
movl %eax, -0x64(%rbp)
callq 0x49f500
movl -0x130(%rbp), %esi
movzbl (%rax), %eax
movl %eax, %ecx
movq $0x1b8f8e0, %rax        # imm = 0x1B8F8E0
movzbl (%rax,%rcx), %edx
leaq -0x80(%rbp), %rdi
callq 0x428480
jmp 0x427008
jmp 0x42700a
jmp 0x426da0
testb $0x1, -0xb5(%rbp)
je 0x42701d
jmp 0x426d80
movq -0x108(%rbp), %rcx
movl -0xac(%rbp), %eax
cmpl 0x78(%rcx), %eax
jne 0x4270da
leaq -0x80(%rbp), %rdi
leaq -0xa8(%rbp), %rsi
callq 0x40b6f0
movb %al, -0x131(%rbp)
jmp 0x42704b
movb -0x131(%rbp), %al
testb $0x1, %al
jne 0x427057
jmp 0x427097
movq -0x108(%rbp), %rdi
leaq -0x80(%rbp), %rsi
callq 0x427a00
movl %eax, -0x138(%rbp)
jmp 0x42706f
movq -0x18(%rbp), %rdi
movl -0xb4(%rbp), %eax
movl %eax, %ecx
addl $0x1, %ecx
movl %ecx, -0xb4(%rbp)
movl %eax, %eax
movl %eax, %esi
callq 0x40b8b0
movl -0x138(%rbp), %ecx
movl %ecx, (%rax)
jmp 0x4270d8
movq -0x108(%rbp), %rdi
leaq -0xa8(%rbp), %rsi
callq 0x427a00
movl %eax, -0x13c(%rbp)
jmp 0x4270b2
movq -0x18(%rbp), %rdi
movl -0xb4(%rbp), %eax
movl %eax, %ecx
addl $0x1, %ecx
movl %ecx, -0xb4(%rbp)
movl %eax, %eax
movl %eax, %esi
callq 0x40b8b0
movl -0x13c(%rbp), %ecx
movl %ecx, (%rax)
jmp 0x4270df
jmp 0x427234
jmp 0x4270e1
movl -0x64(%rbp), %eax
cmpl -0x1c(%rbp), %eax
jae 0x42722f
movq -0x10(%rbp), %rdi
movl -0x64(%rbp), %eax
movl %eax, %esi
callq 0x49f500
movzbl (%rax), %eax
movl %eax, %ecx
movq $0x1b8f8e0, %rax        # imm = 0x1B8F8E0
movsbl (%rax,%rcx), %eax
cmpl $0x0, %eax
jge 0x42711f
movl $0x0, -0xac(%rbp)
jmp 0x42722f
movq -0x10(%rbp), %rdi
movl -0x64(%rbp), %eax
movl %eax, %esi
callq 0x49f500
movzbl (%rax), %eax
movl %eax, %ecx
movq $0x1b8f8e0, %rax        # imm = 0x1B8F8E0
movzbl (%rax,%rcx), %ecx
movl $0x3, %eax
subl %ecx, %eax
movzbl %al, %esi
leaq -0xa8(%rbp), %rdi
callq 0x4284e0
jmp 0x427155
movq -0x10(%rbp), %rdi
movl -0x64(%rbp), %eax
movl %eax, %esi
movl %esi, %eax
incl %eax
movl %eax, -0x64(%rbp)
callq 0x49f500
movzbl (%rax), %eax
movl %eax, %ecx
movq $0x1b8f8e0, %rax        # imm = 0x1B8F8E0
movzbl (%rax,%rcx), %esi
leaq -0x80(%rbp), %rdi
callq 0x4285c0
jmp 0x427185
leaq -0x80(%rbp), %rdi
leaq -0xa8(%rbp), %rsi
callq 0x40b6f0
movb %al, -0x13d(%rbp)
jmp 0x42719d
movb -0x13d(%rbp), %al
testb $0x1, %al
jne 0x4271a9
jmp 0x4271e9
movq -0x108(%rbp), %rdi
leaq -0x80(%rbp), %rsi
callq 0x427a00
movl %eax, -0x144(%rbp)
jmp 0x4271c1
movq -0x18(%rbp), %rdi
movl -0xb4(%rbp), %eax
movl %eax, %ecx
addl $0x1, %ecx
movl %ecx, -0xb4(%rbp)
movl %eax, %eax
movl %eax, %esi
callq 0x40b8b0
movl -0x144(%rbp), %ecx
movl %ecx, (%rax)
jmp 0x42722a
movq -0x108(%rbp), %rdi
leaq -0xa8(%rbp), %rsi
callq 0x427a00
movl %eax, -0x148(%rbp)
jmp 0x427204
movq -0x18(%rbp), %rdi
movl -0xb4(%rbp), %eax
movl %eax, %ecx
addl $0x1, %ecx
movl %ecx, -0xb4(%rbp)
movl %eax, %eax
movl %eax, %esi
callq 0x40b8b0
movl -0x148(%rbp), %ecx
movl %ecx, (%rax)
jmp 0x4270e1
jmp 0x426d80
movl -0xb4(%rbp), %eax
movq %rax, -0x150(%rbp)
movq -0x18(%rbp), %rdi
callq 0x420d40
movq %rax, %rcx
movq -0x150(%rbp), %rax
cmpq %rcx, %rax
jae 0x4272e0
movq -0x18(%rbp), %rdi
callq 0x420c40
movq %rax, -0xf0(%rbp)
movl -0xb4(%rbp), %eax
movl %eax, %esi
leaq -0xf0(%rbp), %rdi
callq 0x428440
movq %rax, -0xe8(%rbp)
movq -0x18(%rbp), %rdi
callq 0x420d40
movq %rax, %rsi
movl -0xb4(%rbp), %eax
subq %rax, %rsi
movl $0x0, -0xf4(%rbp)
movq -0xe8(%rbp), %rdi
leaq -0xf4(%rbp), %rdx
callq 0x4286d0
movq %rax, -0x158(%rbp)
jmp 0x4272c3
movq -0x158(%rbp), %rax
movq %rax, -0x100(%rbp)
movq -0x18(%rbp), %rdi
callq 0x420d40
movl %eax, -0xb4(%rbp)
leaq -0xa8(%rbp), %rdi
callq 0x40bcf0
leaq -0x80(%rbp), %rdi
callq 0x40bcf0
leaq -0x40(%rbp), %rdi
callq 0x49efd0
movb $0x1, %al
andb $0x1, %al
addq $0x160, %rsp            # imm = 0x160
popq %rbp
retq
leaq -0x80(%rbp), %rdi
callq 0x40bcf0
leaq -0x40(%rbp), %rdi
callq 0x49efd0
movq -0x88(%rbp), %rdi
callq 0x4d3c10
nopl (%rax)