// File: /workspace/github_c_makefile_star2_O1/lh3[P]fermi2/match.c
// Function: main_match
int main_match(int argc, char *argv[])
{
	int i, c, use_mmap = 0, batch_size = 10000000, l_seqs;
	gzFile fp;
	char *fn_sa = 0;
	kseq_t *ks;
	global_t g;

	memset(&g, 0, sizeof(global_t));
	g.max_sa_occ = 10, g.min_occ = 1, g.n_threads = 1, g.kmer = 61, g.min_len = 0;
	while ((c = getopt(argc, argv, "Mdps:m:n:b:t:k:l:")) >= 0) {
		if (c == 'M') use_mmap = 1;
		else if (c == 's') fn_sa = optarg;
		else if (c == 'l') g.min_len = atoi(optarg);
		else if (c == 'm') g.max_sa_occ = atoi(optarg);
		else if (c == 'p') g.partial = 1;
		else if (c == 'd') g.discovery = g.partial = 1;
		else if (c == 'n') g.min_occ = atoi(optarg);
		else if (c == 't') g.n_threads = atoi(optarg);
		else if (c == 'k') g.kmer = atoi(optarg), g.discovery = g.partial = 1;
		else if (c == 'b') batch_size = atoi(optarg);
	}

	if (optind + 2 > argc) {
		fprintf(stderr, "Usage: fermi2 match [options] <index.fmd> <seq.fa>\n");
		fprintf(stderr, "Options:\n");
		fprintf(stderr, "  -p        find SMEMs (reqiring both strands in one index)\n");
		fprintf(stderr, "  -d        discovery novel alleles (force -p; experimental)\n");
		fprintf(stderr, "  -k INT    k-mer length in the discovery mode (force -d) [%d]\n", g.kmer);
		fprintf(stderr, "  -t INT    number of threads [%d]\n", g.n_threads);
		fprintf(stderr, "  -b INT    batch size [%d]\n", batch_size);
		fprintf(stderr, "  -s FILE   sampled suffix array []\n");
		fprintf(stderr, "  -m INT    show coordinate if the number of hits is no more than INT [%d]\n", g.max_sa_occ);
		fprintf(stderr, "  -n INT    min occurrences [%d]\n", g.min_occ);
		fprintf(stderr, "  -l INT    min length [%d]\n", g.min_len);
		fprintf(stderr, "Output format:\n");
		fprintf(stderr, "    SQ  seqName seqLen\n");
		fprintf(stderr, "    EM  start   end     occurrence [positions]\n");
//		fprintf(stderr, "    NS  start   leftLen  diffLen  rightLen  leftOcc  rightOcc  strand  seq  qual\n");
//		fprintf(stderr, "  At an 'NS' line, the length of 'seq' always equals leftLen+diffLen+rightLen.\n");
		return 1;
	}

	fp = gzopen(argv[optind+1], "r");
	if (fp == 0) {
		fprintf(stderr, "[E::%s] failed to open the sequence file\n", __func__);
		return 1;
	}
	g.e = use_mmap? rld_restore_mmap(argv[optind]) : rld_restore(argv[optind]);
	if (g.e == 0) {
		fprintf(stderr, "[E::%s] failed to open the index file\n", __func__);
		gzclose(fp);
		return 1;
	}
	if (g.partial && (g.e->mcnt[2] != g.e->mcnt[5] || g.e->mcnt[3] != g.e->mcnt[4])) {
		fprintf(stderr, "[E::%s] with '-p', the index must include both strands\n", __func__);
		rld_destroy((rld_t*)g.e);
		gzclose(fp);
		return 1;
	}
	if (fn_sa) g.sa = fm_sa_restore(fn_sa);
	if (fn_sa && g.sa == 0) {
		fprintf(stderr, "[E::%s] failed to open the sampled SA file\n", __func__);
		rld_destroy((rld_t*)g.e);
		gzclose(fp);
		return 1;
	}

	g.mem = calloc(g.n_threads, sizeof(thrmem_t));

	batch_size *= g.n_threads;
	ks = kseq_init(fp);
	l_seqs = 0;
	while (kseq_read(ks) >= 0) {
		if (g.n_seqs == g.m_seqs) {
			g.m_seqs = g.m_seqs? g.m_seqs<<1 : 4;
			g.name = realloc(g.name, g.m_seqs * sizeof(char*));
			g.seq  = realloc(g.seq,  g.m_seqs * sizeof(char*));
			g.qual = realloc(g.qual, g.m_seqs * sizeof(char*));
			g.out  = realloc(g.out,  g.m_seqs * sizeof(char*));
		}
		g.name[g.n_seqs] = strdup(ks->name.s);
		g.seq[g.n_seqs]  = strdup(ks->seq.s);
		g.qual[g.n_seqs] = ks->qual.l? strdup(ks->qual.s) : 0; // these will be free'd in worker
		++g.n_seqs;
		l_seqs += ks->seq.l;
		if (l_seqs >= batch_size) {
			kt_for(g.n_threads, worker, &g, g.n_seqs);
			for (i = 0; i < g.n_seqs; ++i) {
				puts(g.out[i]);
				free(g.out[i]);
			}
			g.n_seqs = l_seqs = 0;
		}
	}
	// the last batch
	kt_for(g.n_threads, worker, &g, g.n_seqs);
	for (i = 0; i < g.n_seqs; ++i) {
		puts(g.out[i]);
		free(g.out[i]);
	}
	kseq_destroy(ks);

	for (i = 0; i < g.n_threads; ++i) {
		free(g.mem[i].curr.a); free(g.mem[i].prev.a); free(g.mem[i].smem.a);
		free(g.mem[i].cmp[0].s); free(g.mem[i].cmp[1].s); free(g.mem[i].str.s);
	}
	free(g.name); free(g.seq); free(g.qual); free(g.out); free(g.mem);
	if (g.sa) fm_sa_destroy((fmsa_t*)g.sa);
	rld_destroy((rld_t*)g.e);
	gzclose(fp);
	return 0;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x78, %rsp
movq %rsi, %r15
movl %edi, %ebx
xorps %xmm0, %xmm0
movaps %xmm0, 0x10(%rsp)
movaps %xmm0, 0x20(%rsp)
movaps %xmm0, 0x50(%rsp)
movaps %xmm0, 0x40(%rsp)
movaps %xmm0, 0x30(%rsp)
movaps %xmm0, (%rsp)
movabsq $0x10000000a, %rax      # imm = 0x10000000A
movq %rax, 0x10(%rsp)
movabsq $0x10000003d, %rax      # imm = 0x10000003D
movq %rax, 0x24(%rsp)
movl $0x0, 0x18(%rsp)
leaq 0x4cdf(%rip), %rdx      # 0x1dcc8
callq 0x22f0
testl %eax, %eax
js 0x190de
movq $0x0, 0x70(%rsp)
movl $0x989680, 0x68(%rsp)   # imm = 0x989680
leaq 0x4cba(%rip), %r12      # 0x1dcc8
leaq 0x4c67(%rip), %rbp      # 0x1dc7c
movq 0xafbc(%rip), %r13      # 0x23fd8
xorl %r14d, %r14d
leal -0x62(%rax), %ecx
cmpl $0x12, %ecx
ja 0x19040
movslq (%rbp,%rcx,4), %rax
addq %rbp, %rax
jmpq *%rax
movq (%r13), %rdi
callq 0x2300
movl %eax, 0x68(%rsp)
jmp 0x190b9
cmpl $0x4d, %eax
jne 0x190b9
movl $0x1, %eax
movq %rax, 0x70(%rsp)
jmp 0x190b9
movq (%r13), %rdi
callq 0x2300
movl %eax, 0x28(%rsp)
jmp 0x190b9
movq (%r13), %rdi
callq 0x2300
movl %eax, 0x10(%rsp)
jmp 0x190b9
movl $0x1, 0x1c(%rsp)
jmp 0x190b9
movq (%r13), %rdi
callq 0x2300
movl %eax, 0x24(%rsp)
movabsq $0x100000001, %rax      # imm = 0x100000001
movq %rax, 0x1c(%rsp)
jmp 0x190b9
movq (%r13), %rdi
callq 0x2300
movl %eax, 0x18(%rsp)
jmp 0x190b9
movq (%r13), %rdi
callq 0x2300
movl %eax, 0x14(%rsp)
jmp 0x190b9
movq (%r13), %r14
movl %ebx, %edi
movq %r15, %rsi
movq %r12, %rdx
callq 0x22f0
testl %eax, %eax
jns 0x1901f
cmpl $0x0, 0x70(%rsp)
sete %bpl
movl 0x68(%rsp), %r13d
jmp 0x190ea
movl $0x989680, %r13d        # imm = 0x989680
movb $0x1, %bpl
xorl %r14d, %r14d
movq 0xaedf(%rip), %r12      # 0x23fd0
movslq (%r12), %rax
leal 0x2(%rax), %ecx
cmpl %ebx, %ecx
jg 0x19437
movq 0x8(%r15,%rax,8), %rdi
leaq 0x3278(%rip), %rsi      # 0x1c384
callq 0x22b0
testq %rax, %rax
je 0x19585
movq %rax, %rbx
movslq (%r12), %rax
movq (%r15,%rax,8), %rdi
testb %bpl, %bpl
je 0x19131
callq 0x436c
jmp 0x19136
callq 0x47e9
movq %rax, (%rsp)
testq %rax, %rax
je 0x1958c
cmpl $0x0, 0x1c(%rsp)
je 0x1916a
movq 0x28(%rax), %rax
movq 0x10(%rax), %rcx
cmpq 0x28(%rax), %rcx
jne 0x19427
movq 0x18(%rax), %rcx
cmpq 0x20(%rax), %rcx
jne 0x19427
testq %r14, %r14
je 0x1917c
movq %r14, %rdi
callq 0x183ba
movq %rax, 0x8(%rsp)
testq %r14, %r14
je 0x1918d
cmpq $0x0, 0x8(%rsp)
je 0x19596
movslq 0x28(%rsp), %r15
movl $0x78, %esi
movq %r15, %rdi
callq 0x2190
movq %rax, 0x30(%rsp)
movq %rbx, 0x68(%rsp)
movq %rbx, %rdi
callq 0xd8f7
movq %rax, %r14
movq %rax, %rdi
callq 0xd991
testl %eax, %eax
js 0x19301
imull %r13d, %r15d
xorl %ebx, %ebx
leaq 0x3e4(%rip), %r12       # 0x195b5
movq %rsp, %r13
movl 0x3c(%rsp), %eax
cmpl %eax, 0x38(%rsp)
jne 0x1924d
leal (%rax,%rax), %ecx
testl %eax, %eax
movl $0x4, %eax
cmovel %eax, %ecx
movl %ecx, 0x3c(%rsp)
movq 0x40(%rsp), %rdi
movslq %ecx, %rsi
shlq $0x3, %rsi
callq 0x2260
movq %rax, 0x40(%rsp)
movq 0x48(%rsp), %rdi
movslq 0x3c(%rsp), %rsi
shlq $0x3, %rsi
callq 0x2260
movq %rax, 0x48(%rsp)
movq 0x50(%rsp), %rdi
movslq 0x3c(%rsp), %rsi
shlq $0x3, %rsi
callq 0x2260
movq %rax, 0x50(%rsp)
movq 0x58(%rsp), %rdi
movslq 0x3c(%rsp), %rsi
shlq $0x3, %rsi
callq 0x2260
movq %rax, 0x58(%rsp)
movq 0x8(%r14), %rdi
callq 0x2340
movq 0x40(%rsp), %rcx
movslq 0x38(%rsp), %rbp
movq %rax, (%rcx,%rbp,8)
movq 0x28(%r14), %rdi
callq 0x2340
movq 0x48(%rsp), %rcx
movq %rax, (%rcx,%rbp,8)
cmpl $0x0, 0x30(%r14)
je 0x19288
movq 0x38(%r14), %rdi
callq 0x2340
jmp 0x1928a
xorl %eax, %eax
movq 0x50(%rsp), %rcx
movq %rax, (%rcx,%rbp,8)
leal 0x1(%rbp), %eax
movl %eax, 0x38(%rsp)
addl 0x20(%r14), %ebx
cmpl %r15d, %ebx
jl 0x192f1
movl 0x28(%rsp), %edi
movslq %eax, %rcx
movq %r12, %rsi
movq %r13, %rdx
callq 0x360c
cmpl $0x0, 0x38(%rsp)
jle 0x192e7
xorl %ebx, %ebx
movq 0x58(%rsp), %rax
movq (%rax,%rbx,8), %rdi
callq 0x2080
movq 0x58(%rsp), %rax
movq (%rax,%rbx,8), %rdi
callq 0x2040
incq %rbx
movslq 0x38(%rsp), %rax
cmpq %rax, %rbx
jl 0x192be
movl $0x0, 0x38(%rsp)
xorl %ebx, %ebx
movq %r14, %rdi
callq 0xd991
testl %eax, %eax
jns 0x191d4
movq %rsp, %r15
movl 0x28(%r15), %edi
movslq 0x38(%r15), %rcx
leaq 0x2a2(%rip), %rsi       # 0x195b5
movq %r15, %rdx
callq 0x360c
cmpl $0x0, 0x38(%r15)
jle 0x1934d
xorl %ebx, %ebx
movq 0x58(%rsp), %rax
movq (%rax,%rbx,8), %rdi
callq 0x2080
movq 0x58(%rsp), %rax
movq (%rax,%rbx,8), %rdi
callq 0x2040
incq %rbx
movslq 0x38(%rsp), %rax
cmpq %rax, %rbx
jl 0x19324
movq %r14, %rdi
callq 0xd951
cmpl $0x0, 0x28(%rsp)
jle 0x193cc
xorl %ebx, %ebx
xorl %r14d, %r14d
movq 0x30(%rsp), %rax
movq 0x10(%rax,%rbx), %rdi
callq 0x2040
movq 0x30(%rsp), %rax
movq 0x28(%rax,%rbx), %rdi
callq 0x2040
movq 0x30(%rsp), %rax
movq 0x40(%rax,%rbx), %rdi
callq 0x2040
movq 0x30(%rsp), %rax
movq 0x60(%rax,%rbx), %rdi
callq 0x2040
movq 0x30(%rsp), %rax
movq 0x70(%rax,%rbx), %rdi
callq 0x2040
movq 0x30(%rsp), %rax
movq 0x50(%rax,%rbx), %rdi
callq 0x2040
incq %r14
movslq 0x28(%rsp), %rax
addq $0x78, %rbx
cmpq %rax, %r14
jl 0x19361
movq 0x40(%rsp), %rdi
callq 0x2040
movq 0x48(%rsp), %rdi
callq 0x2040
movq 0x50(%rsp), %rdi
callq 0x2040
movq 0x58(%rsp), %rdi
callq 0x2040
movq 0x30(%rsp), %rdi
callq 0x2040
movq 0x8(%rsp), %rdi
testq %rdi, %rdi
je 0x1940d
callq 0x18199
movq (%rsp), %rdi
callq 0x38cc
movq 0x68(%rsp), %rdi
callq 0x2030
xorl %eax, %eax
jmp 0x195a6
movq %rsp, %rdi
movq %rbx, %rsi
callq 0x3175
jmp 0x195a1
movq 0xabba(%rip), %rbx      # 0x23ff8
movq (%rbx), %rcx
leaq 0x4892(%rip), %rdi      # 0x1dcda
movl $0x33, %esi
movl $0x1, %edx
callq 0x2310
movq (%rbx), %rcx
leaq 0x48ad(%rip), %rdi      # 0x1dd0e
movl $0x9, %esi
movl $0x1, %edx
callq 0x2310
movq (%rbx), %rcx
leaq 0x489e(%rip), %rdi      # 0x1dd18
movl $0x3c, %esi
movl $0x1, %edx
callq 0x2310
movq (%rbx), %rcx
leaq 0x48c2(%rip), %rdi      # 0x1dd55
movl $0x3d, %esi
movl $0x1, %edx
callq 0x2310
movq (%rbx), %rdi
movl 0x24(%rsp), %edx
leaq 0x48e3(%rip), %rsi      # 0x1dd93
xorl %eax, %eax
callq 0x21c0
movq (%rbx), %rdi
movl 0x28(%rsp), %edx
leaq 0x490e(%rip), %rsi      # 0x1ddd3
xorl %eax, %eax
callq 0x21c0
movq (%rbx), %rdi
leaq 0x4921(%rip), %rsi      # 0x1ddf7
movl %r13d, %edx
xorl %eax, %eax
callq 0x21c0
movq (%rbx), %rcx
leaq 0x492a(%rip), %rdi      # 0x1de14
movl $0x24, %esi
movl $0x1, %edx
callq 0x2310
movq (%rbx), %rdi
movl 0x10(%rsp), %edx
leaq 0x4932(%rip), %rsi      # 0x1de39
xorl %eax, %eax
callq 0x21c0
movq (%rbx), %rdi
movl 0x14(%rsp), %edx
leaq 0x4969(%rip), %rsi      # 0x1de85
xorl %eax, %eax
callq 0x21c0
movq (%rbx), %rdi
movl 0x18(%rsp), %edx
leaq 0x4976(%rip), %rsi      # 0x1dea7
xorl %eax, %eax
callq 0x21c0
movq (%rbx), %rcx
leaq 0x4982(%rip), %rdi      # 0x1dec4
movl $0xf, %esi
movl $0x1, %edx
callq 0x2310
movq (%rbx), %rcx
leaq 0x4979(%rip), %rdi      # 0x1ded4
movl $0x17, %esi
movl $0x1, %edx
callq 0x2310
movq (%rbx), %rcx
leaq 0x4978(%rip), %rdi      # 0x1deec
movl $0x2f, %esi
movl $0x1, %edx
callq 0x2310
jmp 0x195a1
callq 0x3221
jmp 0x195a1
movq %rbx, %rdi
callq 0x31f5
jmp 0x195a1
movq %rsp, %rdi
movq %rbx, %rsi
callq 0x31b5
movl $0x1, %eax
addq $0x78, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq