// File: yuansliu[P]HiRGC/hirgc.cpp
// Function: searchMatch(char*)
void searchMatch(char *refFile) { // greedy matching
	FILE *fp = fopen(refFile, "w");
	if (NULL == fp) {
		printf("ERROR! fail to open file %s\n", refFile);
		return;
	}

	saveOtherData(fp);

	int pre_dismatch_point = 0, pre_pos = 0;
	int step_len = tar_seq_len - sub_str_num + 1;
	int max_length, max_k;

	int dis_str_len = 0, i, id, k, ref_idx, tar_idx, length, cur_pos;;
	uint64_t tar_value;

	for (i = 0; i < step_len; i++) {
		tar_value = 0;
		for (k = sub_str_num - 1; k >= 0; k--) {
			tar_value <<= 2;
			tar_value += tar_seq_code[i+k];
		}

		id = point[tar_value&(uint64_t)(max_arr_num-1)];
		if (id > -1) {
			max_length = -1;
			max_k = -1;
			for (k = id; k != -1; k = loc[k]) {
					//[pos[k], pos[k]+sub_str_num-1] //at least max_arr_num_bit_shift
				ref_idx = k + max_arr_num_bit_shift;//loc[k].pos == k
				tar_idx = i + max_arr_num_bit_shift;
				length = max_arr_num_bit_shift;
				while (ref_idx < ref_seq_len && tar_idx < tar_seq_len && ref_seq_code[ref_idx++] == tar_seq_code[tar_idx++]) {//extend current match
					length++;
				}
				if (length >= sub_str_num && length > max_length) {
					max_length = length;
					max_k = k;
				}
			}
			if (max_k > -1) { //if a match is found
				//first print mismatch substring
				if (dis_str_len > 0) {
					dismatched_str[dis_str_len] = '\0';
					fprintf(fp, "%s\n", dismatched_str);
					dis_str_len = 0;
				}
				//then print match substring
				cur_pos = max_k - pre_pos;
				pre_pos = max_k + max_length;

				fprintf(fp, "%d %d\n", cur_pos, max_length - sub_str_num);

				i += max_length;
				pre_dismatch_point = i;
				if (i < tar_seq_len) {
					dismatched_str[dis_str_len++] = '0'+tar_seq_code[i];
				}
				continue;
			}
		}
		dismatched_str[dis_str_len++] = '0'+tar_seq_code[i];
	}

	for(; i < tar_seq_len; i++) {
		dismatched_str[dis_str_len++] = '0'+tar_seq_code[i];
	}
	if (dis_str_len > 0) {
		dismatched_str[dis_str_len] = '\0';
		fprintf(fp, "%s\n", dismatched_str);
	}
	fclose(fp);
	// gettimeofday(&end,NULL);
	// timer = 1000000 * (end.tv_sec - start.tv_sec) + end.tv_usec - start.tv_usec;
	// printf("compress timer = %lf ms\n", timer/1000.0);
}

// Assembly:
subq $0x58, %rsp
movq %rdi, 0x50(%rsp)
movq 0x50(%rsp), %rdi
leaq 0x41ae(%rip), %rsi      # 0x8053
callq 0x21b0
movq %rax, 0x48(%rsp)
xorl %eax, %eax
cmpq 0x48(%rsp), %rax
jne 0x3ed0
movq 0x50(%rsp), %rsi
leaq 0x4191(%rip), %rdi      # 0x8055
movb $0x0, %al
callq 0x2040
jmp 0x4210
movq 0x48(%rsp), %rdi
callq 0x3870
movl $0x0, 0x44(%rsp)
movl $0x0, 0x40(%rsp)
movl 0x72d8(%rip), %eax      # 0xb1c8
subl $0x14, %eax
addl $0x1, %eax
movl %eax, 0x3c(%rsp)
movl $0x0, 0x30(%rsp)
movl $0x0, 0x2c(%rsp)
movl 0x2c(%rsp), %eax
cmpl 0x3c(%rsp), %eax
jge 0x418c
movq $0x0, 0x8(%rsp)
movl $0x13, 0x24(%rsp)
cmpl $0x0, 0x24(%rsp)
jl 0x3f6b
movq 0x8(%rsp), %rax
shlq $0x2, %rax
movq %rax, 0x8(%rsp)
movq 0x726b(%rip), %rax      # 0xb1b0
movl 0x2c(%rsp), %ecx
addl 0x24(%rsp), %ecx
movslq %ecx, %rcx
movslq (%rax,%rcx,4), %rax
addq 0x8(%rsp), %rax
movq %rax, 0x8(%rsp)
movl 0x24(%rsp), %eax
addl $-0x1, %eax
movl %eax, 0x24(%rsp)
jmp 0x3f29
movq 0x7276(%rip), %rax      # 0xb1e8
movq 0x8(%rsp), %rcx
andq $0x3fffffff, %rcx       # imm = 0x3FFFFFFF
movl (%rax,%rcx,4), %eax
movl %eax, 0x28(%rsp)
cmpl $-0x1, 0x28(%rsp)
jle 0x414e
movl $0xffffffff, 0x38(%rsp) # imm = 0xFFFFFFFF
movl $0xffffffff, 0x34(%rsp) # imm = 0xFFFFFFFF
movl 0x28(%rsp), %eax
movl %eax, 0x24(%rsp)
cmpl $-0x1, 0x24(%rsp)
je 0x4082
movl 0x24(%rsp), %eax
addl $0xf, %eax
movl %eax, 0x20(%rsp)
movl 0x2c(%rsp), %eax
addl $0xf, %eax
movl %eax, 0x1c(%rsp)
movl $0xf, 0x18(%rsp)
movl 0x20(%rsp), %ecx
xorl %eax, %eax
cmpl 0x71ef(%rip), %ecx      # 0xb1cc
movb %al, 0x7(%rsp)
jge 0x4030
movl 0x1c(%rsp), %ecx
xorl %eax, %eax
cmpl 0x71d9(%rip), %ecx      # 0xb1c8
movb %al, 0x7(%rsp)
jge 0x4030
movq 0x71bc(%rip), %rax      # 0xb1b8
movl 0x20(%rsp), %ecx
movl %ecx, %edx
addl $0x1, %edx
movl %edx, 0x20(%rsp)
movslq %ecx, %rcx
movl (%rax,%rcx,4), %eax
movq 0x719a(%rip), %rcx      # 0xb1b0
movl 0x1c(%rsp), %edx
movl %edx, %esi
addl $0x1, %esi
movl %esi, 0x1c(%rsp)
movslq %edx, %rdx
cmpl (%rcx,%rdx,4), %eax
sete %al
movb %al, 0x7(%rsp)
movb 0x7(%rsp), %al
testb $0x1, %al
jne 0x403a
jmp 0x4047
movl 0x18(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x18(%rsp)
jmp 0x3fd1
cmpl $0x14, 0x18(%rsp)
jl 0x4068
movl 0x18(%rsp), %eax
cmpl 0x38(%rsp), %eax
jle 0x4068
movl 0x18(%rsp), %eax
movl %eax, 0x38(%rsp)
movl 0x24(%rsp), %eax
movl %eax, 0x34(%rsp)
jmp 0x406a
movq 0x716f(%rip), %rax      # 0xb1e0
movslq 0x24(%rsp), %rcx
movl (%rax,%rcx,4), %eax
movl %eax, 0x24(%rsp)
jmp 0x3fa8
cmpl $-0x1, 0x34(%rsp)
jle 0x414c
cmpl $0x0, 0x30(%rsp)
jle 0x40c6
movq 0x7155(%rip), %rax      # 0xb1f0
movslq 0x30(%rsp), %rcx
movb $0x0, (%rax,%rcx)
movq 0x48(%rsp), %rdi
movq 0x7140(%rip), %rdx      # 0xb1f0
leaq 0x3fb7(%rip), %rsi      # 0x806e
movb $0x0, %al
callq 0x2200
movl $0x0, 0x30(%rsp)
movl 0x34(%rsp), %eax
subl 0x40(%rsp), %eax
movl %eax, 0x14(%rsp)
movl 0x34(%rsp), %eax
addl 0x38(%rsp), %eax
movl %eax, 0x40(%rsp)
movq 0x48(%rsp), %rdi
movl 0x14(%rsp), %edx
movl 0x38(%rsp), %ecx
subl $0x14, %ecx
leaq 0x3f7d(%rip), %rsi      # 0x8072
movb $0x0, %al
callq 0x2200
movl 0x38(%rsp), %eax
addl 0x2c(%rsp), %eax
movl %eax, 0x2c(%rsp)
movl 0x2c(%rsp), %eax
movl %eax, 0x44(%rsp)
movl 0x2c(%rsp), %eax
cmpl 0x70ae(%rip), %eax      # 0xb1c8
jge 0x414a
movq 0x708d(%rip), %rax      # 0xb1b0
movslq 0x2c(%rsp), %rcx
movl (%rax,%rcx,4), %eax
addl $0x30, %eax
movb %al, %dl
movq 0x70b9(%rip), %rax      # 0xb1f0
movl 0x30(%rsp), %ecx
movl %ecx, %esi
addl $0x1, %esi
movl %esi, 0x30(%rsp)
movslq %ecx, %rcx
movb %dl, (%rax,%rcx)
jmp 0x417c
jmp 0x414e
movq 0x705b(%rip), %rax      # 0xb1b0
movslq 0x2c(%rsp), %rcx
movl (%rax,%rcx,4), %eax
addl $0x30, %eax
movb %al, %dl
movq 0x7087(%rip), %rax      # 0xb1f0
movl 0x30(%rsp), %ecx
movl %ecx, %esi
addl $0x1, %esi
movl %esi, 0x30(%rsp)
movslq %ecx, %rcx
movb %dl, (%rax,%rcx)
movl 0x2c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x2c(%rsp)
jmp 0x3f0a
jmp 0x418e
movl 0x2c(%rsp), %eax
cmpl 0x7030(%rip), %eax      # 0xb1c8
jge 0x41d5
movq 0x700f(%rip), %rax      # 0xb1b0
movslq 0x2c(%rsp), %rcx
movl (%rax,%rcx,4), %eax
addl $0x30, %eax
movb %al, %dl
movq 0x703b(%rip), %rax      # 0xb1f0
movl 0x30(%rsp), %ecx
movl %ecx, %esi
addl $0x1, %esi
movl %esi, 0x30(%rsp)
movslq %ecx, %rcx
movb %dl, (%rax,%rcx)
movl 0x2c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x2c(%rsp)
jmp 0x418e
cmpl $0x0, 0x30(%rsp)
jle 0x4206
movq 0x700d(%rip), %rax      # 0xb1f0
movslq 0x30(%rsp), %rcx
movb $0x0, (%rax,%rcx)
movq 0x48(%rsp), %rdi
movq 0x6ff8(%rip), %rdx      # 0xb1f0
leaq 0x3e6f(%rip), %rsi      # 0x806e
movb $0x0, %al
callq 0x2200
movq 0x48(%rsp), %rdi
callq 0x2180
addq $0x58, %rsp
retq
nopw %cs:(%rax,%rax)