// File: ChnMasterOG[P]KmerGO2/kmc_api/kmc_file.cpp
// Function: CKMCFile::GetCountersForRead_kmc2_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_kmc2_both_strands(const std::string& read, std::vector<uint32>& counters)
{
	counters.resize(read.length() - kmer_length + 1);
	std::string transformed_read = read;
	for (char& c : transformed_read)
		c = CKmerAPI::num_codes[(uchar)c];

	super_kmers_t super_kmers;
	GetSuperKmers(transformed_read, super_kmers);

	uint32 counters_pos = 0;
	if (super_kmers.empty())
	{
		fill_n(counters.begin(), counters.size(), 0);
		return true;
	}

	CKmerAPI kmer(kmer_length), rev_kmer(kmer_length);

	uint32 last_end = 0;

	//'N' somewhere in first k-mer
	if (std::get<0>(super_kmers.front()) > 0)
	{
		fill_n(counters.begin(), std::get<0>(super_kmers.front()), 0);
		last_end = std::get<0>(super_kmers.front());
		counters_pos = std::get<0>(super_kmers.front());
	}
	for (auto& super_kmer : super_kmers)
	{
		//'N's between super k-mers
		if (last_end < std::get<0>(super_kmer))
		{
			uint32 gap = std::get<0>(super_kmer) -last_end;
			fill_n(counters.begin() + counters_pos, kmer_length + gap - 1, 0);
			counters_pos += kmer_length + gap - 1;
		}
		last_end = std::get<0>(super_kmer) +std::get<1>(super_kmer);

		kmer.from_binary(transformed_read.c_str() + std::get<0>(super_kmer));
		rev_kmer.from_binary_rev(transformed_read.c_str() + std::get<0>(super_kmer));

		uint32 bin_start_pos = std::get<2>(super_kmer) * single_LUT_size;
		if(kmer < rev_kmer)
			counters[counters_pos++] = count_for_kmer_kmc2(kmer, bin_start_pos);
		else
			counters[counters_pos++] = count_for_kmer_kmc2(rev_kmer, bin_start_pos);

		for (uint32 i = std::get<0>(super_kmer) +kmer_length; i < std::get<0>(super_kmer) +std::get<1>(super_kmer); ++i)
		{
			kmer.SHL_insert2bits(transformed_read[i]);
			rev_kmer.SHR_insert2bits(3 - transformed_read[i]);
			if(kmer < rev_kmer)
				counters[counters_pos++] = count_for_kmer_kmc2(kmer, bin_start_pos);
			else
				counters[counters_pos++] = count_for_kmer_kmc2(rev_kmer, bin_start_pos);
		}
	}
	//'N's at the end of read
	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 $0x200, %rsp            # imm = 0x200
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movq %rdx, -0x20(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0x170(%rbp)
movq -0x20(%rbp), %rax
movq %rax, -0x178(%rbp)
movq -0x18(%rbp), %rdi
callq 0x49f200
movq -0x178(%rbp), %rdi
movq %rax, %rsi
movq -0x170(%rbp), %rax
movl 0x78(%rax), %eax
subq %rax, %rsi
addq $0x1, %rsi
callq 0x4282c0
movq -0x18(%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 0x425e48
jmp 0x425e79
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 0x425e35
leaq -0x78(%rbp), %rdi
movq %rdi, -0x180(%rbp)
callq 0x428c10
movq -0x170(%rbp), %rdi
movq -0x180(%rbp), %rdx
leaq -0x40(%rbp), %rsi
callq 0x427be0
jmp 0x425ea2
movl $0x0, -0x88(%rbp)
leaq -0x78(%rbp), %rdi
callq 0x428c30
testb $0x1, %al
jne 0x425ebb
jmp 0x425f32
movq -0x20(%rbp), %rdi
callq 0x420c40
movq %rax, -0x90(%rbp)
movq -0x20(%rbp), %rdi
callq 0x420d40
movq %rax, %rsi
movl $0x0, -0x94(%rbp)
movq -0x90(%rbp), %rdi
leaq -0x94(%rbp), %rdx
callq 0x4286d0
movq %rax, -0x188(%rbp)
jmp 0x425efd
movq -0x188(%rbp), %rax
movq %rax, -0xa0(%rbp)
movb $0x1, -0x1(%rbp)
movl $0x1, -0xa4(%rbp)
jmp 0x42658d
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x80(%rbp)
movl %eax, -0x84(%rbp)
jmp 0x4265ad
movq -0x170(%rbp), %rax
movl 0x78(%rax), %esi
leaq -0xc0(%rbp), %rdi
callq 0x40b540
jmp 0x425f4a
movq -0x170(%rbp), %rax
movl 0x78(%rax), %esi
leaq -0xd8(%rbp), %rdi
callq 0x40b540
jmp 0x425f62
movl $0x0, -0xdc(%rbp)
leaq -0x78(%rbp), %rdi
callq 0x428c90
movq %rax, %rdi
callq 0x428c70
cmpl $0x0, (%rax)
jbe 0x426045
movq -0x20(%rbp), %rdi
callq 0x420c40
movq %rax, -0xe8(%rbp)
leaq -0x78(%rbp), %rdi
callq 0x428c90
movq %rax, %rdi
callq 0x428c70
movl (%rax), %esi
movl $0x0, -0xec(%rbp)
movq -0xe8(%rbp), %rdi
leaq -0xec(%rbp), %rdx
callq 0x4283e0
movq %rax, -0x190(%rbp)
jmp 0x425fcf
movq -0x190(%rbp), %rax
movq %rax, -0xf8(%rbp)
leaq -0x78(%rbp), %rdi
callq 0x428c90
movq %rax, %rdi
callq 0x428c70
movl (%rax), %eax
movl %eax, -0xdc(%rbp)
leaq -0x78(%rbp), %rdi
callq 0x428c90
movq %rax, %rdi
callq 0x428c70
movl (%rax), %eax
movl %eax, -0x88(%rbp)
jmp 0x426045
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x80(%rbp)
movl %eax, -0x84(%rbp)
jmp 0x42657f
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x80(%rbp)
movl %eax, -0x84(%rbp)
leaq -0xd8(%rbp), %rdi
callq 0x40bcf0
jmp 0x42657f
leaq -0x78(%rbp), %rax
movq %rax, -0x100(%rbp)
movq -0x100(%rbp), %rdi
callq 0x428cc0
movq %rax, -0x108(%rbp)
movq -0x100(%rbp), %rdi
callq 0x428cf0
movq %rax, -0x110(%rbp)
leaq -0x108(%rbp), %rdi
leaq -0x110(%rbp), %rsi
callq 0x428d20
testb $0x1, %al
jne 0x426092
jmp 0x4264ab
leaq -0x108(%rbp), %rdi
callq 0x428d60
movq %rax, -0x118(%rbp)
movl -0xdc(%rbp), %eax
movl %eax, -0x194(%rbp)
movq -0x118(%rbp), %rdi
callq 0x428c70
movq %rax, %rcx
movl -0x194(%rbp), %eax
cmpl (%rcx), %eax
jae 0x426183
movq -0x118(%rbp), %rdi
callq 0x428c70
movl (%rax), %eax
movl -0xdc(%rbp), %ecx
subl %ecx, %eax
movl %eax, -0x11c(%rbp)
movq -0x20(%rbp), %rdi
callq 0x420c40
movq %rax, -0x130(%rbp)
movl -0x88(%rbp), %eax
movl %eax, %esi
leaq -0x130(%rbp), %rdi
callq 0x428440
movq %rax, %rcx
movq -0x170(%rbp), %rax
movq %rcx, -0x128(%rbp)
movl 0x78(%rax), %edx
movl -0x11c(%rbp), %eax
movl %eax, %ecx
movl %edx, %eax
leal -0x1(%rax,%rcx), %esi
movl $0x0, -0x134(%rbp)
movq -0x128(%rbp), %rdi
leaq -0x134(%rbp), %rdx
callq 0x4283e0
movq %rax, -0x1a0(%rbp)
jmp 0x426156
movq -0x170(%rbp), %rax
movq -0x1a0(%rbp), %rcx
movq %rcx, -0x140(%rbp)
movl 0x78(%rax), %eax
addl -0x11c(%rbp), %eax
subl $0x1, %eax
addl -0x88(%rbp), %eax
movl %eax, -0x88(%rbp)
movq -0x118(%rbp), %rdi
callq 0x428c70
movl (%rax), %eax
movl %eax, -0x1ac(%rbp)
movq -0x118(%rbp), %rdi
callq 0x428d80
movq %rax, %rcx
movl -0x1ac(%rbp), %eax
movl (%rcx), %ecx
addl %ecx, %eax
movl %eax, -0xdc(%rbp)
leaq -0x40(%rbp), %rdi
callq 0x4a0a10
movq %rax, -0x1a8(%rbp)
movq -0x118(%rbp), %rdi
callq 0x428c70
movq -0x1a8(%rbp), %rsi
movl (%rax), %eax
addq %rax, %rsi
leaq -0xc0(%rbp), %rdi
callq 0x428da0
jmp 0x4261ec
leaq -0x40(%rbp), %rdi
callq 0x4a0a10
movq %rax, -0x1b8(%rbp)
movq -0x118(%rbp), %rdi
callq 0x428c70
movq -0x1b8(%rbp), %rsi
movl (%rax), %eax
addq %rax, %rsi
leaq -0xd8(%rbp), %rdi
callq 0x428e00
jmp 0x426222
movq -0x118(%rbp), %rdi
callq 0x428e70
movq -0x170(%rbp), %rcx
movl (%rax), %eax
movl 0x48(%rcx), %ecx
imull %ecx, %eax
movl %eax, -0x144(%rbp)
leaq -0xc0(%rbp), %rdi
leaq -0xd8(%rbp), %rsi
callq 0x40b6f0
movb %al, -0x1b9(%rbp)
jmp 0x42625e
movb -0x1b9(%rbp), %al
testb $0x1, %al
jne 0x42626a
jmp 0x4262b3
movq -0x170(%rbp), %rdi
movl -0x144(%rbp), %edx
leaq -0xc0(%rbp), %rsi
callq 0x427ae0
movl %eax, -0x1c0(%rbp)
jmp 0x42628b
movq -0x20(%rbp), %rdi
movl -0x88(%rbp), %eax
movl %eax, %ecx
addl $0x1, %ecx
movl %ecx, -0x88(%rbp)
movl %eax, %eax
movl %eax, %esi
callq 0x40b8b0
movl -0x1c0(%rbp), %ecx
movl %ecx, (%rax)
jmp 0x4262fa
movq -0x170(%rbp), %rdi
movl -0x144(%rbp), %edx
leaq -0xd8(%rbp), %rsi
callq 0x427ae0
movl %eax, -0x1c4(%rbp)
jmp 0x4262d4
movq -0x20(%rbp), %rdi
movl -0x88(%rbp), %eax
movl %eax, %ecx
addl $0x1, %ecx
movl %ecx, -0x88(%rbp)
movl %eax, %eax
movl %eax, %esi
callq 0x40b8b0
movl -0x1c4(%rbp), %ecx
movl %ecx, (%rax)
movq -0x118(%rbp), %rdi
callq 0x428c70
movq -0x170(%rbp), %rcx
movl (%rax), %eax
addl 0x78(%rcx), %eax
movl %eax, -0x148(%rbp)
movl -0x148(%rbp), %eax
movl %eax, -0x1c8(%rbp)
movq -0x118(%rbp), %rdi
callq 0x428c70
movl (%rax), %eax
movl %eax, -0x1cc(%rbp)
movq -0x118(%rbp), %rdi
callq 0x428d80
movl -0x1cc(%rbp), %ecx
movq %rax, %rdx
movl -0x1c8(%rbp), %eax
addl (%rdx), %ecx
cmpl %ecx, %eax
jae 0x426498
movl -0x148(%rbp), %eax
movl %eax, %esi
leaq -0x40(%rbp), %rdi
callq 0x49f510
movq %rax, -0x1d8(%rbp)
jmp 0x426377
movq -0x1d8(%rbp), %rax
movzbl (%rax), %esi
leaq -0xc0(%rbp), %rdi
callq 0x4285c0
jmp 0x42638f
movl -0x148(%rbp), %eax
movl %eax, %esi
leaq -0x40(%rbp), %rdi
callq 0x49f510
movq %rax, -0x1e0(%rbp)
jmp 0x4263a9
movq -0x1e0(%rbp), %rax
movzbl (%rax), %ecx
movl $0x3, %eax
subl %ecx, %eax
movzbl %al, %esi
leaq -0xd8(%rbp), %rdi
callq 0x4284e0
jmp 0x4263cb
leaq -0xc0(%rbp), %rdi
leaq -0xd8(%rbp), %rsi
callq 0x40b6f0
movb %al, -0x1e1(%rbp)
jmp 0x4263e6
movb -0x1e1(%rbp), %al
testb $0x1, %al
jne 0x4263f2
jmp 0x42643b
movq -0x170(%rbp), %rdi
movl -0x144(%rbp), %edx
leaq -0xc0(%rbp), %rsi
callq 0x427ae0
movl %eax, -0x1e8(%rbp)
jmp 0x426413
movq -0x20(%rbp), %rdi
movl -0x88(%rbp), %eax
movl %eax, %ecx
addl $0x1, %ecx
movl %ecx, -0x88(%rbp)
movl %eax, %eax
movl %eax, %esi
callq 0x40b8b0
movl -0x1e8(%rbp), %ecx
movl %ecx, (%rax)
jmp 0x426482
movq -0x170(%rbp), %rdi
movl -0x144(%rbp), %edx
leaq -0xd8(%rbp), %rsi
callq 0x427ae0
movl %eax, -0x1ec(%rbp)
jmp 0x42645c
movq -0x20(%rbp), %rdi
movl -0x88(%rbp), %eax
movl %eax, %ecx
addl $0x1, %ecx
movl %ecx, -0x88(%rbp)
movl %eax, %eax
movl %eax, %esi
callq 0x40b8b0
movl -0x1ec(%rbp), %ecx
movl %ecx, (%rax)
jmp 0x426484
movl -0x148(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x148(%rbp)
jmp 0x426318
jmp 0x42649a
leaq -0x108(%rbp), %rdi
callq 0x428e90
jmp 0x426076
movl -0x88(%rbp), %eax
movq %rax, -0x1f8(%rbp)
movq -0x20(%rbp), %rdi
callq 0x420d40
movq %rax, %rcx
movq -0x1f8(%rbp), %rax
cmpq %rcx, %rax
jae 0x426557
movq -0x20(%rbp), %rdi
callq 0x420c40
movq %rax, -0x158(%rbp)
movl -0x88(%rbp), %eax
movl %eax, %esi
leaq -0x158(%rbp), %rdi
callq 0x428440
movq %rax, -0x150(%rbp)
movq -0x20(%rbp), %rdi
callq 0x420d40
movq %rax, %rsi
movl -0x88(%rbp), %eax
subq %rax, %rsi
movl $0x0, -0x15c(%rbp)
movq -0x150(%rbp), %rdi
leaq -0x15c(%rbp), %rdx
callq 0x4286d0
movq %rax, -0x200(%rbp)
jmp 0x42653a
movq -0x200(%rbp), %rax
movq %rax, -0x168(%rbp)
movq -0x20(%rbp), %rdi
callq 0x420d40
movl %eax, -0x88(%rbp)
movb $0x1, -0x1(%rbp)
movl $0x1, -0xa4(%rbp)
leaq -0xd8(%rbp), %rdi
callq 0x40bcf0
leaq -0xc0(%rbp), %rdi
callq 0x40bcf0
jmp 0x42658d
leaq -0xc0(%rbp), %rdi
callq 0x40bcf0
jmp 0x4265ad
leaq -0x78(%rbp), %rdi
callq 0x428eb0
leaq -0x40(%rbp), %rdi
callq 0x49efd0
movb -0x1(%rbp), %al
andb $0x1, %al
addq $0x200, %rsp            # imm = 0x200
popq %rbp
retq
leaq -0x78(%rbp), %rdi
callq 0x428eb0
leaq -0x40(%rbp), %rdi
callq 0x49efd0
movq -0x80(%rbp), %rdi
callq 0x4d3c10
nopl (%rax,%rax)