// File: chhylp123[P]hifiasm/ecovlp.cpp
// Function: rs_sort_ec16(unsigned short*, unsigned short*, int, int)
KRADIX_SORT_INIT(ec16, uint16_t, generic_key, 2)
KRADIX_SORT_INIT(ec32, uint32_t, generic_key, 4)
KRADIX_SORT_INIT(ec64, uint64_t, generic_key, 8)

#define kdq_clear(q) ((q)->count = (q)->front = 0)

typedef struct {size_t n, m; asg16_v *a; uint8_t *f; } cc_v;
cc_v scc = {0, 0, NULL, NULL};
cc_v scb = {0, 0, NULL, NULL};
cc_v sca = {0, 0, NULL, NULL};

typedef struct {size_t n, m; char *a; UC_Read z; asg8_v q;} sl_v;


void h_ec_lchain(ha_abuf_t *ab, uint32_t rid, char* rs, uint64_t rl, uint64_t mz_w, uint64_t mz_k, All_reads *rref, overlap_region_alloc *overlap_list, Candidates_list *cl, double bw_thres, 
								 int max_n_chain, int apend_be, kvec_t_u8_warp* k_flag, kvec_t_u64_warp* dbg_ct, st_mt_t *sp, uint32_t *high_occ, uint32_t *low_occ, uint32_t is_accurate, uint32_t gen_off, int64_t mcopy_num, double mcopy_rate, uint32_t chain_cutoff, uint32_t mcopy_khit_cut, uint64_t ocv_w);
void h_ec_lchain_amz(ha_abuf_t *ab, uint32_t rid, char* rs, uint64_t rl, uint64_t mz_w, uint64_t mz_k, All_reads *rref, overlap_region_alloc *overlap_list, Candidates_list *cl, double bw_thres, 
								 int max_n_chain, int apend_be, kvec_t_u8_warp* k_flag, kvec_t_u64_warp* dbg_ct, st_mt_t *sp, uint32_t *high_occ, uint32_t *low_occ, uint32_t is_accurate, uint32_t gen_off, int64_t enable_mcopy, double mcopy_rate, uint32_t chain_cutoff, uint32_t mcopy_khit_cut, uint64_t ocv_w);
void h_ec_lchain_re_gen(ha_abuf_t *ab, uint32_t rid, char* rs, uint64_t rl, uint64_t mz_w, uint64_t mz_k, ha_pt_t *ha_idx, All_reads *rref, overlap_region_alloc *overlap_list, Candidates_list *cl, double bw_thres, 
								 int apend_be, kvec_t_u8_warp* k_flag, kvec_t_u64_warp* dbg_ct, st_mt_t *sp, uint32_t *high_occ, uint32_t *low_occ, uint32_t gen_off, int64_t enable_mcopy, double mcopy_rate, uint32_t mcopy_khit_cut, 
								 int64_t max_skip, int64_t max_iter, int64_t max_dis, int64_t quick_check, double chn_pen_gap, double chn_pen_skip, UC_Read *tu, asg64_v *oidx, asg16_v *scc);
void h_ec_lchain_re_gen3(ha_abuf_t *ab, uint32_t rid, char* rs, uint64_t rl, uint64_t mz_w, uint64_t mz_k, ha_pt_t *ha_idx, All_reads *rref, overlap_region_alloc *overlap_list, Candidates_list *cl, double bw_thres, 
								 int apend_be, kvec_t_u8_warp* k_flag, kvec_t_u64_warp* dbg_ct, st_mt_t *sp, uint32_t *high_occ, uint32_t *low_occ, uint32_t gen_off, int64_t enable_mcopy, double mcopy_rate, uint32_t mcopy_khit_cut, 
								 int64_t max_skip, int64_t max_iter, int64_t max_dis, int64_t quick_check, double chn_pen_gap, double chn_pen_skip, UC_Read *tu, asg64_v *oidx, asg16_v *scc);
uint64_t get_mz1(const char *str, int len, int w, int k, uint32_t rid, int is_hpc, ha_abuf_t *ab, const void *hf, ha_pt_t *ha_idx, int sample_dist, kvec_t_u8_warp* k_flag, kvec_t_u64_warp* dbg_ct, ha_pt_t *pt, int min_freq, int32_t dp_min_len, float dp_e, st_mt_t *mt, int32_t ws, int32_t is_unique, void *km, uint64_t beg_i);
void get_pi_ec_chain(ha_abuf_t *ab, uint64_t rid, uint64_t rl, uint32_t tid, char* ts, uint64_t tl, uint64_t mz_w, uint64_t mz_k, overlap_region_alloc *overlap_list, Candidates_list *cl, double bw_thres, 
								int apend_be, kvec_t_u8_warp* k_flag, kvec_t_u64_warp* dbg_ct, st_mt_t *sp, uint32_t *high_occ, uint32_t *low_occ, /**uint32_t is_accurate,**/ uint32_t gen_off, int64_t enable_mcopy, double mcopy_rate, uint32_t mcopy_khit_cut, 
								int64_t max_skip, int64_t max_iter, int64_t max_dis, int64_t quick_check, double chn_pen_gap, double chn_pen_skip);
void set_lchain_dp_op(uint32_t is_accurate, uint32_t mz_k, int64_t *max_skip, int64_t *max_iter, int64_t *max_dis, double *chn_pen_gap, double *chn_pen_skip, int64_t *quick_check);
void h_ec_lchain_re_gen_srt(ha_abuf_t *ab, ha_pt_t *ha_idx, overlap_region_alloc *olst, Candidates_list *cl);
uint64_t h_ec_lchain_re_gen_qry(ha_abuf_t *ab, uint64_t *k, uint64_t *l, uint64_t *i, uint64_t *idx_a, uint64_t idx_n, uint64_t *tid, uint64_t *trev);
uint64_t h_ec_lchain_re_chn(ha_abuf_t *ab, uint64_t si, uint64_t ei, uint32_t rid, char* rs, uint64_t rl, uint64_t tid, char* ts, uint64_t tl, uint64_t trev, uint64_t mz_w, uint64_t mz_k, overlap_region_alloc *olst, Candidates_list *cl, double bw_thres, 
								 int apend_be, uint64_t max_cnt, uint64_t min_cnt, uint32_t gen_off, int64_t enable_mcopy, double mcopy_rate, uint32_t mcopy_khit_cut, int64_t max_skip, int64_t max_iter, int64_t max_dis, int64_t quick_check, double chn_pen_gap, double chn_pen_skip, tiny_queue_t *tq, asg16_v *scc, int64_t *n, int64_t *zn);
overlap_region* h_ec_lchain_fast(ha_abuf_t *ab, uint32_t rid, UC_Read *qu, UC_Read *tu, uint64_t mz_w, uint64_t mz_k, All_reads *rref, overlap_region_alloc *ol, Candidates_list *cl, bit_extz_t *exz, asg16_v *buf, asg64_v *srt_i, double bw_thres, 
								 int apend_be, kvec_t_u8_warp* k_flag, kvec_t_u64_warp* dbg_ct, st_mt_t *sp, uint32_t *high_occ, uint32_t *low_occ, uint32_t is_accurate, uint32_t gen_off, int64_t enable_mcopy, double mcopy_rate, uint32_t mcopy_khit_cut, ma_hit_t_alloc *in0, ma_hit_t_alloc *in1, double sh);
void h_ec_lchain_fast_new(ha_abuf_t *ab, uint32_t rid, UC_Read *qu, UC_Read *tu, All_reads *rref, overlap_region_alloc *ol, Candidates_list *cl, bit_extz_t *exz, asg16_v *buf, asg64_v *srt_i, ma_hit_t_alloc *in0, ma_hit_t_alloc *in1, double sh);

ec_ovec_buf_t* gen_ec_ovec_buf_t(uint32_t n)
{
    uint32_t k; ec_ovec_buf_t0 *z = NULL;
    ec_ovec_buf_t *p = NULL; CALLOC(p, 1);
    p->n = n; CALLOC(p->a, p->n);
    for (k = 0; k < p->n; k++) {
        z = &(p->a[k]);
        init_UC_Read(&z->self_read);
	    init_UC_Read(&z->ovlp_read);
	    init_Candidates_list(&z->clist);
	    init_overlap_region_alloc(&z->olist);

        // init_fake_cigar(&(z->tmp.f_cigar));
        // memset(&(z->tmp.w_list), 0, sizeof(z->tmp.w_list));
        // CALLOC(z->tmp.w_list.a, 1); z->tmp.w_list.n = z->tmp.w_list.m = 1;

        // kv_init(z->b_buf.a);
        // kv_init(z->r_buf.a);
        kv_init(z->k_flag.a);
        kv_init(z->sp);
        kv_init(z->pidx);
	    kv_init(z->v64);
        kv_init(z->v32);
        kv_init(z->v16);
        kv_init(z->v8q);
        kv_init(z->v8t);
        init_bit_extz_t(&(z->exz), 31);

        z->ab = ha_abuf_init();
        
        InitHaplotypeEvdience(&z->hap);
        z->cns.q = kdq_init(uint32_t);
    }
    
    return p;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x70, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movl %edx, -0x14(%rbp)
movl %ecx, -0x18(%rbp)
movb -0x14(%rbp), %cl
movl $0x1, %eax
shll %cl, %eax
movl %eax, -0x24(%rbp)
movl -0x24(%rbp), %eax
decl %eax
movl %eax, -0x28(%rbp)
movl -0x24(%rbp), %eax
movl %eax, %ecx
movq %rsp, %rax
movq %rax, -0x38(%rbp)
movq %rcx, %rdx
shlq $0x4, %rdx
movq %rsp, %rax
subq %rdx, %rax
movq %rax, -0x60(%rbp)
movq %rax, %rsp
movq %rcx, -0x40(%rbp)
movslq -0x24(%rbp), %rdx
shlq $0x4, %rdx
movq %rax, %rcx
addq %rdx, %rcx
movq %rcx, -0x48(%rbp)
movq %rax, -0x30(%rbp)
movq -0x30(%rbp), %rax
cmpq -0x48(%rbp), %rax
je 0x24a080
movq -0x8(%rbp), %rcx
movq -0x30(%rbp), %rax
movq %rcx, 0x8(%rax)
movq -0x30(%rbp), %rax
movq %rcx, (%rax)
movq -0x30(%rbp), %rax
addq $0x10, %rax
movq %rax, -0x30(%rbp)
jmp 0x24a055
movq -0x8(%rbp), %rax
movq %rax, -0x20(%rbp)
movq -0x20(%rbp), %rax
cmpq -0x10(%rbp), %rax
je 0x24a0cb
movq -0x60(%rbp), %rax
movq -0x20(%rbp), %rcx
movzwl (%rcx), %edx
movl -0x18(%rbp), %ecx
sarl %cl, %edx
movl %edx, %ecx
andl -0x28(%rbp), %ecx
movslq %ecx, %rcx
shlq $0x4, %rcx
addq %rcx, %rax
movq 0x8(%rax), %rcx
addq $0x2, %rcx
movq %rcx, 0x8(%rax)
movq -0x20(%rbp), %rax
addq $0x2, %rax
movq %rax, -0x20(%rbp)
jmp 0x24a088
movq -0x60(%rbp), %rax
addq $0x10, %rax
movq %rax, -0x30(%rbp)
movq -0x30(%rbp), %rax
cmpq -0x48(%rbp), %rax
je 0x24a11f
movq -0x30(%rbp), %rax
movq -0x8(%rax), %rcx
movq -0x8(%rbp), %rax
subq %rax, %rcx
sarq %rcx
movq -0x30(%rbp), %rax
shlq %rcx
addq 0x8(%rax), %rcx
movq %rcx, 0x8(%rax)
movq -0x30(%rbp), %rax
movq -0x8(%rax), %rcx
movq -0x30(%rbp), %rax
movq %rcx, (%rax)
movq -0x30(%rbp), %rax
addq $0x10, %rax
movq %rax, -0x30(%rbp)
jmp 0x24a0d7
movq -0x60(%rbp), %rax
movq %rax, -0x30(%rbp)
movq -0x30(%rbp), %rax
cmpq -0x48(%rbp), %rax
je 0x24a21b
movq -0x30(%rbp), %rax
movq (%rax), %rax
movq -0x30(%rbp), %rcx
cmpq 0x8(%rcx), %rax
je 0x24a20a
movq -0x60(%rbp), %rax
movq -0x30(%rbp), %rcx
movq (%rcx), %rcx
movzwl (%rcx), %edx
movl -0x18(%rbp), %ecx
sarl %cl, %edx
movl %edx, %ecx
andl -0x28(%rbp), %ecx
movslq %ecx, %rcx
shlq $0x4, %rcx
addq %rcx, %rax
movq %rax, -0x50(%rbp)
cmpq -0x30(%rbp), %rax
je 0x24a1fa
movq -0x30(%rbp), %rax
movq (%rax), %rax
movw (%rax), %ax
movw %ax, -0x52(%rbp)
movq -0x60(%rbp), %rax
movw -0x52(%rbp), %cx
movw %cx, -0x54(%rbp)
movq -0x50(%rbp), %rcx
movq (%rcx), %rcx
movw (%rcx), %cx
movw %cx, -0x52(%rbp)
movw -0x54(%rbp), %dx
movq -0x50(%rbp), %rsi
movq (%rsi), %rcx
movq %rcx, %rdi
addq $0x2, %rdi
movq %rdi, (%rsi)
movw %dx, (%rcx)
movzwl -0x52(%rbp), %edx
movl -0x18(%rbp), %ecx
sarl %cl, %edx
movl %edx, %ecx
andl -0x28(%rbp), %ecx
movslq %ecx, %rcx
shlq $0x4, %rcx
addq %rcx, %rax
movq %rax, -0x50(%rbp)
movq -0x50(%rbp), %rax
cmpq -0x30(%rbp), %rax
jne 0x24a188
movw -0x52(%rbp), %cx
movq -0x30(%rbp), %rdx
movq (%rdx), %rax
movq %rax, %rsi
addq $0x2, %rsi
movq %rsi, (%rdx)
movw %cx, (%rax)
jmp 0x24a208
movq -0x30(%rbp), %rax
movq (%rax), %rcx
addq $0x2, %rcx
movq %rcx, (%rax)
jmp 0x24a216
movq -0x30(%rbp), %rax
addq $0x10, %rax
movq %rax, -0x30(%rbp)
jmp 0x24a127
movq -0x60(%rbp), %rax
movq -0x8(%rbp), %rcx
movq %rcx, (%rax)
addq $0x10, %rax
movq %rax, -0x30(%rbp)
movq -0x30(%rbp), %rax
cmpq -0x48(%rbp), %rax
je 0x24a255
movq -0x30(%rbp), %rax
movq -0x8(%rax), %rcx
movq -0x30(%rbp), %rax
movq %rcx, (%rax)
movq -0x30(%rbp), %rax
addq $0x10, %rax
movq %rax, -0x30(%rbp)
jmp 0x24a22e
cmpl $0x0, -0x18(%rbp)
je 0x24a30e
movl -0x18(%rbp), %eax
cmpl -0x14(%rbp), %eax
jle 0x24a272
movl -0x18(%rbp), %eax
subl -0x14(%rbp), %eax
movl %eax, -0x64(%rbp)
jmp 0x24a279
xorl %eax, %eax
movl %eax, -0x64(%rbp)
jmp 0x24a279
movq -0x60(%rbp), %rax
movl -0x64(%rbp), %ecx
movl %ecx, -0x18(%rbp)
movq %rax, -0x30(%rbp)
movq -0x30(%rbp), %rax
cmpq -0x48(%rbp), %rax
je 0x24a30c
movq -0x30(%rbp), %rax
movq 0x8(%rax), %rax
movq -0x30(%rbp), %rcx
movq (%rcx), %rcx
subq %rcx, %rax
sarq %rax
cmpq $0x40, %rax
jle 0x24a2c8
movq -0x30(%rbp), %rax
movq (%rax), %rdi
movq -0x30(%rbp), %rax
movq 0x8(%rax), %rsi
movl -0x14(%rbp), %edx
movl -0x18(%rbp), %ecx
callq 0x249ff0
jmp 0x24a2f9
movq -0x30(%rbp), %rax
movq 0x8(%rax), %rax
movq -0x30(%rbp), %rcx
movq (%rcx), %rcx
subq %rcx, %rax
sarq %rax
cmpq $0x1, %rax
jle 0x24a2f7
movq -0x30(%rbp), %rax
movq (%rax), %rdi
movq -0x30(%rbp), %rax
movq 0x8(%rax), %rsi
callq 0x249f30
jmp 0x24a2f9
jmp 0x24a2fb
movq -0x30(%rbp), %rax
addq $0x10, %rax
movq %rax, -0x30(%rbp)
jmp 0x24a287
jmp 0x24a30e
movq -0x38(%rbp), %rax
movq %rax, %rsp
movq %rbp, %rsp
popq %rbp
retq
nopw (%rax,%rax)