// File: /workspace/github_cpp_makefile_star2_O3/ChnMasterOG[P]KmerGO2/kmc_api/kmc_file.cpp
// Function: CKMCFile::BinarySearch(long long, long long, CKmerAPI const&, unsigned long long&, unsigned int)
bool CKMCFile::BinarySearch(int64 index_start, int64 index_stop, const CKmerAPI& kmer, uint64& counter, uint32 pattern_offset)
{
	if (index_start >= static_cast<int64>(total_kmers))
		return false;
	uchar *sufix_byte_ptr = nullptr;
	uint64 sufix = 0;

	//sufix_offset is always 56
	uint32 sufix_offset = 56;			// the offset of a sufix is for shifting the sufix towards MSB, to compare the sufix with a pattern
	// Bytes of a pattern to search are always shifted towards MSB

	uint32 row_index = 0;				// the number of a current row in an array kmer_data

	bool found = false;

	while (index_start <= index_stop)
	{
		int64 mid_index = (index_start + index_stop) / 2;
		sufix_byte_ptr = &sufix_file_buf[mid_index * sufix_rec_size];

		uint64 pattern = 0;

		pattern_offset = (lut_prefix_length + kmer.byte_alignment) * 2;

		row_index = 0;
		for (uint32 a = 0; a < sufix_size; a++)		//check byte by byte
		{
			pattern = kmer.kmer_data[row_index];
			pattern = pattern << pattern_offset;
			pattern = pattern & 0xff00000000000000;

			sufix = sufix_byte_ptr[a];
			sufix = sufix << sufix_offset;

			if (pattern != sufix)
				break;

			pattern_offset += 8;

			if (pattern_offset == 64)				//the end of a word
			{
				pattern_offset = 0;
				row_index++;
			}
		}

		if (pattern == sufix)
		{
			found = true;
			break;
		}
		if (sufix < pattern)
			index_start = mid_index + 1;
		else
			index_stop = mid_index - 1;
	}

	if (found)
	{
		sufix_byte_ptr += sufix_size;

		counter = *sufix_byte_ptr;

		for (uint32 b = 1; b < counter_size; b++)
		{
			uint64 aux = 0x000000ff & *(sufix_byte_ptr + b);

			aux = aux << 8 * (b);
			counter = aux | counter;
		}
		if (mode != 0)
		{
			float float_counter;
			memcpy(&float_counter, &counter, counter_size);
			return (float_counter >= min_count) && (float_counter <= max_count);
		}
		return (counter >= min_count) && (counter <= max_count);
	}
	return false;
}

// Assembly:
cmpq %rsi, 0x98(%rdi)
setle %r10b
cmpq %rdx, %rsi
setg %r9b
xorl %eax, %eax
orb %r10b, %r9b
jne 0x416b2c
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x28, %rsp
movq 0x60(%rdi), %r11
movl 0xac(%rdi), %ebx
movzbl 0xc(%rcx), %r9d
addl 0x84(%rdi), %r9d
addl %r9d, %r9d
movl %r9d, 0x4(%rsp)
movq %rdi, 0x10(%rsp)
movl 0xa8(%rdi), %r9d
movq (%rcx), %r14
movabsq $-0x100000000000000, %r15 # imm = 0xFF00000000000000
xorl %r10d, %r10d
movq %r11, 0x8(%rsp)
movq %rbx, 0x18(%rsp)
leaq (%rsi,%rdx), %rcx
movq %rcx, %r12
shrq $0x3f, %r12
addq %rcx, %r12
sarq %r12
movq %r12, %r13
imulq %rbx, %r13
leaq (%r11,%r13), %rbp
testq %r9, %r9
je 0x416a20
xorl %edi, %edi
xorl %r11d, %r11d
movl 0x4(%rsp), %ecx
movl %r11d, %r10d
movq (%r14,%r10,8), %rbx
shlq %cl, %rbx
andq %r15, %rbx
movzbl (%rbp,%rdi), %r10d
shlq $0x38, %r10
cmpq %r10, %rbx
jne 0x416a22
addl $0x8, %ecx
xorl %r10d, %r10d
cmpl $0x40, %ecx
cmovel %eax, %ecx
sete %r10b
addl %r10d, %r11d
incq %rdi
cmpq %rdi, %r9
jne 0x4169e7
jmp 0x416a54
xorl %ebx, %ebx
cmpq %r10, %rbx
je 0x416a54
leaq 0x1(%r12), %rcx
decq %r12
cmpq %rbx, %r10
cmovaeq %r12, %rdx
cmovbq %rcx, %rsi
cmpq %rdx, %rsi
movq 0x8(%rsp), %r11
movq 0x18(%rsp), %rbx
jle 0x4169bd
xorl %eax, %eax
jmp 0x416b1e
movzbl (%rbp,%r9), %eax
movq %rax, (%r8)
movq 0x10(%rsp), %rbx
movl 0x80(%rbx), %edx
cmpq $0x2, %rdx
jb 0x416aa7
addq 0x8(%rsp), %r9
leaq (%r9,%r13), %rsi
incq %rsi
leaq (,%rdx,8), %rdi
movl $0x8, %r9d
movzbl (%rsi), %r10d
movl %r9d, %ecx
andb $-0x8, %cl
shlq %cl, %r10
orq %r10, %rax
movq %rax, (%r8)
addq $0x8, %r9
incq %rsi
cmpq %r9, %rdi
jne 0x416a88
cmpl $0x0, 0x7c(%rbx)
je 0x416ae0
leaq 0x24(%rsp), %r14
movq %r14, %rdi
movq %r8, %rsi
callq 0x401080
movl 0x8c(%rbx), %eax
cvtsi2ss %rax, %xmm0
movss (%r14), %xmm1
movq 0x90(%rbx), %rax
testq %rax, %rax
js 0x416afa
cvtsi2ss %rax, %xmm2
jmp 0x416b0f
movl 0x8c(%rbx), %ecx
cmpq %rcx, %rax
setae %cl
cmpq 0x90(%rbx), %rax
setbe %al
andb %cl, %al
jmp 0x416b1e
movq %rax, %rcx
shrq %rcx
andl $0x1, %eax
orq %rcx, %rax
cvtsi2ss %rax, %xmm2
addss %xmm2, %xmm2
cmpleps %xmm1, %xmm0
cmpleps %xmm2, %xmm1
andps %xmm0, %xmm1
movd %xmm1, %eax
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
andb $0x1, %al
retq
nop