// File: /workspace/github_c_makefile_star2_O0/c-zhou[P]oatk/syncerr.c
// Function: read_error_correction
void read_error_correction(sr_db_t *sr_db, scg_t *g, double max_edist, uint32_t err_mer_c, uint32_t max_err_c, 
        uint32_t err_arc_c, double max_arc_f, int n_threads, FILE *fo, int verbose)
{
    if (n_threads <= 0)
        n_threads = 1;

#ifdef DEBUG_SYNCMER_CORRECTION
    if (n_threads > 1) {
        n_threads = 1;
        fprintf(stderr, "[DEBUG_SYNCMER_CORRECTION::%s] set thread number to one for debugging mode\n", __func__);
    }
#endif

    double realtime1 = realtime();
    double cputime1 = cputime();

    // mark errors in syncmer database
    find_error_syncmers(g, err_mer_c, max_err_c, err_arc_c, max_arc_f, 1);
    
    // sort arcs by coverage for each source vertex
    // DFS then will visit the high coverage paths first
    // this will hopefully increase the chance of error correction for complex regions capped by MAX_DFS_PATH
    // TODO does this really help?
    /***
    uint64_t i, n, na;
    asmg_arc_t *a;
    asmg_t *asmg;
    asmg = g->utg_asmg;
    for (i = 0, n = 2 * asmg->n_vtx; i < n; ++i) {
        na = asmg_arc_n(asmg, i);
        if (na) {
            a = asmg_arc_a(asmg, i);
            qsort(a, na, sizeof(asmg_arc_t), arc_cov_cmpfunc);
        }
    }
    **/

    int t;
    // shared data
    ec_shared_t shared;

    ec_cached_t *cached;
    MYCALLOC(cached, n_threads);
    for (t = 0; t < n_threads; ++t) {
        MYCALLOC(cached[t].conf, 1);
        MYCALLOC(cached[t].seq, 1);
        MYCALLOC(cached[t].c_seq, 1);
        MYCALLOC(cached[t].c_kmer, 1);
        MYCALLOC(cached[t].c_mpos, 1);
        MYCALLOC(cached[t].dfs, 1);
        MYBZERO(cached[t].stats, 11);
    }

    shared.sr_db = sr_db;
    shared.g = g;
    shared.max_edist = max_edist;
    shared.cache = cached;
    shared.fo = fo;
    
    if (pthread_mutex_init(&mutex, NULL) != 0) {
        fprintf(stderr, "[E::%s] pthread mutex init failed\n", __func__);
        goto do_clean;
    }
    kt_for(n_threads, read_error_correction_analysis_thread, &shared, sr_db->n);
    pthread_mutex_destroy(&mutex);
    
    /***
    uint64_t rids[] = {0, 9, 15, 21, 31}; //{9007, 58477, 59602, 89548, 129398, 192, 15778, 24013, 25430, 44358, 102676, 103790, 129066, 140012};
    for (int r = 0; r < sizeof(rids) / sizeof(*rids); ++r)
        read_error_correction_analysis_thread(&shared, rids[r], 0);
    **/

    int j;
    long *stats;
    stats = cached[0].stats;
    for (t = 1; t < n_threads; ++t)
        for (j = 0; j < 11; ++j)
            stats[j] += cached[t].stats[j];
    
    // update syncmer database
    update_syncmer_db(sr_db, g->scm_db);

    // print error correction summary results
    fprintf(stderr, "[M::%s] Error Correction Summary Results\n", __func__);
    fprintf(stderr, "[M::%s] total number of error blocks : %ld\n", __func__, stats[0] + stats[5] + stats[10]);
    fprintf(stderr, "[M::%s]                - uncorrected : %ld\n", __func__, stats[1] + stats[6]);
    fprintf(stderr, "[M::%s]                  - corrected : %ld\n", __func__, stats[2] + stats[7]);
    fprintf(stderr, "[M::%s]             - ambiguous seqs : %ld\n", __func__, stats[3] + stats[8]);
    fprintf(stderr, "[M::%s]             - ambiguous path : %ld\n", __func__, stats[4] + stats[9]);
    // more verbose information
    if (verbose) {
        fprintf(stderr, "[M::%s] error blocks in the tail end : %ld\n", __func__, stats[0]);
        fprintf(stderr, "[M::%s]                - uncorrected : %ld\n", __func__, stats[1]);
        fprintf(stderr, "[M::%s]                  - corrected : %ld\n", __func__, stats[2]);
        fprintf(stderr, "[M::%s]             - ambiguous seqs : %ld\n", __func__, stats[3]);
        fprintf(stderr, "[M::%s]             - ambiguous path : %ld\n", __func__, stats[4]);
        fprintf(stderr, "[M::%s]   error blocks in the middle : %ld\n", __func__, stats[5]);
        fprintf(stderr, "[M::%s]                - uncorrected : %ld\n", __func__, stats[6]);
        fprintf(stderr, "[M::%s]                  - corrected : %ld\n", __func__, stats[7]);
        fprintf(stderr, "[M::%s]             - ambiguous seqs : %ld\n", __func__, stats[8]);
        fprintf(stderr, "[M::%s]             - ambiguous path : %ld\n", __func__, stats[9]);
        fprintf(stderr, "[M::%s]      error blocks overlapped : %ld\n", __func__, stats[10]);
        fprintf(stderr, "[M::%s]   error correction  CPU time : %.3f sec\n", __func__, cputime() - cputime1);
        fprintf(stderr, "[M::%s]   error correction real time : %.3f sec\n", __func__, realtime() - realtime1);
    }

do_clean:
    for (t = 0; t < n_threads; ++t) {
        // do free
        wf_config_destroy(cached[t].conf, 0);
        dfs_info_destroy(cached[t].dfs);
        free(cached[t].seq->s);
        free(cached[t].seq);
        free(cached[t].c_seq->s);
        free(cached[t].c_seq);
        free(cached[t].c_kmer->a);
        free(cached[t].c_kmer);
        free(cached[t].c_mpos->a);
        free(cached[t].c_mpos);
    }
    free(cached);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xa0, %rsp
movl 0x18(%rbp), %eax
movq 0x10(%rbp), %rax
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movsd %xmm0, -0x18(%rbp)
movl %edx, -0x1c(%rbp)
movl %ecx, -0x20(%rbp)
movl %r8d, -0x24(%rbp)
movsd %xmm1, -0x30(%rbp)
movl %r9d, -0x34(%rbp)
cmpl $0x0, -0x34(%rbp)
jg 0x1b0bf
movl $0x1, -0x34(%rbp)
callq 0x29140
movsd %xmm0, -0x40(%rbp)
callq 0x290b0
movsd %xmm0, -0x48(%rbp)
movq -0x10(%rbp), %rdi
movl -0x1c(%rbp), %esi
movl -0x20(%rbp), %edx
movl -0x24(%rbp), %ecx
movsd -0x30(%rbp), %xmm0
movl $0x1, %r8d
callq 0x1ab70
movslq -0x34(%rbp), %rdi
movl $0x88, %esi
callq 0x2250
movq %rax, -0x80(%rbp)
movl $0x0, -0x4c(%rbp)
movl -0x4c(%rbp), %eax
cmpl -0x34(%rbp), %eax
jge 0x1b234
movl $0x1, %edi
movl $0x48, %esi
callq 0x2250
movq %rax, %rcx
movq -0x80(%rbp), %rax
movslq -0x4c(%rbp), %rdx
imulq $0x88, %rdx, %rdx
addq %rdx, %rax
movq %rcx, (%rax)
movl $0x1, %edi
movl $0x18, %esi
callq 0x2250
movq %rax, %rcx
movq -0x80(%rbp), %rax
movslq -0x4c(%rbp), %rdx
imulq $0x88, %rdx, %rdx
addq %rdx, %rax
movq %rcx, 0x8(%rax)
movl $0x1, %edi
movl $0x18, %esi
callq 0x2250
movq %rax, %rcx
movq -0x80(%rbp), %rax
movslq -0x4c(%rbp), %rdx
imulq $0x88, %rdx, %rdx
addq %rdx, %rax
movq %rcx, 0x10(%rax)
movl $0x1, %edi
movl $0x18, %esi
callq 0x2250
movq %rax, %rcx
movq -0x80(%rbp), %rax
movslq -0x4c(%rbp), %rdx
imulq $0x88, %rdx, %rdx
addq %rdx, %rax
movq %rcx, 0x18(%rax)
movl $0x1, %edi
movl $0x18, %esi
callq 0x2250
movq %rax, %rcx
movq -0x80(%rbp), %rax
movslq -0x4c(%rbp), %rdx
imulq $0x88, %rdx, %rdx
addq %rdx, %rax
movq %rcx, 0x20(%rax)
movl $0x1, %edi
movl $0x70, %esi
callq 0x2250
movq %rax, %rcx
movq -0x80(%rbp), %rax
movslq -0x4c(%rbp), %rdx
imulq $0x88, %rdx, %rdx
addq %rdx, %rax
movq %rcx, 0x28(%rax)
movq -0x80(%rbp), %rdi
movslq -0x4c(%rbp), %rax
imulq $0x88, %rax, %rax
addq %rax, %rdi
addq $0x30, %rdi
xorl %esi, %esi
movl $0x58, %edx
callq 0x21f0
movl -0x4c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x4c(%rbp)
jmp 0x1b109
movq -0x8(%rbp), %rax
movq %rax, -0x78(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0x70(%rbp)
movsd -0x18(%rbp), %xmm0
movsd %xmm0, -0x68(%rbp)
movq -0x80(%rbp), %rax
movq %rax, -0x60(%rbp)
movq 0x10(%rbp), %rax
movq %rax, -0x58(%rbp)
leaq 0x19243(%rip), %rdi     # 0x344a8
xorl %eax, %eax
movl %eax, %esi
callq 0x24f0
cmpl $0x0, %eax
je 0x1b297
movq 0x18d7e(%rip), %rax     # 0x33ff8
movq (%rax), %rdi
leaq 0x13371(%rip), %rsi     # 0x2e5f5
leaq 0x1338d(%rip), %rdx     # 0x2e618
movb $0x0, %al
callq 0x2290
jmp 0x1b6c9
movl -0x34(%rbp), %edi
movq -0x8(%rbp), %rax
movq (%rax), %rcx
leaq 0x578(%rip), %rsi       # 0x1b820
leaq -0x78(%rbp), %rdx
callq 0x29830
leaq 0x191f0(%rip), %rdi     # 0x344a8
callq 0x2190
movq -0x80(%rbp), %rax
addq $0x30, %rax
movq %rax, -0x90(%rbp)
movl $0x1, -0x4c(%rbp)
movl -0x4c(%rbp), %eax
cmpl -0x34(%rbp), %eax
jge 0x1b340
movl $0x0, -0x84(%rbp)
cmpl $0xb, -0x84(%rbp)
jge 0x1b333
movq -0x80(%rbp), %rax
movslq -0x4c(%rbp), %rcx
imulq $0x88, %rcx, %rcx
addq %rcx, %rax
movslq -0x84(%rbp), %rcx
movq 0x30(%rax,%rcx,8), %rdx
movq -0x90(%rbp), %rax
movslq -0x84(%rbp), %rcx
addq (%rax,%rcx,8), %rdx
movq %rdx, (%rax,%rcx,8)
movl -0x84(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x84(%rbp)
jmp 0x1b2e5
jmp 0x1b335
movl -0x4c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x4c(%rbp)
jmp 0x1b2d3
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rax
movq (%rax), %rsi
callq 0x1d280
movq 0x18ca1(%rip), %rax     # 0x33ff8
movq (%rax), %rdi
leaq 0x132cd(%rip), %rsi     # 0x2e62e
leaq 0x132b0(%rip), %rdx     # 0x2e618
movb $0x0, %al
callq 0x2290
movq 0x18c82(%rip), %rax     # 0x33ff8
movq (%rax), %rdi
movq -0x90(%rbp), %rax
movq (%rax), %rcx
movq -0x90(%rbp), %rax
addq 0x28(%rax), %rcx
movq -0x90(%rbp), %rax
addq 0x50(%rax), %rcx
leaq 0x132b8(%rip), %rsi     # 0x2e658
leaq 0x13271(%rip), %rdx     # 0x2e618
movb $0x0, %al
callq 0x2290
movq 0x18c43(%rip), %rax     # 0x33ff8
movq (%rax), %rdi
movq -0x90(%rbp), %rax
movq 0x8(%rax), %rcx
movq -0x90(%rbp), %rax
addq 0x30(%rax), %rcx
leaq 0x132af(%rip), %rsi     # 0x2e684
leaq 0x1323c(%rip), %rdx     # 0x2e618
movb $0x0, %al
callq 0x2290
movq 0x18c0e(%rip), %rax     # 0x33ff8
movq (%rax), %rdi
movq -0x90(%rbp), %rax
movq 0x10(%rax), %rcx
movq -0x90(%rbp), %rax
addq 0x38(%rax), %rcx
leaq 0x132a6(%rip), %rsi     # 0x2e6b0
leaq 0x13207(%rip), %rdx     # 0x2e618
movb $0x0, %al
callq 0x2290
movq 0x18bd9(%rip), %rax     # 0x33ff8
movq (%rax), %rdi
movq -0x90(%rbp), %rax
movq 0x18(%rax), %rcx
movq -0x90(%rbp), %rax
addq 0x40(%rax), %rcx
leaq 0x1329d(%rip), %rsi     # 0x2e6dc
leaq 0x131d2(%rip), %rdx     # 0x2e618
movb $0x0, %al
callq 0x2290
movq 0x18ba4(%rip), %rax     # 0x33ff8
movq (%rax), %rdi
movq -0x90(%rbp), %rax
movq 0x20(%rax), %rcx
movq -0x90(%rbp), %rax
addq 0x48(%rax), %rcx
leaq 0x13294(%rip), %rsi     # 0x2e708
leaq 0x1319d(%rip), %rdx     # 0x2e618
movb $0x0, %al
callq 0x2290
cmpl $0x0, 0x18(%rbp)
je 0x1b6c7
movq 0x18b65(%rip), %rax     # 0x33ff8
movq (%rax), %rdi
movq -0x90(%rbp), %rax
movq (%rax), %rcx
leaq 0x1328d(%rip), %rsi     # 0x2e734
leaq 0x1316a(%rip), %rdx     # 0x2e618
movb $0x0, %al
callq 0x2290
movq 0x18b3c(%rip), %rax     # 0x33ff8
movq (%rax), %rdi
movq -0x90(%rbp), %rax
movq 0x8(%rax), %rcx
leaq 0x131b3(%rip), %rsi     # 0x2e684
leaq 0x13140(%rip), %rdx     # 0x2e618
movb $0x0, %al
callq 0x2290
movq 0x18b12(%rip), %rax     # 0x33ff8
movq (%rax), %rdi
movq -0x90(%rbp), %rax
movq 0x10(%rax), %rcx
leaq 0x131b5(%rip), %rsi     # 0x2e6b0
leaq 0x13116(%rip), %rdx     # 0x2e618
movb $0x0, %al
callq 0x2290
movq 0x18ae8(%rip), %rax     # 0x33ff8
movq (%rax), %rdi
movq -0x90(%rbp), %rax
movq 0x18(%rax), %rcx
leaq 0x131b7(%rip), %rsi     # 0x2e6dc
leaq 0x130ec(%rip), %rdx     # 0x2e618
movb $0x0, %al
callq 0x2290
movq 0x18abe(%rip), %rax     # 0x33ff8
movq (%rax), %rdi
movq -0x90(%rbp), %rax
movq 0x20(%rax), %rcx
leaq 0x131b9(%rip), %rsi     # 0x2e708
leaq 0x130c2(%rip), %rdx     # 0x2e618
movb $0x0, %al
callq 0x2290
movq 0x18a94(%rip), %rax     # 0x33ff8
movq (%rax), %rdi
movq -0x90(%rbp), %rax
movq 0x28(%rax), %rcx
leaq 0x131e7(%rip), %rsi     # 0x2e760
leaq 0x13098(%rip), %rdx     # 0x2e618
movb $0x0, %al
callq 0x2290
movq 0x18a6a(%rip), %rax     # 0x33ff8
movq (%rax), %rdi
movq -0x90(%rbp), %rax
movq 0x30(%rax), %rcx
leaq 0x130e1(%rip), %rsi     # 0x2e684
leaq 0x1306e(%rip), %rdx     # 0x2e618
movb $0x0, %al
callq 0x2290
movq 0x18a40(%rip), %rax     # 0x33ff8
movq (%rax), %rdi
movq -0x90(%rbp), %rax
movq 0x38(%rax), %rcx
leaq 0x130e3(%rip), %rsi     # 0x2e6b0
leaq 0x13044(%rip), %rdx     # 0x2e618
movb $0x0, %al
callq 0x2290
movq 0x18a16(%rip), %rax     # 0x33ff8
movq (%rax), %rdi
movq -0x90(%rbp), %rax
movq 0x40(%rax), %rcx
leaq 0x130e5(%rip), %rsi     # 0x2e6dc
leaq 0x1301a(%rip), %rdx     # 0x2e618
movb $0x0, %al
callq 0x2290
movq 0x189ec(%rip), %rax     # 0x33ff8
movq (%rax), %rdi
movq -0x90(%rbp), %rax
movq 0x48(%rax), %rcx
leaq 0x130e7(%rip), %rsi     # 0x2e708
leaq 0x12ff0(%rip), %rdx     # 0x2e618
movb $0x0, %al
callq 0x2290
movq 0x189c2(%rip), %rax     # 0x33ff8
movq (%rax), %rdi
movq -0x90(%rbp), %rax
movq 0x50(%rax), %rcx
leaq 0x13141(%rip), %rsi     # 0x2e78c
leaq 0x12fc6(%rip), %rdx     # 0x2e618
movb $0x0, %al
callq 0x2290
movq 0x18998(%rip), %rax     # 0x33ff8
movq (%rax), %rax
movq %rax, -0xa0(%rbp)
callq 0x290b0
movq -0xa0(%rbp), %rdi
subsd -0x48(%rbp), %xmm0
leaq 0x13136(%rip), %rsi     # 0x2e7b8
leaq 0x12f8f(%rip), %rdx     # 0x2e618
movb $0x1, %al
callq 0x2290
movq 0x18961(%rip), %rax     # 0x33ff8
movq (%rax), %rax
movq %rax, -0x98(%rbp)
callq 0x29140
movq -0x98(%rbp), %rdi
subsd -0x40(%rbp), %xmm0
leaq 0x13130(%rip), %rsi     # 0x2e7e9
leaq 0x12f58(%rip), %rdx     # 0x2e618
movb $0x1, %al
callq 0x2290
jmp 0x1b6c9
movl $0x0, -0x4c(%rbp)
movl -0x4c(%rbp), %eax
cmpl -0x34(%rbp), %eax
jge 0x1b809
movq -0x80(%rbp), %rax
movslq -0x4c(%rbp), %rcx
imulq $0x88, %rcx, %rcx
addq %rcx, %rax
movq (%rax), %rdi
xorl %esi, %esi
callq 0x1dd10
movq -0x80(%rbp), %rax
movslq -0x4c(%rbp), %rcx
imulq $0x88, %rcx, %rcx
addq %rcx, %rax
movq 0x28(%rax), %rdi
callq 0x1d670
movq -0x80(%rbp), %rax
movslq -0x4c(%rbp), %rcx
imulq $0x88, %rcx, %rcx
addq %rcx, %rax
movq 0x8(%rax), %rax
movq 0x10(%rax), %rdi
callq 0x2060
movq -0x80(%rbp), %rax
movslq -0x4c(%rbp), %rcx
imulq $0x88, %rcx, %rcx
addq %rcx, %rax
movq 0x8(%rax), %rdi
callq 0x2060
movq -0x80(%rbp), %rax
movslq -0x4c(%rbp), %rcx
imulq $0x88, %rcx, %rcx
addq %rcx, %rax
movq 0x10(%rax), %rax
movq 0x10(%rax), %rdi
callq 0x2060
movq -0x80(%rbp), %rax
movslq -0x4c(%rbp), %rcx
imulq $0x88, %rcx, %rcx
addq %rcx, %rax
movq 0x10(%rax), %rdi
callq 0x2060
movq -0x80(%rbp), %rax
movslq -0x4c(%rbp), %rcx
imulq $0x88, %rcx, %rcx
addq %rcx, %rax
movq 0x18(%rax), %rax
movq 0x10(%rax), %rdi
callq 0x2060
movq -0x80(%rbp), %rax
movslq -0x4c(%rbp), %rcx
imulq $0x88, %rcx, %rcx
addq %rcx, %rax
movq 0x18(%rax), %rdi
callq 0x2060
movq -0x80(%rbp), %rax
movslq -0x4c(%rbp), %rcx
imulq $0x88, %rcx, %rcx
addq %rcx, %rax
movq 0x20(%rax), %rax
movq 0x10(%rax), %rdi
callq 0x2060
movq -0x80(%rbp), %rax
movslq -0x4c(%rbp), %rcx
imulq $0x88, %rcx, %rcx
addq %rcx, %rax
movq 0x20(%rax), %rdi
callq 0x2060
movl -0x4c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x4c(%rbp)
jmp 0x1b6d0
movq -0x80(%rbp), %rdi
callq 0x2060
addq $0xa0, %rsp
popq %rbp
retq
nopl (%rax,%rax)