// File: /workspace/github_cpp_makefile_star2_O1/chhylp123[P]hifiasm/Correct.cpp
// Function: gen_single_khit(Candidates_list*, long, long, long, long, long, long, long, long, long, long)
int64_t gen_single_khit(Candidates_list *cl, int64_t ch_n, int64_t h_khit, int64_t mode, int64_t qs, int64_t qe, int64_t ts, int64_t te, int64_t max_skip, int64_t max_iter, int64_t rid)
{
    // if(ch_n != 3 || mode != 0 || qs != 171728 || qe != 172258) return 0;
    k_mer_hit *ch_a = cl->list + cl->length; int64_t k, i, j, occ, m, ncn, prefix, suffix, srt = 1;
    prefix = suffix = 0;
    if(mode == 0 || mode == 2) suffix = 1;
    if(mode == 0 || mode == 1) prefix = 1;
    // if(ch_n == 2 && mode == 2 && qe - qs == 2419 && te - ts == 2419) {
        // fprintf(stderr, "[M::%s::mode->%ld] ch_n::%ld, q::[%ld, %ld), t::[%ld, %ld)\n", 
        //     __func__, mode, ch_n, qs, qe, ts, te);
    // }
    
    for (k = occ = m = 0; k < ch_n; k++) {
        // if(ch_n == 2 && mode == 2 && qe - qs == 2419 && te - ts == 2419) {
        // fprintf(stderr, "+i::%ld[M::%s::] x::[%u, %u), y::[%u, %u), cnt::%u\n", k, __func__, 
        //     ch_a[k].self_offset+1-(ch_a[k].cnt&((uint32_t)(0xffu))), ch_a[k].self_offset+1,
        //     ch_a[k].offset+1-(ch_a[k].cnt&((uint32_t)(0xffu))), ch_a[k].offset+1, (ch_a[k].cnt&(0xffu)));
        // }
        if(!(ch_a[k].cnt&(0xffu))) continue;
        occ++;
        if((ch_a[k].cnt&(0xffu)) > 1) occ++;
        ch_a[m++] = ch_a[k];
    }
    ch_n = m; if(!ch_n) return ch_n;
    occ += prefix + suffix;
    // if(ch_n == 2 && mode == 2 && qe - qs == 2419 && te - ts == 2419) {
        // fprintf(stderr, "+[M::%s::] occ::%ld\n", __func__, occ);
    // }

    ncn = occ + cl->length;
    if(cl->size < ncn) {
        cl->size = ncn;
        REALLOC(cl->list, cl->size);
        // cl->list = (k_mer_hit*)realloc(cl->list, (sizeof((*(cl->list)))*cl->length));
    }
    ch_a = cl->list + cl->length; assert((cl->length+occ)<= cl->size);

    k_mer_hit cht;
    ///global or backward
    if(suffix) {
        cht.self_offset = qe;
        cht.offset = te;
        cht.cnt = 1; cht.readID = 1;//make it as primary chain
        cht.strand = 0;
        ch_a[--occ] = cht;
        // fprintf(stderr, "occ::%ld[M::%s::] x::%u, y::%u, cnt::%u, cov::%u\n", occ, __func__, 
        //     cht.self_offset, cht.offset, cht.cnt, cht.readID);
    }
    for (k = ch_n-1; k >= 0; k--) {
        if(!(ch_a[k].cnt&(0xffu))) continue;
        ///end
        cht.self_offset = ch_a[k].self_offset+1;
        cht.offset = ch_a[k].offset+1;
        cht.strand = 0;
        cht.cnt = cht.readID = (ch_a[k].cnt&(0xffu));
        //make it as non-primary chain
        if((ch_a[k].cnt&(0xffu)) < h_khit) cht.readID = cht.cnt + 1;
        ch_a[--occ] = cht;
        // fprintf(stderr, "occ::%ld[M::%s::] x::%u, y::%u, cnt::%u, cov::%u\n", occ, __func__, 
        //     cht.self_offset, cht.offset, cht.cnt, cht.readID);

        if((ch_a[k].cnt&(0xffu)) > 1) {
            ///start
            cht.self_offset = ch_a[k].self_offset+1-(ch_a[k].cnt&(0xffu));
            cht.offset = ch_a[k].offset+1-(ch_a[k].cnt&(0xffu));
            cht.strand = 0;
            cht.cnt = cht.readID = (ch_a[k].cnt&(0xffu));
            //make it as non-primary chain
            if((ch_a[k].cnt&(0xffu)) < h_khit) cht.readID = cht.cnt + 1;
            ch_a[--occ] = cht;
            // fprintf(stderr, "occ::%ld[M::%s::] x::%u, y::%u, cnt::%u, cov::%u\n", occ, __func__, 
            // cht.self_offset, cht.offset, cht.cnt, cht.readID);
        }
    }
    
    if(prefix) { ///global or forward
        cht.self_offset = qs;
        cht.offset = ts;
        cht.cnt = 1; cht.readID = 1;//make it as primary chain
        cht.strand = 0;
        ch_a[--occ] = cht;
        // fprintf(stderr, "occ::%ld[M::%s::] x::%u, y::%u, cnt::%u, cov::%u\n", occ, __func__, 
        //     cht.self_offset, cht.offset, cht.cnt, cht.readID);
    }
    // if(ch_n == 2 && mode == 2 && qe - qs == 2419 && te - ts == 2419) {
        // fprintf(stderr, "-[M::%s::] occ::%ld\n", __func__, occ);
    // }
    // if(!(occ == 0)) {
    //     fprintf(stderr, "[M::%s] rid::%ld, name::%.*s\n", __func__, rid,
    //      (int32_t)UL_INF.nid.a[rid].n, UL_INF.nid.a[rid].a);
    // }
    assert(occ == 0);
    ch_n = occ = ncn - cl->length;
    uint64_t q[2], t[2]; 
    q[0] = q[1] = t[0] = t[1] = (uint64_t)-1;
    if(prefix) {
        q[0] = qs; t[0] = ts;
    }
    if(suffix) {
        q[1] = qe; t[1] = te;
    }

    // for (k = 0; k < ch_n; k++) {
    //     fprintf(stderr, "<i::%ld[M::%s::] x::%u, y::%u, cnt::%u, cov::%u\n", k, __func__, 
    //         ch_a[k].self_offset, ch_a[k].offset, ch_a[k].cnt, ch_a[k].readID);
    // }
    for (k = m = occ = 0; k < ch_n; k++) {
        if((k>0) && (ch_a[k].self_offset==q[0]) && (ch_a[k].offset=t[0])) continue;
        if(((k+1)<ch_n) && (ch_a[k].self_offset==q[1]) && (ch_a[k].offset=t[1])) continue;
        if(m>0) {
            if((ch_a[k].self_offset>ch_a[m-1].self_offset) && (ch_a[k].offset>ch_a[m-1].offset)) {
                occ++;
            }
            if(ch_a[k].self_offset<=ch_a[m-1].self_offset) srt = 0;
        } else {
            occ++;
        }
        ch_a[m++] = ch_a[k];
    }
    ch_n = m;
    if(occ == ch_n) return ch_n;///already colinear
    if(!srt) {
        radix_sort_k_mer_hit_self(ch_a, ch_a + ch_n);
        for (i = 1, j = 0; i <= ch_n; i++) {
            if (i == ch_n || ch_a[i].self_offset != ch_a[j].self_offset) {
                if(i - j > 1) radix_sort_k_mer_hit_off(ch_a+j, ch_a+i);
                j = i;
            }
        }
    }

    // for (k = 0; k < ch_n; k++) {
    //     fprintf(stderr, ">i::%ld[M::%s::] x::%u, y::%u, cnt::%u, cov::%u\n", k, __func__, 
    //         ch_a[k].self_offset, ch_a[k].offset, ch_a[k].cnt, ch_a[k].readID);
    // }
    occ = ch_n;
    ch_n = lchain_simple(ch_a+prefix, ch_n-prefix-suffix, ch_a+prefix, &(cl->chainDP), max_skip, max_iter);
    ch_n += prefix + suffix; if(suffix) ch_a[ch_n-1] = ch_a[occ-1];
    // for (k = 0; k < ch_n; k++) {
    //     fprintf(stderr, "-i::%ld[M::%s::] x::%u, y::%u, cnt::%u, cov::%u\n", k, __func__, 
    //         ch_a[k].self_offset, ch_a[k].offset, ch_a[k].cnt, ch_a[k].readID);
    // }
    
    return ch_n;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x38, %rsp
movq %r9, 0x18(%rsp)
movq %r8, 0x20(%rsp)
movq %rcx, %rbx
movq %rdx, %r15
xorl %r12d, %r12d
testq $-0x3, %rcx
sete %al
xorl %r10d, %r10d
cmpq $0x2, %rcx
setb %cl
testq %rsi, %rsi
movq %rdi, 0x8(%rsp)
jle 0x68796
movq 0x8(%rdi), %rdx
shlq $0x4, %rdx
addq (%rdi), %rdx
xorl %ebp, %ebp
movq %rdx, %rdi
xorl %r14d, %r14d
movzbl 0xc(%rdi), %r8d
testl %r8d, %r8d
je 0x6878b
xorl %r9d, %r9d
cmpl $0x1, %r8d
sete %r9b
subq %r9, %r14
addq $0x2, %r14
leaq 0x1(%rbp), %r8
shlq $0x4, %rbp
movups (%rdi), %xmm0
movups %xmm0, (%rdx,%rbp)
movq %r8, %rbp
addq $0x10, %rdi
decq %rsi
jne 0x6875d
jmp 0x6879b
xorl %r14d, %r14d
xorl %ebp, %ebp
testq %rbp, %rbp
je 0x68905
movb %al, %r12b
movb %cl, %r10b
movq %r10, 0x28(%rsp)
addq %r10, %r12
addq %r12, %r14
movq 0x8(%rsp), %rcx
movq 0x8(%rcx), %r13
addq %r14, %r13
cmpq %r13, 0x10(%rcx)
jge 0x687e7
movq %r13, 0x10(%rcx)
movq 0x8(%rsp), %rax
movq (%rax), %rdi
movq %r13, %rsi
shlq $0x4, %rsi
callq 0x2370
movq 0x8(%rsp), %rcx
movq %rax, (%rcx)
movq %r12, 0x30(%rsp)
movq 0x8(%rcx), %rdx
leaq (%rdx,%r14), %rax
cmpq 0x10(%rcx), %rax
jg 0x68b46
movq 0x78(%rsp), %rax
movq (%rcx), %rcx
shlq $0x4, %rdx
movq %rdx, 0x10(%rsp)
movq %rcx, %rdi
leaq (%rcx,%rdx), %r12
testq $-0x3, %rbx
jne 0x68846
decq %r14
movq %r14, %rcx
shlq $0x4, %rcx
movl $0x1, %edx
movl %edx, (%r12,%rcx)
movl %eax, 0x4(%r12,%rcx)
movq 0x18(%rsp), %rsi
movl %esi, 0x8(%r12,%rcx)
movl %edx, 0xc(%r12,%rcx)
testq %rbp, %rbp
jle 0x6890c
leaq 0x1(%rbp), %rcx
shlq $0x4, %rbp
addq 0x10(%rsp), %rbp
leaq (%rdi,%rbp), %rdx
addq $-0x4, %rdx
movq %rdi, %rbp
movzbl (%rdx), %edi
testq %rdi, %rdi
je 0x688ec
movl -0x8(%rdx), %r8d
movl -0x4(%rdx), %r9d
incl %r9d
incl %r8d
xorl %r10d, %r10d
cmpq %r15, %rdi
setl %r10b
addl %edi, %r10d
leaq -0x1(%r14), %rsi
movq %rsi, %r11
shlq $0x4, %r11
movl %r10d, (%r12,%r11)
movl %r8d, 0x4(%r12,%r11)
movl %r9d, 0x8(%r12,%r11)
movl %edi, 0xc(%r12,%r11)
movzbl (%rdx), %edi
cmpl $0x2, %edi
jb 0x688ef
movl -0x8(%rdx), %esi
movl -0x4(%rdx), %r8d
subl %edi, %r8d
incl %r8d
subl %edi, %esi
incl %esi
xorl %r9d, %r9d
cmpq %r15, %rdi
setl %r9b
addl %edi, %r9d
addq $-0x2, %r14
movq %r14, %r10
shlq $0x4, %r10
movl %r9d, (%r12,%r10)
movl %esi, 0x4(%r12,%r10)
movl %r8d, 0x8(%r12,%r10)
movl %edi, 0xc(%r12,%r10)
movq %r14, %rsi
decq %rcx
addq $-0x10, %rdx
movq %rsi, %r14
cmpq $0x1, %rcx
jg 0x68867
jmp 0x68912
xorl %eax, %eax
jmp 0x68b37
movq %r14, %rsi
movq %rdi, %rbp
movq 0x70(%rsp), %rcx
cmpq $0x1, %rbx
ja 0x6894b
decq %rsi
movq %rsi, %rdx
shlq $0x4, %rdx
movl $0x1, %edi
movl %edi, (%r12,%rdx)
movl %ecx, 0x4(%r12,%rdx)
movq 0x20(%rsp), %r14
movl %r14d, 0x8(%r12,%rdx)
movl %edi, 0xc(%r12,%rdx)
movq 0x18(%rsp), %r11
jmp 0x68955
movq 0x18(%rsp), %r11
movq 0x20(%rsp), %r14
testq %rsi, %rsi
movq 0x8(%rsp), %rdi
jne 0x68b65
movq %rbx, %rsi
andq $-0x3, %rsi
cmpq $0x2, %rbx
movl $0xffffffff, %edx       # imm = 0xFFFFFFFF
cmovbl %ecx, %edx
xorl %ecx, %ecx
negq %rsi
movl $0x0, %esi
sbbl %esi, %esi
subq 0x8(%rdi), %r13
jle 0x68a3c
orl %eax, %esi
movq 0x10(%rsp), %rax
addq %rbp, %rax
addq $0x8, %rax
movl $0x1, %edi
xorl %r15d, %r15d
xorl %ecx, %ecx
xorl %r8d, %r8d
testq %r8, %r8
je 0x689c1
cmpq $0x1, %rbx
ja 0x689c1
movl (%rax), %r9d
cmpq %r14, %r9
jne 0x689c1
movl %edx, -0x4(%rax)
testl %edx, %edx
jne 0x68a24
leaq 0x1(%r8), %r9
cmpq %r13, %r9
jge 0x689e2
testq $-0x3, %rbx
jne 0x689e2
movl (%rax), %r9d
cmpq %r11, %r9
jne 0x689e2
movl %esi, -0x4(%rax)
testl %esi, %esi
jne 0x68a24
testq %r15, %r15
jle 0x68a09
movl (%rax), %r10d
movq %r15, %r9
shlq $0x4, %r9
cmpl -0x8(%r12,%r9), %r10d
jbe 0x68a0e
addq %r12, %r9
movl -0xc(%r9), %r9d
cmpl -0x4(%rax), %r9d
adcq $0x0, %rcx
jmp 0x68a10
incq %rcx
jmp 0x68a10
xorl %edi, %edi
leaq 0x1(%r15), %r9
shlq $0x4, %r15
movups -0x8(%rax), %xmm0
movups %xmm0, (%r12,%r15)
movq %r9, %r15
incq %r8
addq $0x10, %rax
cmpq %r13, %r8
jl 0x689a7
testq %rdi, %rdi
sete %al
jmp 0x68a41
xorl %r15d, %r15d
xorl %eax, %eax
cmpq %r15, %rcx
jne 0x68a4e
movq %r15, %rax
jmp 0x68b37
testb %al, %al
je 0x68add
movq %r15, %rsi
shlq $0x4, %rsi
addq %r12, %rsi
movq %r12, %rdi
callq 0x47027
testq %r15, %r15
jle 0x68add
movq %r15, %r14
negq %r14
movq 0x10(%rsp), %rax
addq %rax, %rbp
addq $0x10, %rbp
movl $0x1, %r13d
xorl %edi, %edi
movq %r14, %rax
addq %r13, %rax
je 0x68aa5
movl 0x8(%rbp), %eax
movq %rdi, %rcx
shlq $0x4, %rcx
cmpl 0x8(%r12,%rcx), %eax
jne 0x68aa5
movq %rdi, %rax
jmp 0x68ac6
movq %r13, %rcx
subq %rdi, %rcx
movq %r13, %rax
cmpq $0x2, %rcx
jl 0x68ac6
shlq $0x4, %rdi
addq %r12, %rdi
movq %rbp, %rsi
callq 0x4726f
movq %r13, %rax
leaq (%r14,%r13), %rcx
incq %rcx
incq %r13
addq $0x10, %rbp
movq %rax, %rdi
cmpq $0x1, %rcx
jne 0x68a87
movq 0x28(%rsp), %rdi
shll $0x4, %edi
addq %r12, %rdi
movq %r15, %rsi
movq 0x30(%rsp), %r14
subq %r14, %rsi
movq 0x8(%rsp), %rcx
addq $0x18, %rcx
movq %rdi, %rdx
movq 0x80(%rsp), %r8
movq 0x88(%rsp), %r9
callq 0x4455e
addq %r14, %rax
testq $-0x3, %rbx
jne 0x68b37
shlq $0x4, %r15
movq %rax, %rcx
shlq $0x4, %rcx
movups -0x10(%r12,%r15), %xmm0
movups %xmm0, -0x10(%r12,%rcx)
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x1be56d(%rip), %rdi    # 0x2270ba
leaq 0x1bcaef(%rip), %rsi    # 0x225643
leaq 0x1be57b(%rip), %rcx    # 0x2270d6
movl $0x4204, %edx           # imm = 0x4204
callq 0x2110
leaq 0x1be5ef(%rip), %rdi    # 0x22715b
leaq 0x1bcad0(%rip), %rsi    # 0x225643
leaq 0x1be55c(%rip), %rcx    # 0x2270d6
movl $0x423c, %edx           # imm = 0x423C
callq 0x2110