// File: /workspace/github_c_makefile_star2_O3/c-zhou[P]oatk/run_hmmannot.c
// Function: annot_worker_pipeline
static void *annot_worker_pipeline(void *shared, int step, void *in)
{
    annot_pipeline_t *p = (annot_pipeline_t *) shared;
    if (step == 0) { // read sequence data into bacthes        
        annot_step_t *annot_s;
        MYCALLOC(annot_s, 1);
        MYMALLOC(annot_s->temp_in, p->max_batch_num);
        MYMALLOC(annot_s->temp_out, p->max_batch_num);

        kstream_t *ks = p->ks;
        kstring_t *s = p->s;
        int dret, ret, is_fa, is_fq, is_gfa;
        uint32_t batch_size, batch_num, n_seq, l_seq;
        FILE *fo;
        char file_template[strlen(p->tmpdir) + 16];

        is_fa = is_fq = is_gfa = 0;
        batch_size = batch_num = 0;
        fo = 0;
        n_seq = l_seq = 0;

        // need the file names only and the file descriptors have already been closed
        annot_s->temp_in[batch_num]  = make_tempfile(p->tmpdir, file_template, ".fa");
        annot_s->temp_out[batch_num] = make_tempfile(p->tmpdir, file_template, ".out");
        
        fo = fopen(annot_s->temp_in[batch_num], "w");
        ++batch_num;

        while (s->l || ks_getuntil(ks, KS_SEP_LINE, s, &dret) >= 0) {
            if (s->l == 0) // empty line
                continue;
            
            if (batch_size >= p->max_batch_size && (is_gfa || (is_fa && s->s[0] == '>') || (is_fq && s->s[0] == '@'))) {
                fclose(fo);
                fo = 0;
                l_seq += batch_size;

                if (batch_num >= p->max_batch_num) {
                    break;
                } else {
                    // make a new batch
                    // need the file names only and the file descriptors have already been closed
                    annot_s->temp_in[batch_num]  = make_tempfile(p->tmpdir, file_template, ".fa");
                    annot_s->temp_out[batch_num] = make_tempfile(p->tmpdir, file_template, ".out");
                    fo = fopen(annot_s->temp_in[batch_num], "w");
                    ++batch_num;
                    batch_size = 0;
                }
            }

            ret = 0; 
            if (!is_gfa && s->s[0] == '>') { // FASTA header
                is_fa = 1;
                // parse header
                ret = parse_fheader(s->s);
                if (!ret)
                    fprintf(fo, "%s\n", s->s);
                ++n_seq;
            } else if (!is_gfa && s->s[0] == '@') { // FASTQ header
                is_fq = 1;
                // parse and write header
                ret = parse_fheader(s->s);
                if (!ret)
                    fprintf(fo, ">%s\n", s->s + 1);
                // parse sequence
                if(ks_getuntil(ks, KS_SEP_LINE, s, &dret) < 0)
                    ret = 2;
                if (!ret) {
                    fprintf(fo, "%s\n", s->s);
                    batch_size += s->l;
                }

                // skip quality score lines
                if (ks_getuntil(ks, KS_SEP_LINE, s, &dret) < 0 ||
                        ks_getuntil(ks, KS_SEP_LINE, s, &dret) < 0)
                    ret = 3;
                ++n_seq;
            } else if (is_fa) { // FASTA sequence line
                fprintf(fo, "%s\n", s->s);
                batch_size += s->l;
            } else {
                is_gfa = 1;
                if (s->s[0] == 'S') {
                    char *seg, *seq;
                    seg = seq = NULL;
                    ret = parse_gseq(s->s, &seg, &seq);
                    if (!ret) {
                        fprintf(fo, ">%s\n", seg);
                        fprintf(fo, "%s\n", seq);
                        batch_size += strlen(seq);
                    }
                    ++n_seq;
                }
            }

            if (ret) {
                fprintf(stderr, "[E::%s] failed to parse %s file (error code: %d)\n", __func__, is_fa? "FASTA" : (is_fq? "FASTQ" : "GFA"), ret);
                exit(EXIT_FAILURE);
            }

            s->l = 0;
        }

        if (fo) {
            fclose(fo);
            l_seq += batch_size;
            if (batch_size == 0) {
                --batch_num;
                remove(annot_s->temp_in[batch_num]);
                remove(annot_s->temp_out[batch_num]);
                free(annot_s->temp_in[batch_num]);
                free(annot_s->temp_out[batch_num]);
            }
        }

        assert(is_fa + is_fq + is_gfa <= 1);

        if (batch_num == 0) {
            free(annot_s->temp_in);
            free(annot_s->temp_out);
            free(annot_s);
        } else {
            annot_s->batch_num = batch_num;
            annot_s->shared = p;
            fprintf(stderr, "[M::%s] %u sequences (%u bp) loaded in %u batc%s\n", __func__, n_seq, l_seq, batch_num, batch_num > 1? "hes" : "h");
            return annot_s;
        }
    } else if (step == 1) { // do nhmmscan annotation
        kt_for(p->n_threads, annot_worker_for, in, ((annot_step_t*)in)->batch_num);
        return in;
    } else if (step == 2) { // parse nhmmscan output
        annot_step_t *annot_s = (annot_step_t *) in;
        int i;
        FILE *fp;
        char c;

        for (i = 0; i < annot_s->batch_num; ++i) {
            fp = fopen(annot_s->temp_out[i], "r");
            while ((c = fgetc(fp)) != EOF)
                fputc(c, p->fo);
            fclose(fp);

            remove(annot_s->temp_in[i]);
            remove(annot_s->temp_out[i]);
            free(annot_s->temp_in[i]);
            free(annot_s->temp_out[i]);
        }
        free(annot_s->temp_in);
        free(annot_s->temp_out);
        free(annot_s);
    }

    return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x58, %rsp
movq %rdi, %r14
testl %esi, %esi
je 0x2bd3
movq %rdx, %rbx
cmpl $0x1, %esi
je 0x2bb7
cmpl $0x2, %esi
jne 0x30c4
cmpl $0x0, 0x8(%rbx)
jle 0x2b98
xorl %r13d, %r13d
leaq 0x4a1a(%rip), %r15      # 0x7532
movq 0x18(%rbx), %rax
movq (%rax,%r13,8), %rdi
movq %r15, %rsi
callq 0x2310
movq %rax, %r12
movq %rax, %rdi
callq 0x21a0
shll $0x18, %eax
cmpl $0xff000000, %eax       # imm = 0xFF000000
je 0x2b50
sarl $0x18, %eax
movq 0x28(%r14), %rsi
movl %eax, %edi
callq 0x21c0
movq %r12, %rdi
jmp 0x2b2e
movq %r12, %rdi
callq 0x2110
movq 0x10(%rbx), %rax
movq (%rax,%r13,8), %rdi
callq 0x2080
movq 0x18(%rbx), %rax
movq (%rax,%r13,8), %rdi
callq 0x2080
movq 0x10(%rbx), %rax
movq (%rax,%r13,8), %rdi
callq 0x2050
movq 0x18(%rbx), %rax
movq (%rax,%r13,8), %rdi
callq 0x2050
incq %r13
movslq 0x8(%rbx), %rax
cmpq %rax, %r13
jl 0x2b18
movq 0x10(%rbx), %rdi
callq 0x2050
movq 0x18(%rbx), %rdi
callq 0x2050
movq %rbx, %rdi
callq 0x2050
jmp 0x30c4
movl 0x38(%r14), %edi
movslq 0x8(%rbx), %rcx
leaq 0x115b(%rip), %rsi      # 0x3d21
movq %rbx, %rdx
callq 0x5d20
jmp 0x30c6
movl $0x1, %edi
movl $0x20, %esi
callq 0x21f0
movq %rax, %rbx
movl 0x4(%r14), %r15d
shlq $0x3, %r15
movq %r15, %rdi
callq 0x2280
movq %rax, %r13
movq %rax, 0x10(%rbx)
movq %r15, %rdi
callq 0x2280
movq %rax, -0x38(%rbp)
movq %rax, 0x18(%rbx)
movq 0x18(%r14), %rax
movq %rax, -0x58(%rbp)
movq 0x20(%r14), %r15
movq 0x30(%r14), %rdi
callq 0x2130
movq %rsp, -0x78(%rbp)
movq %rsp, %r12
addq $0x1f, %rax
andq $-0x10, %rax
subq %rax, %r12
movq %r12, %rsp
movq 0x30(%r14), %rdi
leaq 0x4791(%rip), %rdx      # 0x73d2
movq %r12, %rsi
callq 0x555c
movq %rax, (%r13)
movq 0x30(%r14), %rdi
leaq 0x477e(%rip), %rdx      # 0x73d6
movq %r12, -0x80(%rbp)
movq %r12, %rsi
callq 0x555c
movq -0x38(%rbp), %rcx
movq %rax, (%rcx)
movq (%r13), %rdi
movq -0x58(%rbp), %r13
leaq 0x46cf(%rip), %rsi      # 0x7349
callq 0x2310
movq %rax, -0x48(%rbp)
cmpq $0x0, (%r15)
sete %al
movl $0x1, %ecx
movq %rcx, -0x60(%rbp)
leaq -0x6c(%rbp), %r12
movl $0x0, -0x38(%rbp)
movl $0x0, -0x64(%rbp)
movl $0x0, -0x68(%rbp)
movl $0x0, -0x2c(%rbp)
movl $0x0, -0x4c(%rbp)
movl $0x0, -0x30(%rbp)
testb $0x1, %al
je 0x2ce1
movq %r13, %rdi
movq %r15, %rsi
movq %r12, %rdx
callq 0x3b5e
testl %eax, %eax
js 0x303c
cmpq $0x0, (%r15)
je 0x2cc5
movl -0x38(%rbp), %eax
cmpl (%r14), %eax
jb 0x2d87
cmpl $0x0, -0x2c(%rbp)
je 0x2e08
movq -0x48(%rbp), %rdi
callq 0x2110
movl -0x38(%rbp), %eax
addl %eax, -0x68(%rbp)
movq -0x60(%rbp), %rax
cmpl 0x4(%r14), %eax
jae 0x308e
movq 0x30(%r14), %rdi
movq -0x80(%rbp), %r13
movq %r13, %rsi
leaq 0x46ac(%rip), %rdx      # 0x73d2
callq 0x555c
movq 0x10(%rbx), %rcx
movq %rcx, -0x38(%rbp)
movl -0x60(%rbp), %r12d
movq %rax, (%rcx,%r12,8)
movq 0x30(%r14), %rdi
movq %r13, %rsi
leaq 0x468d(%rip), %rdx      # 0x73d6
callq 0x555c
movq 0x18(%rbx), %rcx
movq %rax, (%rcx,%r12,8)
movq -0x38(%rbp), %rax
movq (%rax,%r12,8), %rdi
leaq -0x6c(%rbp), %r12
leaq 0x45e0(%rip), %rsi      # 0x7349
callq 0x2310
movq %rax, -0x48(%rbp)
movq -0x60(%rbp), %rax
incl %eax
movq %rax, -0x60(%rbp)
movl $0x0, -0x38(%rbp)
movq -0x58(%rbp), %r13
cmpl $0x0, -0x2c(%rbp)
jne 0x2f33
movq 0x10(%r15), %r13
movb (%r13), %al
cmpb $0x40, %al
je 0x2e38
movzbl %al, %eax
cmpl $0x3e, %eax
jne 0x2f2f
callq 0x23f0
movq (%rax), %rcx
movb $0x3e, %dl
movq %r13, %rax
movsbq %dl, %rdx
testb $0x20, 0x1(%rcx,%rdx,2)
jne 0x2dcf
movb 0x1(%rax), %dl
incq %rax
testb %dl, %dl
jne 0x2dba
movb $0x0, (%rax)
subq %r13, %rax
movl $0x0, -0x2c(%rbp)
cmpq $0x1, %rax
je 0x3167
movq 0x10(%r15), %rdx
movq -0x48(%rbp), %rdi
leaq 0x472a(%rip), %rsi      # 0x751f
xorl %eax, %eax
callq 0x2220
movl $0x1, -0x30(%rbp)
jmp 0x3027
movq 0x10(%r15), %r13
cmpl $0x0, -0x30(%rbp)
je 0x2e1d
cmpb $0x3e, (%r13)
je 0x2cf7
cmpl $0x0, -0x4c(%rbp)
je 0x2d95
movb (%r13), %al
cmpb $0x40, %al
je 0x2cf7
jmp 0x2d99
callq 0x23f0
movq (%rax), %rcx
movb $0x40, %dl
movq %r13, %rax
movsbq %dl, %rdx
testb $0x20, 0x1(%rcx,%rdx,2)
jne 0x2e5a
movb 0x1(%rax), %dl
incq %rax
testb %dl, %dl
jne 0x2e45
movb $0x0, (%rax)
subq %r13, %rax
xorl %r13d, %r13d
cmpq $0x1, %rax
sete %al
je 0x2e8b
movq 0x10(%r15), %rdx
incq %rdx
movq -0x48(%rbp), %rdi
leaq 0x455d(%rip), %rsi      # 0x73db
movb %al, -0x2c(%rbp)
xorl %eax, %eax
callq 0x2220
movb -0x2c(%rbp), %al
movb %al, %r13b
movq -0x58(%rbp), %rdi
movq %r15, %rsi
movq %r12, %rdx
callq 0x3b5e
testl %eax, %eax
movl $0x2, %eax
cmovsl %eax, %r13d
testl %r13d, %r13d
jne 0x2ecc
movq 0x10(%r15), %rdx
movq -0x48(%rbp), %rdi
leaq 0x4663(%rip), %rsi      # 0x751f
xorl %eax, %eax
callq 0x2220
movl -0x38(%rbp), %eax
addl (%r15), %eax
movl %eax, -0x38(%rbp)
movq -0x58(%rbp), %r12
movq %r12, %rdi
movq %r15, %rsi
leaq -0x6c(%rbp), %rdx
callq 0x3b5e
movl $0x3, -0x3c(%rbp)
testl %eax, %eax
js 0x312f
movq %r12, %rdi
movq %r15, %rsi
leaq -0x6c(%rbp), %r12
movq %r12, %rdx
callq 0x3b5e
testl %eax, %eax
js 0x312f
movl %r13d, -0x3c(%rbp)
testl %r13d, %r13d
jne 0x312f
incl -0x64(%rbp)
movl $0x0, -0x2c(%rbp)
movl $0x1, -0x4c(%rbp)
movq -0x58(%rbp), %r13
jmp 0x302e
movq -0x58(%rbp), %r13
movq 0x10(%r15), %rdx
cmpl $0x0, -0x30(%rbp)
je 0x2f64
movq -0x48(%rbp), %rdi
leaq 0x45d7(%rip), %rsi      # 0x751f
xorl %eax, %eax
callq 0x2220
movl -0x38(%rbp), %eax
addl (%r15), %eax
movl %eax, -0x38(%rbp)
movl $0x1, -0x30(%rbp)
jmp 0x302e
cmpb $0x53, (%rdx)
jne 0x2fbb
leaq 0x2(%rdx), %r13
addq $0x3, %rdx
xorl %eax, %eax
xorl %ecx, %ecx
movzbl -0x1(%rdx), %edi
cmpl $0x9, %edi
je 0x2f82
testl %edi, %edi
jne 0x2fa4
movb $0x0, -0x1(%rdx)
testl %ecx, %ecx
movq %rax, %rsi
cmoveq %r13, %rsi
cmpl $0x1, %ecx
je 0x2fcb
movl $0x1, %r8d
movq %rdx, %r9
testb %dil, %dil
jne 0x2fad
jmp 0x2fcb
movq %rax, %rsi
movl %ecx, %r8d
movq %r13, %r9
incq %rdx
movq %rsi, %rax
movl %r8d, %ecx
movq %r9, %r13
jmp 0x2f75
movl $0x1, -0x2c(%rbp)
movl $0x0, -0x30(%rbp)
jmp 0x302e
movb $0x1, %dl
movl %edx, -0x2c(%rbp)
cmpl $0x1, %ecx
jne 0x3170
cmpb $0x2a, (%r13)
je 0x3179
movl $0x0, -0x30(%rbp)
movq -0x48(%rbp), %rdi
leaq 0x43e5(%rip), %rsi      # 0x73db
movq %rax, %rdx
xorl %eax, %eax
callq 0x2220
movq -0x48(%rbp), %rdi
leaq 0x4514(%rip), %rsi      # 0x751f
movq %r13, %rdx
xorl %eax, %eax
callq 0x2220
movq %r13, %rdi
callq 0x2130
addl %eax, -0x38(%rbp)
movl $0x1, -0x2c(%rbp)
movq -0x58(%rbp), %r13
incl -0x64(%rbp)
movq $0x0, (%r15)
movb $0x1, %al
jmp 0x2cc1
movq -0x48(%rbp), %rdi
testq %rdi, %rdi
je 0x308e
callq 0x2110
movl -0x38(%rbp), %eax
addl %eax, -0x68(%rbp)
testl %eax, %eax
jne 0x308e
movq -0x60(%rbp), %r12
decl %r12d
movq 0x10(%rbx), %r15
movq (%r15,%r12,8), %rdi
callq 0x2080
movq %r12, %r13
movq %r12, -0x60(%rbp)
movq 0x18(%rbx), %r12
movq (%r12,%r13,8), %rdi
callq 0x2080
movq (%r15,%r13,8), %rdi
callq 0x2050
movq (%r12,%r13,8), %rdi
callq 0x2050
movl -0x4c(%rbp), %eax
addl -0x2c(%rbp), %eax
addl -0x30(%rbp), %eax
cmpl $0x2, %eax
jge 0x3148
cmpl $0x0, -0x60(%rbp)
jne 0x30d8
movq 0x10(%rbx), %rdi
callq 0x2050
movq 0x18(%rbx), %rdi
callq 0x2050
movq %rbx, %rdi
callq 0x2050
movq -0x78(%rbp), %rsp
xorl %ebx, %ebx
movq %rbx, %rax
leaq -0x28(%rbp), %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq -0x60(%rbp), %r9
movl %r9d, 0x8(%rbx)
movq %r14, (%rbx)
movq 0x6f06(%rip), %rax      # 0x9ff0
movq (%rax), %rdi
cmpl $0x1, %r9d
leaq 0x3f70(%rip), %rax      # 0x7068
leaq 0x43c7(%rip), %r10      # 0x74c6
cmoveq %rax, %r10
subq $0x8, %rsp
leaq 0x4386(%rip), %rsi      # 0x7494
leaq 0x42fd(%rip), %rdx      # 0x7412
movl -0x64(%rbp), %ecx
movl -0x68(%rbp), %r8d
xorl %eax, %eax
pushq %r10
callq 0x2220
addq $0x10, %rsp
movq -0x78(%rbp), %rsp
jmp 0x30c6
movq 0x6eba(%rip), %rax      # 0x9ff0
movq (%rax), %rdi
cmpl $0x0, -0x30(%rbp)
jne 0x31a6
leaq 0x42e8(%rip), %rcx      # 0x742e
jmp 0x31ad
leaq 0x42e9(%rip), %rdi      # 0x7438
leaq 0x42fe(%rip), %rsi      # 0x7454
leaq 0x4306(%rip), %rcx      # 0x7463
movl $0xf5, %edx
callq 0x2180
movl $0x1, -0x3c(%rbp)
jmp 0x3180
movl $0x5, -0x3c(%rbp)
jmp 0x3180
movl $0x6, -0x3c(%rbp)
movq 0x6e69(%rip), %rax      # 0x9ff0
movq (%rax), %rdi
cmpl $0x0, -0x4c(%rbp)
leaq 0x429f(%rip), %rax      # 0x7434
leaq 0x4292(%rip), %rcx      # 0x742e
cmoveq %rax, %rcx
cmpb $0x0, -0x2c(%rbp)
jne 0x31ad
leaq 0x427b(%rip), %rcx      # 0x7428
leaq 0x422c(%rip), %rsi      # 0x73e0
leaq 0x4257(%rip), %rdx      # 0x7412
movl -0x3c(%rbp), %r8d
xorl %eax, %eax
callq 0x2220
movl $0x1, %edi
callq 0x2370