// File: chhylp123[P]hifiasm/Overlaps.cpp
// Function: try_rescue_overlaps(ma_hit_t_alloc*, ma_hit_t_alloc*, unsigned long, unsigned long, unsigned int)
void try_rescue_overlaps(ma_hit_t_alloc* paf, ma_hit_t_alloc* rev, uint64_t rn, uint64_t rescue_threshold, uint32_t is_del)
{
    double startTime = Get_T();
    int64_t revises = 0, dd, dp, old_dp, start, max_dp, m; uint32_t qn, tn, qs, qe; uint64_t ff, i, j; ma_sub_t max_interval; 
    kvec_t(uint64_t) ev; kv_init(ev);
    kvec_t(uint64_t) evi; kv_init(evi);
    kvec_t(uint32_t) b; kv_init(b);
    
    for (i = 0; i < rn; i++) {
        ev.n = evi.n = 0;
        for (j = 0; j < rev[i].length; j++) {
            if(is_del && rev[i].buffer[j].del) continue;
            qn = Get_qn(rev[i].buffer[j]); tn = Get_tn(rev[i].buffer[j]);
            dd = get_specific_overlap(&(paf[tn]), tn, qn);
            if((dd != -1) && ((!is_del) || (paf[tn].buffer[dd].del == 0))) {
                ff = tn; ff <<= 32; ff |= (uint64_t)(dd);
                kv_push(uint64_t, ev, ff); kv_push(uint64_t, evi, j);
            }
        }

        ///based on qn, all edges at edge_vector/edge_vector_index come from different haplotype
        ///but at another direction, all these edges come from the same haplotype
        //here we want to recover these edges
        if(evi.n >= rescue_threshold) {
            kv_resize(uint32_t, b, evi.n); b.n = 0;
            for (j = 0; j < evi.n; j++) {
                qs = Get_qs(rev[i].buffer[evi.a[j]]);
                qe = Get_qe(rev[i].buffer[evi.a[j]]);
                kv_push(uint32_t, b, qs<<1);
                kv_push(uint32_t, b, qe<<1|1);
            }

            ks_introsort_uint32_t(b.n, b.a);
            dp = 0, start = 0, max_dp = 0;
            max_interval.s = max_interval.e = 0;
            for (j = 0, dp = 0; j < b.n; ++j)  {
                old_dp = dp;
                ///if a[j] is qe
                if (b.a[j]&1) --dp;
                else ++dp;
                
                if(old_dp < dp) {///b.a[j] is qs
                    ///case 2, a[j] is qs
                    //here should use dp >= max_dp, instead of dp > max_dp
                    if(dp >= max_dp) {
                        start = b.a[j]>>1;
                        max_dp = dp;
                    }
                } else if (old_dp > dp) {///old_dp > min_dp, b.a[j] is qe
                    if(old_dp == max_dp) {
                        max_interval.s = start;
                        max_interval.e = b.a[j]>>1;
                    }
                }
            }

            if(((uint64_t)max_dp) >= rescue_threshold) {
                m = 0;
                for (j = 0; j < evi.n; j++) {
                    qs = Get_qs(rev[i].buffer[evi.a[j]]);
                    qe = Get_qe(rev[i].buffer[evi.a[j]]);
                    if(qs <= max_interval.s && qe >= max_interval.e) {
                        evi.a[m] = evi.a[j]; ev.a[m] = ev.a[j]; m++;
                    }
                }
                evi.n = ev.n = m;

                ///the read itself do not have these overlaps, but all related reads have
                ///we need to remove all overlaps from rev_paf[i], and then add all overlaps to paf[i]
                remove_overlaps(&(rev[i]), evi.a, evi.n);
                add_overlaps_from_different_sources(paf, &(paf[i]), ev.a, ev.n);
                revises = revises + ev.n;
            }
        }
    }

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x110, %rsp            # imm = 0x110
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq %rcx, -0x20(%rbp)
movl %r8d, -0x24(%rbp)
callq 0x2510
movsd %xmm0, -0x30(%rbp)
movq $0x0, -0x38(%rbp)
movq $0x0, -0xb0(%rbp)
movq $0x0, -0xb8(%rbp)
movq $0x0, -0xa8(%rbp)
movq $0x0, -0xc8(%rbp)
movq $0x0, -0xd0(%rbp)
movq $0x0, -0xc0(%rbp)
movq $0x0, -0xe0(%rbp)
movq $0x0, -0xe8(%rbp)
movq $0x0, -0xd8(%rbp)
movq $0x0, -0x88(%rbp)
movq -0x88(%rbp), %rax
cmpq -0x18(%rbp), %rax
jae 0x150713
movq $0x0, -0xd0(%rbp)
movq $0x0, -0xb8(%rbp)
movq $0x0, -0x90(%rbp)
movq -0x90(%rbp), %rax
movq -0x10(%rbp), %rcx
imulq $0x18, -0x88(%rbp), %rdx
addq %rdx, %rcx
movl 0xc(%rcx), %ecx
cmpq %rcx, %rax
jae 0x15017f
cmpl $0x0, -0x24(%rbp)
je 0x14ff88
movq -0x10(%rbp), %rax
imulq $0x18, -0x88(%rbp), %rcx
addq %rcx, %rax
movq (%rax), %rax
imulq $0x28, -0x90(%rbp), %rcx
addq %rcx, %rax
movq 0x18(%rax), %rax
shrq $0x3f, %rax
cmpl $0x0, %eax
je 0x14ff88
jmp 0x150168
movq -0x10(%rbp), %rax
imulq $0x18, -0x88(%rbp), %rcx
addq %rcx, %rax
movq (%rax), %rax
imulq $0x28, -0x90(%rbp), %rcx
addq %rcx, %rax
movq (%rax), %rax
shrq $0x20, %rax
movl %eax, -0x6c(%rbp)
movq -0x10(%rbp), %rax
imulq $0x18, -0x88(%rbp), %rcx
addq %rcx, %rax
movq (%rax), %rax
imulq $0x28, -0x90(%rbp), %rcx
addq %rcx, %rax
movl 0xc(%rax), %eax
movl %eax, -0x70(%rbp)
movq -0x8(%rbp), %rdi
movl -0x70(%rbp), %eax
imulq $0x18, %rax, %rax
addq %rax, %rdi
movl -0x70(%rbp), %esi
movl -0x6c(%rbp), %edx
callq 0xce1b0
movq %rax, -0x40(%rbp)
cmpq $-0x1, -0x40(%rbp)
je 0x150166
cmpl $0x0, -0x24(%rbp)
je 0x15002a
movq -0x8(%rbp), %rax
movl -0x70(%rbp), %ecx
imulq $0x18, %rcx, %rcx
addq %rcx, %rax
movq (%rax), %rax
imulq $0x28, -0x40(%rbp), %rcx
addq %rcx, %rax
movq 0x18(%rax), %rax
shrq $0x3f, %rax
cmpl $0x0, %eax
jne 0x150166
movl -0x70(%rbp), %eax
movq %rax, -0x80(%rbp)
movq -0x80(%rbp), %rax
shlq $0x20, %rax
movq %rax, -0x80(%rbp)
movq -0x40(%rbp), %rax
orq -0x80(%rbp), %rax
movq %rax, -0x80(%rbp)
movq -0xb8(%rbp), %rax
cmpq -0xb0(%rbp), %rax
jne 0x1500b0
cmpq $0x0, -0xb0(%rbp)
je 0x150076
movq -0xb0(%rbp), %rax
shlq %rax
movq %rax, -0xf0(%rbp)
jmp 0x150084
movl $0x2, %eax
movq %rax, -0xf0(%rbp)
jmp 0x150084
movq -0xf0(%rbp), %rax
movq %rax, -0xb0(%rbp)
movq -0xa8(%rbp), %rdi
movq -0xb0(%rbp), %rsi
shlq $0x3, %rsi
callq 0x2360
movq %rax, -0xa8(%rbp)
movq -0x80(%rbp), %rdx
movq -0xa8(%rbp), %rax
movq -0xb8(%rbp), %rcx
movq %rcx, %rsi
addq $0x1, %rsi
movq %rsi, -0xb8(%rbp)
movq %rdx, (%rax,%rcx,8)
jmp 0x1500d6
movq -0xd0(%rbp), %rax
cmpq -0xc8(%rbp), %rax
jne 0x15013d
cmpq $0x0, -0xc8(%rbp)
je 0x150103
movq -0xc8(%rbp), %rax
shlq %rax
movq %rax, -0xf8(%rbp)
jmp 0x150111
movl $0x2, %eax
movq %rax, -0xf8(%rbp)
jmp 0x150111
movq -0xf8(%rbp), %rax
movq %rax, -0xc8(%rbp)
movq -0xc0(%rbp), %rdi
movq -0xc8(%rbp), %rsi
shlq $0x3, %rsi
callq 0x2360
movq %rax, -0xc0(%rbp)
movq -0x90(%rbp), %rdx
movq -0xc0(%rbp), %rax
movq -0xd0(%rbp), %rcx
movq %rcx, %rsi
addq $0x1, %rsi
movq %rsi, -0xd0(%rbp)
movq %rdx, (%rax,%rcx,8)
jmp 0x150166
jmp 0x150168
movq -0x90(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x90(%rbp)
jmp 0x14ff31
movq -0xd0(%rbp), %rax
cmpq -0x20(%rbp), %rax
jb 0x1506fa
jmp 0x150192
movq -0xe0(%rbp), %rax
cmpq -0xd0(%rbp), %rax
jae 0x150272
movq -0xd0(%rbp), %rax
movq %rax, -0xe0(%rbp)
movq -0xe0(%rbp), %rax
addq $-0x1, %rax
movq %rax, -0xe0(%rbp)
movq -0xe0(%rbp), %rax
shrq %rax
orq -0xe0(%rbp), %rax
movq %rax, -0xe0(%rbp)
movq -0xe0(%rbp), %rax
shrq $0x2, %rax
orq -0xe0(%rbp), %rax
movq %rax, -0xe0(%rbp)
movq -0xe0(%rbp), %rax
shrq $0x4, %rax
orq -0xe0(%rbp), %rax
movq %rax, -0xe0(%rbp)
movq -0xe0(%rbp), %rax
shrq $0x8, %rax
orq -0xe0(%rbp), %rax
movq %rax, -0xe0(%rbp)
movq -0xe0(%rbp), %rax
shrq $0x10, %rax
orq -0xe0(%rbp), %rax
movq %rax, -0xe0(%rbp)
movq -0xe0(%rbp), %rax
addq $0x1, %rax
movq %rax, -0xe0(%rbp)
movq -0xd8(%rbp), %rdi
movq -0xe0(%rbp), %rsi
shlq $0x2, %rsi
callq 0x2360
movq %rax, -0xd8(%rbp)
jmp 0x150274
movq $0x0, -0xe8(%rbp)
movq $0x0, -0x90(%rbp)
movq -0x90(%rbp), %rax
cmpq -0xd0(%rbp), %rax
jae 0x15042e
movq -0x10(%rbp), %rax
imulq $0x18, -0x88(%rbp), %rcx
addq %rcx, %rax
movq (%rax), %rax
movq -0xc0(%rbp), %rcx
movq -0x90(%rbp), %rdx
imulq $0x28, (%rcx,%rdx,8), %rcx
addq %rcx, %rax
movq (%rax), %rax
movl %eax, -0x74(%rbp)
movq -0x10(%rbp), %rax
imulq $0x18, -0x88(%rbp), %rcx
addq %rcx, %rax
movq (%rax), %rax
movq -0xc0(%rbp), %rcx
movq -0x90(%rbp), %rdx
imulq $0x28, (%rcx,%rdx,8), %rcx
addq %rcx, %rax
movl 0x8(%rax), %eax
movl %eax, -0x78(%rbp)
movq -0xe8(%rbp), %rax
cmpq -0xe0(%rbp), %rax
jne 0x150361
cmpq $0x0, -0xe0(%rbp)
je 0x150327
movq -0xe0(%rbp), %rax
shlq %rax
movq %rax, -0x100(%rbp)
jmp 0x150335
movl $0x2, %eax
movq %rax, -0x100(%rbp)
jmp 0x150335
movq -0x100(%rbp), %rax
movq %rax, -0xe0(%rbp)
movq -0xd8(%rbp), %rdi
movq -0xe0(%rbp), %rsi
shlq $0x2, %rsi
callq 0x2360
movq %rax, -0xd8(%rbp)
movl -0x74(%rbp), %edx
shll %edx
movq -0xd8(%rbp), %rax
movq -0xe8(%rbp), %rcx
movq %rcx, %rsi
addq $0x1, %rsi
movq %rsi, -0xe8(%rbp)
movl %edx, (%rax,%rcx,4)
jmp 0x150387
movq -0xe8(%rbp), %rax
cmpq -0xe0(%rbp), %rax
jne 0x1503ee
cmpq $0x0, -0xe0(%rbp)
je 0x1503b4
movq -0xe0(%rbp), %rax
shlq %rax
movq %rax, -0x108(%rbp)
jmp 0x1503c2
movl $0x2, %eax
movq %rax, -0x108(%rbp)
jmp 0x1503c2
movq -0x108(%rbp), %rax
movq %rax, -0xe0(%rbp)
movq -0xd8(%rbp), %rdi
movq -0xe0(%rbp), %rsi
shlq $0x2, %rsi
callq 0x2360
movq %rax, -0xd8(%rbp)
movl -0x78(%rbp), %edx
shll %edx
orl $0x1, %edx
movq -0xd8(%rbp), %rax
movq -0xe8(%rbp), %rcx
movq %rcx, %rsi
addq $0x1, %rsi
movq %rsi, -0xe8(%rbp)
movl %edx, (%rax,%rcx,4)
jmp 0x150417
movq -0x90(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x90(%rbp)
jmp 0x15028a
movq -0xe8(%rbp), %rdi
movq -0xd8(%rbp), %rsi
callq 0xcb330
movq $0x0, -0x48(%rbp)
movq $0x0, -0x58(%rbp)
movq $0x0, -0x60(%rbp)
movl $0x0, -0x98(%rbp)
movl -0x9c(%rbp), %eax
andl $0x80000000, %eax       # imm = 0x80000000
orl $0x0, %eax
movl %eax, -0x9c(%rbp)
movq $0x0, -0x90(%rbp)
movq $0x0, -0x48(%rbp)
movq -0x90(%rbp), %rax
cmpq -0xe8(%rbp), %rax
jae 0x150579
movq -0x48(%rbp), %rax
movq %rax, -0x50(%rbp)
movq -0xd8(%rbp), %rax
movq -0x90(%rbp), %rcx
movl (%rax,%rcx,4), %eax
andl $0x1, %eax
cmpl $0x0, %eax
je 0x1504cd
movq -0x48(%rbp), %rax
addq $-0x1, %rax
movq %rax, -0x48(%rbp)
jmp 0x1504d9
movq -0x48(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x48(%rbp)
movq -0x50(%rbp), %rax
cmpq -0x48(%rbp), %rax
jge 0x150510
movq -0x48(%rbp), %rax
cmpq -0x60(%rbp), %rax
jl 0x15050e
movq -0xd8(%rbp), %rax
movq -0x90(%rbp), %rcx
movl (%rax,%rcx,4), %eax
shrl %eax
movl %eax, %eax
movq %rax, -0x58(%rbp)
movq -0x48(%rbp), %rax
movq %rax, -0x60(%rbp)
jmp 0x150560
movq -0x50(%rbp), %rax
cmpq -0x48(%rbp), %rax
jle 0x15055e
movq -0x50(%rbp), %rax
cmpq -0x60(%rbp), %rax
jne 0x15055c
movq -0x58(%rbp), %rax
movl %eax, %ecx
movl -0x9c(%rbp), %eax
andl $0x7fffffff, %ecx       # imm = 0x7FFFFFFF
andl $0x80000000, %eax       # imm = 0x80000000
orl %ecx, %eax
movl %eax, -0x9c(%rbp)
movq -0xd8(%rbp), %rax
movq -0x90(%rbp), %rcx
movl (%rax,%rcx,4), %eax
shrl %eax
movl %eax, -0x98(%rbp)
jmp 0x15055e
jmp 0x150560
jmp 0x150562
movq -0x90(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x90(%rbp)
jmp 0x15048a
movq -0x60(%rbp), %rax
cmpq -0x20(%rbp), %rax
jb 0x1506f8
movq $0x0, -0x68(%rbp)
movq $0x0, -0x90(%rbp)
movq -0x90(%rbp), %rax
cmpq -0xd0(%rbp), %rax
jae 0x15068f
movq -0x10(%rbp), %rax
imulq $0x18, -0x88(%rbp), %rcx
addq %rcx, %rax
movq (%rax), %rax
movq -0xc0(%rbp), %rcx
movq -0x90(%rbp), %rdx
imulq $0x28, (%rcx,%rdx,8), %rcx
addq %rcx, %rax
movq (%rax), %rax
movl %eax, -0x74(%rbp)
movq -0x10(%rbp), %rax
imulq $0x18, -0x88(%rbp), %rcx
addq %rcx, %rax
movq (%rax), %rax
movq -0xc0(%rbp), %rcx
movq -0x90(%rbp), %rdx
imulq $0x28, (%rcx,%rdx,8), %rcx
addq %rcx, %rax
movl 0x8(%rax), %eax
movl %eax, -0x78(%rbp)
movl -0x74(%rbp), %eax
movl -0x9c(%rbp), %ecx
andl $0x7fffffff, %ecx       # imm = 0x7FFFFFFF
cmpl %ecx, %eax
ja 0x150676
movl -0x78(%rbp), %eax
cmpl -0x98(%rbp), %eax
jb 0x150676
movq -0xc0(%rbp), %rax
movq -0x90(%rbp), %rcx
movq (%rax,%rcx,8), %rdx
movq -0xc0(%rbp), %rax
movq -0x68(%rbp), %rcx
movq %rdx, (%rax,%rcx,8)
movq -0xa8(%rbp), %rax
movq -0x90(%rbp), %rcx
movq (%rax,%rcx,8), %rdx
movq -0xa8(%rbp), %rax
movq -0x68(%rbp), %rcx
movq %rdx, (%rax,%rcx,8)
movq -0x68(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x68(%rbp)
jmp 0x150678
movq -0x90(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x90(%rbp)
jmp 0x15059a
movq -0x68(%rbp), %rax
movq %rax, -0xb8(%rbp)
movq %rax, -0xd0(%rbp)
movq -0x10(%rbp), %rdi
imulq $0x18, -0x88(%rbp), %rax
addq %rax, %rdi
movq -0xc0(%rbp), %rsi
movq -0xd0(%rbp), %rdx
callq 0xcd450
movq -0x8(%rbp), %rdi
movq -0x8(%rbp), %rsi
imulq $0x18, -0x88(%rbp), %rax
addq %rax, %rsi
movq -0xa8(%rbp), %rdx
movq -0xb8(%rbp), %rcx
callq 0xcd540
movq -0x38(%rbp), %rax
addq -0xb8(%rbp), %rax
movq %rax, -0x38(%rbp)
jmp 0x1506fa
jmp 0x1506fc
movq -0x88(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x88(%rbp)
jmp 0x14feff
movq -0xa8(%rbp), %rdi
callq 0x2210
movq -0xc0(%rbp), %rdi
callq 0x2210
movq -0xd8(%rbp), %rdi
callq 0x2210
addq $0x110, %rsp            # imm = 0x110
popq %rbp
retq