// File: /workspace/github_cpp_makefile_star2_O2/chhylp123[P]hifiasm/inter.cpp
// Function: quick_rechain(overlap_region_alloc*, ul_ov_t*, long, kv_rtrace_t*, ul_idx_t const*, ug_opt_t const*, long, double, long, long, long, long, bit_extz_t*, long, All_reads*, char*, UC_Read*, double, int*, int*, int*, int*, long*, long*)
int64_t quick_rechain(overlap_region_alloc* ol, ul_ov_t *a, int64_t a_n, kv_rtrace_t *trace, const ul_idx_t *uref, const ug_opt_t *uopt, 
int64_t bw, double diff_ec_ul, int64_t qlen, int64_t max_skip, int64_t max_iter, int64_t max_dis, 
bit_extz_t *exz, int64_t trans_sc, All_reads *ridx, char* qstr, UC_Read *tu, double e_rate, 
int32_t *f, int32_t *c_n, int32_t *c_sc, int32_t *rch, int64_t *p, int64_t *t)
{
	int64_t mm_ovlp, x, i, j, sc, csc, mm_sc, mm_idx, mm_n, sn, n_skip, end_j; 
	ul_ov_t *li, *lj; rtrace_iter tc; int64_t st, max_ii, max, max_n; uint32_t li_v;
	memset(t, 0, (a_n*sizeof((*t)))); 

	for (i = st = 0, max_ii = -1; i < a_n; ++i) {
        li = &(a[i]); li_v = (li->tn<<1)|li->rev; rch[i] = INT32_MAX;
		csc = li->qe - li->qs; csc -= (((int64_t)li->sec)*trans_sc);
        mm_sc = INT32_MIN; mm_idx = -1; mm_n = 0; 
        n_skip = 0; end_j = -1; tc.k = INT32_MAX;
		// if((i>=15) && (rch_connect(rch[15], 18))) {
		// 	fprintf(stderr, ">>>[i::%ld] (id::%u)%.*s\t%c\trch[i]::%d\n", i, li->tn,
		// 				(int)Get_NAME_LENGTH(R_INF, a[i].tn), Get_NAME(R_INF, a[i].tn), 
		// 				"+-"[a[i].rev], rch[15]);
		// }
		if(li->el) {
			mm_ovlp = max_ovlp_src_contain(uopt, li_v^1);        
			x = (li->qs + mm_ovlp)*diff_ec_ul; 
			if(x < bw) x = bw; 
			x += li->qs + mm_ovlp;
			if (x > qlen+1) x = qlen+1;
			x = find_ul_ov_max(i, a, x+G_CHAIN_INDEL); 
			if ((x-st) > max_iter) st = x-max_iter;
			for (j = x; j >= st; --j) { // collect potential destination vertices
				lj = &(a[j]); 
				rch[j] = (i<<2); rch[j] += 3;//set it to unaviable
				// if((i>=15) && (rch_connect(rch[15], 18))) {
				// 	fprintf(stderr, "**j::%ld**[i::%ld] (id::%u)%.*s\t%c\trch[i]::%d\n", j, i, li->tn,
				// 				(int)Get_NAME_LENGTH(R_INF, a[i].tn), Get_NAME(R_INF, a[i].tn), 
				// 				"+-"[a[i].rev], rch[15]);
				// }
				if(!(lj->el)) continue;
				if(lj->qe <= li->qs) break;//even this pair has a overlap, its length will be very small; just ignore
				if(lj->qs > li->qs) continue;///no contain
				sc = quick_rechain_sc(a, ol, uref, uopt, bw, diff_ec_ul, ridx, trace, qstr, tu, 
				&tc, e_rate, exz, trans_sc, f, i, j);
				if(sc == INT32_MIN) continue;
				// if(li->tn == 23989) {
				// 	fprintf(stderr, "*[i::%ld] (id::%u)%.*s\t%c\tj::%ld\t%.*s\n", i, li->tn,
				// 		(int)Get_NAME_LENGTH(R_INF, a[i].tn), Get_NAME(R_INF, a[i].tn), 
				// 		"+-"[a[i].rev], j, (int)Get_NAME_LENGTH(R_INF, lj->tn), Get_NAME(R_INF, lj->tn));
				// }
				rch[j] = (i<<2);//set it to aviable
				sn = c_n[j] + 1;
				if((sc > mm_sc) || ((sc == mm_sc) && (sn > mm_n))) {
					mm_sc = sc, mm_idx = j; mm_n = sn; 
					if (n_skip > 0) --n_skip;
				} else if (t[j] == i) {
					if (++n_skip > max_skip)
						break;
				}
				if (p[j] >= 0) t[p[j]] = i;
			}
			// if((i>=15) && (rch_connect(rch[15], 18))) {
			// 	fprintf(stderr, ">>>1[i::%ld] (id::%u)%.*s\t%c\trch[i]::%d\n", i, li->tn,
			// 				(int)Get_NAME_LENGTH(R_INF, a[i].tn), Get_NAME(R_INF, a[i].tn), 
			// 				"+-"[a[i].rev], rch[15]);
			// }

			end_j = j;
			if (max_ii < 0 || (a[i].qe>(a[max_ii].qe+max_dis))) {//too long
				max = INT32_MIN; max_n = INT32_MIN; max_ii = -1;
				for (j = i - 1; (j >= st) && (a[i].qe<=(max_dis+a[j].qe)); --j) {
					if ((max < f[j]) || ((max == f[j]) && (max_n < c_n[j]))) {
						max = f[j]; max_n = c_n[j]; max_ii = j;
					}
				}
			}
			// if((i>=15) && (rch_connect(rch[15], 18))) {
			// 	fprintf(stderr, ">>>2[i::%ld] (id::%u)%.*s\t%c\trch[i]::%d\n", i, li->tn,
			// 				(int)Get_NAME_LENGTH(R_INF, a[i].tn), Get_NAME(R_INF, a[i].tn), 
			// 				"+-"[a[i].rev], rch[15]);
			// }

			if (max_ii >= 0 && max_ii < end_j) {///just have a try with a[i]<->a[max_ii]
				lj = &(a[max_ii]); 
				if((lj->el) && (lj->qe > li->qs) && (lj->qs <= li->qs)) {
					sc = quick_rechain_sc(a, ol, uref, uopt, bw, diff_ec_ul, ridx, trace, qstr, tu, 
					&tc, e_rate, exz, trans_sc, f, i, max_ii);
					///as max_ii < end_j, get_rid_backward_cigar_err still works
					if(sc != INT32_MIN) {
						sn = c_n[max_ii] + 1;
						if((sc > mm_sc) || ((sc == mm_sc) && (sn > mm_n))) {
							mm_sc = sc; mm_idx = max_ii; mm_n = sn; 
						}
					}
				}
			}
			// if((i>=15) && (rch_connect(rch[15], 18))) {
			// 	fprintf(stderr, ">>>3[i::%ld] (id::%u)%.*s\t%c\trch[i]::%d\n", i, li->tn,
			// 				(int)Get_NAME_LENGTH(R_INF, a[i].tn), Get_NAME(R_INF, a[i].tn), 
			// 				"+-"[a[i].rev], rch[15]);
			// }
			sc = csc; sn = 1;///for i itself
			if((sc > mm_sc) || ((sc == mm_sc) && (sn > mm_n))) {
				mm_sc = sc, mm_idx = -1; mm_n = sn; 
			}

			if(mm_sc < 0) {
				mm_sc = csc; mm_idx = -1; mm_n = 1;
			}
			// if(li->tn == 23989) {
			// 	fprintf(stderr, "+[i::%ld] (id::%u)%.*s\t%c\tj::%ld\t%.*s\n", i, li->tn,
			// 		(int)Get_NAME_LENGTH(R_INF, a[i].tn), Get_NAME(R_INF, a[i].tn), 
			// 		"+-"[a[i].rev], mm_idx, mm_idx>=0?((int)Get_NAME_LENGTH(R_INF, a[mm_idx].tn)):(1), 
			// 		mm_idx>=0?(Get_NAME(R_INF, a[mm_idx].tn)):("*"));
			// }
			if(mm_idx >= 0) {
				///mo meed to update mm_sc and is_fc
				quick_rechain_propagate_transitive_reduction(uref, uopt, ridx, bw, diff_ec_ul, a, x+1, i, rch, f, p, c_n, t, &mm_sc, &mm_idx, &mm_n);
			}
			// if(li->tn == 23989) {
			// 	fprintf(stderr, "-[i::%ld] (id::%u)%.*s\t%c\tj::%ld\t%.*s\n", i, li->tn,
			// 		(int)Get_NAME_LENGTH(R_INF, a[i].tn), Get_NAME(R_INF, a[i].tn), 
			// 		"+-"[a[i].rev], mm_idx, mm_idx>=0?((int)Get_NAME_LENGTH(R_INF, a[mm_idx].tn)):(1), 
			// 		mm_idx>=0?(Get_NAME(R_INF, a[mm_idx].tn)):("*"));
			// }
		}
		f[i] = mm_sc; p[i] = mm_idx; c_n[i] = mm_n; 
		if ((max_ii < 0) || ((a[i].qe<=max_dis+a[max_ii].qe) && (f[max_ii]<f[i]))) {
			max_ii = i;
		}
	}

	int64_t cl = 0; i = a_n-1; 
	while (i >= 0) {
		// fprintf(stderr, "i::%ld[M::%s] (id::%u)%.*s\t%c\tq::[%u, %u)\tt::[%u, %u)\tc::%u\n", 
		// i, __func__, a[i].tn, (int)Get_NAME_LENGTH(R_INF, a[i].tn), Get_NAME(R_INF, a[i].tn), 
		// 			"+-"[a[i].rev], a[i].qs, a[i].qe, a[i].ts, a[i].te, !a[i].el);
        t[cl++] = i; i = p[i];
    }
	return cl;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x148, %rsp            # imm = 0x148
movsd %xmm1, 0x80(%rsp)
movsd %xmm0, 0x58(%rsp)
movq %r9, 0x50(%rsp)
movq %r8, 0x60(%rsp)
movq %rcx, 0x78(%rsp)
movq %rdx, %rbx
movq %rsi, %r12
movq %rdi, 0x70(%rsp)
movq 0x1f8(%rsp), %rdi
movq 0x1d8(%rsp), %rbp
movq 0x1a0(%rsp), %r15
movq 0x188(%rsp), %r14
leaq (,%rdx,8), %rdx
xorl %r13d, %r13d
xorl %esi, %esi
callq 0x20e0
movq %r15, %r11
movq 0x1d0(%rsp), %r10
incq %r14
movq %r14, 0xa0(%rsp)
testq %rbx, %rbx
movl $0x0, %edi
movq %rbx, 0x90(%rsp)
cmovgq %rbx, %rdi
leaq 0x4(%r12), %rax
movq %rax, 0x98(%rsp)
leaq -0x14(%r12), %rax
movq %rax, 0xa8(%rsp)
pushq $-0x1
popq %rbx
xorl %r15d, %r15d
movq %r12, 0x88(%rsp)
movq %rdi, 0x40(%rsp)
cmpq %rdi, %r13
je 0x17448e
imulq $0x1c, %r13, %rdx
leaq (%r12,%rdx), %r8
movl 0xc(%r12,%rdx), %esi
movl 0x18(%r12,%rdx), %eax
movq 0x1e8(%rsp), %rcx
movl $0x7fffffff, (%rcx,%r13,4) # imm = 0x7FFFFFFF
movl 0x8(%r12,%rdx), %r9d
movl 0x18(%r12,%rdx), %ecx
subl 0x4(%r12,%rdx), %r9d
movq $0x7fffffff, 0xb0(%rsp) # imm = 0x7FFFFFFF
btl $0x1e, %ecx
jb 0x173e3d
movq $-0x80000000, %rdx      # imm = 0x80000000
xorl %r14d, %r14d
pushq $-0x1
popq %rsi
jmp 0x1743e3
movq %r9, %rdx
movq %rbx, 0x20(%rsp)
andl $0x3fffffff, %ecx       # imm = 0x3FFFFFFF
imulq 0x1b0(%rsp), %rcx
subq %rcx, %rdx
movq %rdx, 0x28(%rsp)
shldl $0x1, %eax, %esi
xorl $0x1, %esi
movq 0x50(%rsp), %rdi
movq %r8, 0x8(%rsp)
callq 0x173810
movq 0x8(%rsp), %rcx
movl 0x4(%rcx), %ecx
addq %rax, %rcx
cvtsi2sd %rcx, %xmm0
mulsd 0x58(%rsp), %xmm0
cvttsd2si %xmm0, %rdx
movq 0x180(%rsp), %rax
cmpq %rax, %rdx
cmovleq %rax, %rdx
addq %rcx, %rdx
movq 0xa0(%rsp), %rax
cmpq %rax, %rdx
cmovgeq %rax, %rdx
subl $-0x80, %edx
movl %r13d, %edi
movq %r12, %rsi
callq 0x160717
movq 0x8(%rsp), %r8
movq 0x1a0(%rsp), %r11
movq 0x1d0(%rsp), %r10
movq 0x1e8(%rsp), %r9
movl %eax, 0x68(%rsp)
movslq %eax, %rbx
movq %rbx, %rax
subq %r15, %rax
movq %rbx, %rcx
movq 0x198(%rsp), %rdx
subq %rdx, %rcx
cmpq %rdx, %rax
cmovgq %rcx, %r15
leal (,%r13,4), %eax
movl %eax, 0x6c(%rsp)
movq %r13, 0x10(%rsp)
leal 0x3(,%r13,4), %ebp
imulq $0x1c, %rbx, %r12
addq 0x98(%rsp), %r12
movq $-0x80000000, 0x18(%rsp) # imm = 0x80000000
pushq $-0x1
popq %rsi
xorl %r14d, %r14d
movq $0x0, 0x48(%rsp)
cmpq %r15, %rbx
jl 0x1740f6
movl %ebp, (%r9,%rbx,4)
testb $0x40, 0x17(%r12)
je 0x173f62
movl 0x4(%r8), %eax
cmpl %eax, 0x4(%r12)
jbe 0x1740f6
cmpl %eax, (%r12)
jbe 0x173f71
movq %r14, %rcx
decq %rbx
addq $-0x1c, %r12
movq %rcx, %r14
jmp 0x173f38
movq %rsi, %r13
subq $0x8, %rsp
movq 0x90(%rsp), %rdi
movq 0x78(%rsp), %rsi
movq 0x68(%rsp), %rdx
movq 0x58(%rsp), %rcx
movq 0x188(%rsp), %r8
movsd 0x60(%rsp), %xmm0
movq 0x1c0(%rsp), %r9
movsd 0x88(%rsp), %xmm1
pushq %rbx
pushq 0x20(%rsp)
pushq %r10
pushq 0x1d0(%rsp)
pushq 0x1d0(%rsp)
leaq 0xe0(%rsp), %rax
pushq %rax
pushq 0x200(%rsp)
pushq 0x200(%rsp)
pushq 0xc0(%rsp)
callq 0x173923
addq $0x50, %rsp
cmpq $-0x80000000, %rax      # imm = 0x80000000
jne 0x17401a
movq %r14, %rcx
movq 0x1e8(%rsp), %r9
movq 0x1d0(%rsp), %r10
movq 0x1a0(%rsp), %r11
movq 0x8(%rsp), %r8
movq %r13, %rsi
jmp 0x173f65
movq 0x1e8(%rsp), %r9
movl 0x6c(%rsp), %ecx
movl %ecx, (%r9,%rbx,4)
movq 0x1d8(%rsp), %rcx
movslq (%rcx,%rbx,4), %rcx
incq %rcx
cmpq 0x18(%rsp), %rax
jg 0x174047
jne 0x1740aa
cmpq %rcx, %r14
jge 0x1740aa
xorl %edx, %edx
movq 0x48(%rsp), %rsi
testq %rsi, %rsi
setg %dl
subq %rdx, %rsi
movq %rsi, 0x48(%rsp)
movq %rbx, %rsi
movq %rax, 0x18(%rsp)
movq 0x1d0(%rsp), %r10
movq 0x1a0(%rsp), %r11
movq 0x8(%rsp), %r8
movq 0x1f0(%rsp), %rax
movq (%rax,%rbx,8), %rax
testq %rax, %rax
js 0x173f65
movq 0x1f8(%rsp), %rdx
movq %rsi, %rdi
movq 0x10(%rsp), %rsi
movq %rsi, (%rdx,%rax,8)
movq %rdi, %rsi
jmp 0x173f65
movq 0x1f8(%rsp), %rax
movq 0x10(%rsp), %rcx
cmpq %rcx, (%rax,%rbx,8)
movq 0x1d0(%rsp), %r10
movq 0x1a0(%rsp), %r11
movq 0x8(%rsp), %r8
jne 0x1740ee
movq 0x48(%rsp), %rax
cmpq 0x190(%rsp), %rax
movq %r13, %rsi
jge 0x1740f6
incq 0x48(%rsp)
movq %r14, %rcx
jmp 0x174079
movq %r14, %rcx
movq %r13, %rsi
jmp 0x174079
movq %r14, 0x30(%rsp)
movq %rsi, 0x38(%rsp)
movq 0x20(%rsp), %rdx
testq %rdx, %rdx
movq 0x88(%rsp), %r12
movq 0x1d8(%rsp), %rbp
js 0x174133
movl 0x8(%r8), %eax
imulq $0x1c, %rdx, %rcx
movl 0x8(%r12,%rcx), %ecx
addq %r11, %rcx
cmpq %rax, %rcx
jge 0x1741d5
movq %rsi, %r13
movq $-0x80000000, %rcx      # imm = 0x80000000
movq 0x10(%rsp), %rax
pushq $-0x1
popq %rdx
movq %rdx, 0x20(%rsp)
movq $-0x80000000, %rdx      # imm = 0x80000000
imulq $0x1c, %rax, %rsi
decq %rax
addq 0xa8(%rsp), %rsi
leaq 0x1(%rax), %rdi
cmpq %r15, %rdi
jle 0x1741c1
movl 0x8(%r8), %edi
movl (%rsi), %r8d
addq %r11, %r8
cmpq %rdi, %r8
jl 0x1741c8
movslq (%r10,%rax,4), %rdi
cmpq %rdi, %rcx
jl 0x17419b
jne 0x17418d
movslq (%rbp,%rax,4), %r8
cmpq %r8, %rdx
jl 0x1741af
decq %rax
addq $-0x1c, %rsi
movq 0x8(%rsp), %r8
jmp 0x174160
movslq (%rbp,%rax,4), %rdx
movq %rax, 0x20(%rsp)
movq %rdi, %rcx
movq 0x8(%rsp), %r8
jmp 0x174151
movq %rax, 0x20(%rsp)
movq %rdi, %rcx
movq %r8, %rdx
movq 0x8(%rsp), %r8
jmp 0x174151
movq 0x20(%rsp), %rdx
jmp 0x1741d2
movq 0x20(%rsp), %rdx
movq 0x8(%rsp), %r8
movq %r13, %rsi
testq %rdx, %rdx
js 0x1742c5
cmpq %rbx, %rdx
movq %rdx, %rbx
jge 0x1742c8
imulq $0x1c, %rbx, %rax
testb $0x40, 0x1b(%r12,%rax)
movq 0x28(%rsp), %rdx
je 0x1742cd
addq %r12, %rax
movl 0x4(%r8), %ecx
cmpl %ecx, 0x8(%rax)
jbe 0x1742cd
cmpl %ecx, 0x4(%rax)
ja 0x1742cd
movq %r15, %r13
movq %rsi, %r15
subq $0x8, %rsp
movq %r12, %rdi
movq 0x78(%rsp), %rsi
movq 0x68(%rsp), %rdx
movq 0x58(%rsp), %rcx
movq 0x188(%rsp), %r8
movsd 0x60(%rsp), %xmm0
movq 0x1c0(%rsp), %r9
movsd 0x88(%rsp), %xmm1
pushq %rbx
pushq 0x20(%rsp)
pushq %r10
pushq 0x1d0(%rsp)
pushq 0x1d0(%rsp)
leaq 0xe0(%rsp), %rax
pushq %rax
pushq 0x200(%rsp)
pushq 0x200(%rsp)
pushq 0xc0(%rsp)
callq 0x173923
addq $0x50, %rsp
cmpq $-0x80000000, %rax      # imm = 0x80000000
jne 0x17442e
movq 0x1e8(%rsp), %r9
movq 0x1d0(%rsp), %r10
movq 0x1a0(%rsp), %r11
movq 0x8(%rsp), %r8
movq 0x28(%rsp), %rdx
movq %r15, %rsi
movq %r13, %r15
jmp 0x1742cd
movq %rdx, %rbx
movq 0x28(%rsp), %rdx
cmpq 0x18(%rsp), %rdx
jg 0x1742db
jne 0x1742f8
testq %r14, %r14
jg 0x1742f8
orq $-0x1, 0x38(%rsp)
movq $0x1, 0x30(%rsp)
testq %rdx, %rdx
jns 0x1743d2
jmp 0x1743c3
cmpq $0x0, 0x18(%rsp)
js 0x1743c3
testq %rsi, %rsi
js 0x174427
movl 0x68(%rsp), %r8d
incl %r8d
subq $0x50, %rsp
leaq 0x80(%rsp), %rax
movq %rax, 0x40(%rsp)
leaq 0x88(%rsp), %rax
movq %rax, 0x38(%rsp)
movq 0x248(%rsp), %rax
movq %rax, 0x28(%rsp)
movq %rbp, 0x20(%rsp)
movq 0x240(%rsp), %rax
movq %rax, 0x18(%rsp)
movq %r9, 0x8(%rsp)
movq 0x60(%rsp), %r13
movq %r13, (%rsp)
movq 0xb0(%rsp), %rdi
movq 0xa0(%rsp), %rsi
movq 0x208(%rsp), %rdx
movq 0x1d0(%rsp), %rcx
movsd 0xa8(%rsp), %xmm0
movl %r8d, %r9d
movq %r12, %r8
callq 0x173a98
movq 0x58(%rsp), %r8
movq 0x1f0(%rsp), %r11
movq 0x220(%rsp), %r10
addq $0x50, %rsp
movq 0x38(%rsp), %rsi
movq 0x30(%rsp), %r14
movq 0x18(%rsp), %rdx
movq 0x40(%rsp), %rdi
jmp 0x1743e3
orq $-0x1, 0x38(%rsp)
movq $0x1, 0x30(%rsp)
pushq $0x1
popq %r14
pushq $-0x1
popq %rsi
movq 0x40(%rsp), %rdi
movq 0x10(%rsp), %r13
movl %edx, (%r10,%r13,4)
movq 0x1f0(%rsp), %rax
movq %rsi, (%rax,%r13,8)
movl %r14d, (%rbp,%r13,4)
testq %rbx, %rbx
js 0x17441c
movl 0x8(%r8), %eax
imulq $0x1c, %rbx, %rcx
movl 0x8(%r12,%rcx), %ecx
addq %r11, %rcx
cmpq %rax, %rcx
jl 0x17441f
movl (%r10,%rbx,4), %eax
cmpl (%r10,%r13,4), %eax
jge 0x17441f
movq %r13, %rbx
incq %r13
jmp 0x173ddf
movq 0x18(%rsp), %rdx
jmp 0x1743d9
movslq (%rbp,%rbx,4), %rcx
incq %rcx
cmpq 0x18(%rsp), %rax
movq 0x1e8(%rsp), %r9
movq 0x1d0(%rsp), %r10
movq 0x1a0(%rsp), %r11
movq 0x8(%rsp), %r8
movq 0x28(%rsp), %rdx
movq %r15, %rsi
movq %r13, %r15
jg 0x174474
jne 0x1742cd
cmpq %rcx, %r14
jge 0x1742cd
movq %rbx, 0x38(%rsp)
movq %rcx, 0x30(%rsp)
movq %rbx, %rsi
movq %rcx, %r14
movq %rax, 0x18(%rsp)
jmp 0x1742cd
movq 0x90(%rsp), %rcx
decq %rcx
xorl %eax, %eax
testq %rcx, %rcx
js 0x1744bd
movq 0x1f8(%rsp), %rdx
movq %rcx, (%rdx,%rax,8)
incq %rax
movq 0x1f0(%rsp), %rdx
movq (%rdx,%rcx,8), %rcx
jmp 0x17449b
addq $0x148, %rsp            # imm = 0x148
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq