// File: /workspace/github_c_makefile_star2_O2/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 $0xa8, %rsp
movq %rsi, %r15
movl %edi, %r12d
xorps %xmm0, %xmm0
movups %xmm0, 0x40(%rsp)
movups %xmm0, 0x60(%rsp)
movups %xmm0, 0x50(%rsp)
movups %xmm0, 0x80(%rsp)
movups %xmm0, 0x70(%rsp)
andq $0x0, 0x90(%rsp)
movabsq $0x10000000a, %rax      # imm = 0x10000000A
movq %rax, 0x48(%rsp)
movl $0x1, 0x60(%rsp)
movl $0x3d, 0x5c(%rsp)
movl 0x50(%rsp), %eax
movl %eax, 0x24(%rsp)
movl 0x54(%rsp), %eax
movl %eax, 0x18(%rsp)
movl 0x58(%rsp), %eax
movl %eax, 0x14(%rsp)
pushq $0x1
popq %rbp
pushq $0xa
popq %rax
movl %eax, 0x30(%rsp)
movl $0x989680, 0xc(%rsp)    # imm = 0x989680
movq $0x0, 0x98(%rsp)
pushq $0x3d
popq %rax
movl %eax, 0x28(%rsp)
leaq 0x433d(%rip), %r14      # 0x1adc0
leaq 0x42ea(%rip), %r13      # 0x1ad74
movl %ebp, 0x2c(%rsp)
movl %ebp, 0x34(%rsp)
movl $0x0, 0x10(%rsp)
xorl %ecx, %ecx
movq $0x0, 0xa0(%rsp)
movl %ecx, %ebx
movl %r12d, %edi
movq %r15, %rsi
movq %r14, %rdx
callq 0x22f0
testl %eax, %eax
js 0x16b8c
leal -0x62(%rax), %ecx
cmpl $0x12, %ecx
ja 0x16aea
movslq (%r13,%rcx,4), %rax
addq %r13, %rax
jmpq *%rax
movq 0xb4ff(%rip), %rax      # 0x21fd8
movq (%rax), %rdi
callq 0x2300
movl %eax, 0xc(%rsp)
jmp 0x16b85
movl %ebp, %ecx
cmpl $0x4d, %eax
je 0x16aa8
jmp 0x16b85
movq 0xb4db(%rip), %rax      # 0x21fd8
movq (%rax), %rdi
callq 0x2300
movl %eax, 0x34(%rsp)
jmp 0x16b85
movq 0xb4c6(%rip), %rax      # 0x21fd8
movq (%rax), %rdi
callq 0x2300
movl %eax, 0x24(%rsp)
movq %rax, 0x98(%rsp)
jmp 0x16b85
movq 0xb4a9(%rip), %rax      # 0x21fd8
movq (%rax), %rdi
callq 0x2300
movl %eax, 0x2c(%rsp)
jmp 0x16b85
movq 0xb494(%rip), %rax      # 0x21fd8
movq (%rax), %rdi
callq 0x2300
movl %eax, 0x28(%rsp)
movl %ebp, 0x14(%rsp)
movl %ebp, 0x18(%rsp)
movl %ebp, 0x10(%rsp)
jmp 0x16b85
movq 0xb473(%rip), %rax      # 0x21fd8
movq (%rax), %rdi
callq 0x2300
movl %eax, 0x30(%rsp)
jmp 0x16b85
movq 0xb45e(%rip), %rax      # 0x21fd8
movq (%rax), %rax
movq %rax, 0xa0(%rsp)
movl %ebx, %ecx
jmp 0x16aa8
movl 0x28(%rsp), %esi
movl %esi, 0x5c(%rsp)
movl 0x18(%rsp), %eax
movl %eax, 0x54(%rsp)
movl 0x14(%rsp), %eax
movl %eax, 0x58(%rsp)
movl 0x34(%rsp), %ebp
movl %ebp, 0x60(%rsp)
movl 0x2c(%rsp), %edx
movl %edx, 0x4c(%rsp)
movl 0x30(%rsp), %r13d
movl %r13d, 0x48(%rsp)
movl 0x24(%rsp), %eax
movl %eax, 0x50(%rsp)
movq 0xb403(%rip), %r14      # 0x21fd0
movslq (%r14), %rax
leal 0x2(%rax), %ecx
cmpl %r12d, %ecx
jg 0x16f3b
movq 0x8(%r15,%rax,8), %rdi
leaq 0x27bc(%rip), %rsi      # 0x193a4
callq 0x22b0
testq %rax, %rax
je 0x17073
movq %rax, %r12
movslq (%r14), %rax
movq (%r15,%rax,8), %rdi
testl %ebx, %ebx
je 0x16c0b
callq 0x32b2
jmp 0x16c10
callq 0x2f1e
movq %rax, %r14
movq %rax, 0x38(%rsp)
testq %rax, %rax
je 0x17094
cmpl $0x0, 0x10(%rsp)
je 0x16c48
movq 0x28(%r14), %rax
movq 0x10(%rax), %rcx
cmpq 0x28(%rax), %rcx
jne 0x16f25
movq 0x18(%rax), %rcx
cmpq 0x20(%rax), %rcx
jne 0x16f25
movq 0xa0(%rsp), %rdi
testq %rdi, %rdi
je 0x16c68
callq 0x15eb6
movq %rax, 0x40(%rsp)
testq %rax, %rax
je 0x170b5
movslq %ebp, %rdi
pushq $0x78
popq %rsi
callq 0x2190
leaq 0x38(%rsp), %r15
movq %rax, 0x30(%r15)
movl 0xc(%rsp), %eax
imull %ebp, %eax
movl %eax, 0xc(%rsp)
movq %r12, 0x18(%rsp)
movq %r12, %rdi
callq 0xc26c
movq %rax, %r14
xorl %ebp, %ebp
pushq $0x4
popq %rbx
leaq 0x456(%rip), %r13       # 0x170f9
movq %r14, %rdi
callq 0xc2d8
testl %eax, %eax
js 0x16df8
movl 0x70(%rsp), %r12d
cmpl 0x74(%rsp), %r12d
jne 0x16d46
leal (%r12,%r12), %eax
testl %r12d, %r12d
cmovel %ebx, %eax
movl %eax, 0x74(%rsp)
movq 0x78(%rsp), %rdi
movslq %eax, %rsi
shlq $0x3, %rsi
callq 0x2260
movq %rax, 0x78(%rsp)
movq 0x80(%rsp), %rdi
movslq 0x74(%rsp), %rsi
shlq $0x3, %rsi
callq 0x2260
movq %rax, 0x80(%rsp)
movq 0x88(%rsp), %rdi
movslq 0x74(%rsp), %rsi
shlq $0x3, %rsi
callq 0x2260
movq %rax, 0x88(%rsp)
movq 0x90(%rsp), %rdi
movslq 0x74(%rsp), %rsi
shlq $0x3, %rsi
callq 0x2260
movq %rax, 0x90(%rsp)
movl 0x70(%rsp), %r12d
movq 0x8(%r14), %rdi
callq 0x2340
movq 0x78(%rsp), %rcx
movslq %r12d, %r12
movq %rax, (%rcx,%r12,8)
movq 0x28(%r14), %rdi
callq 0x2340
movq 0x80(%rsp), %rcx
movq %rax, (%rcx,%r12,8)
cmpl $0x0, 0x30(%r14)
je 0x16d82
movq 0x38(%r14), %rdi
callq 0x2340
jmp 0x16d84
xorl %eax, %eax
movq 0x88(%rsp), %rcx
movq %rax, (%rcx,%r12,8)
incl %r12d
movl %r12d, 0x70(%rsp)
addl 0x20(%r14), %ebp
cmpl 0xc(%rsp), %ebp
jl 0x16ca3
movl 0x60(%rsp), %edi
movslq %r12d, %rcx
movq %r13, %rsi
movq %r15, %rdx
callq 0x247c
xorl %r12d, %r12d
movslq 0x70(%rsp), %rax
cmpq %rax, %r12
jge 0x16dec
movq 0x90(%rsp), %rax
movq (%rax,%r12,8), %rdi
callq 0x2080
movq 0x90(%rsp), %rax
movq (%rax,%r12,8), %rdi
callq 0x2040
incq %r12
jmp 0x16dbb
andl $0x0, 0x70(%rsp)
xorl %ebp, %ebp
jmp 0x16ca3
leaq 0x38(%rsp), %rdx
movl 0x28(%rdx), %edi
movslq 0x38(%rdx), %rcx
leaq 0x2ee(%rip), %rsi       # 0x170f9
callq 0x247c
xorl %ebx, %ebx
movslq 0x70(%rsp), %rax
cmpq %rax, %rbx
jge 0x16e43
movq 0x90(%rsp), %rax
movq (%rax,%rbx,8), %rdi
callq 0x2080
movq 0x90(%rsp), %rax
movq (%rax,%rbx,8), %rdi
callq 0x2040
incq %rbx
jmp 0x16e12
movq %r14, %rdi
callq 0xc298
xorl %ebx, %ebx
xorl %r14d, %r14d
movq 0x18(%rsp), %r15
movslq 0x60(%rsp), %rax
cmpq %rax, %r14
jge 0x16ec2
movq 0x68(%rsp), %rax
movq 0x10(%rax,%rbx), %rdi
callq 0x2040
movq 0x68(%rsp), %rax
movq 0x28(%rax,%rbx), %rdi
callq 0x2040
movq 0x68(%rsp), %rax
movq 0x40(%rax,%rbx), %rdi
callq 0x2040
movq 0x68(%rsp), %rax
movq 0x60(%rax,%rbx), %rdi
callq 0x2040
movq 0x68(%rsp), %rax
movq 0x70(%rax,%rbx), %rdi
callq 0x2040
movq 0x68(%rsp), %rax
movq 0x50(%rax,%rbx), %rdi
callq 0x2040
incq %r14
addq $0x78, %rbx
jmp 0x16e55
movq 0x78(%rsp), %rdi
callq 0x2040
movq 0x80(%rsp), %rdi
callq 0x2040
movq 0x88(%rsp), %rdi
callq 0x2040
movq 0x90(%rsp), %rdi
callq 0x2040
movq 0x68(%rsp), %rdi
callq 0x2040
movq 0x40(%rsp), %rdi
testq %rdi, %rdi
je 0x16f0c
callq 0x15cad
movq 0x38(%rsp), %rdi
callq 0x26e6
movq %r15, %rdi
callq 0x2030
xorl %eax, %eax
jmp 0x170e7
movq 0xb0cc(%rip), %rax      # 0x21ff8
movq (%rax), %rdi
leaq 0x413a(%rip), %rsi      # 0x1b070
jmp 0x170c6
movq 0xb0b6(%rip), %rbx      # 0x21ff8
movq (%rbx), %rcx
leaq 0x3e86(%rip), %rdi      # 0x1add2
movl %esi, %r12d
pushq $0x33
popq %rsi
pushq $0x1
popq %r14
movl %edx, %r15d
movq %r14, %rdx
callq 0x2310
movq (%rbx), %rcx
leaq 0x3e9b(%rip), %rdi      # 0x1ae06
pushq $0x9
popq %rsi
movq %r14, %rdx
callq 0x2310
movq (%rbx), %rcx
leaq 0x3e90(%rip), %rdi      # 0x1ae10
pushq $0x3c
popq %rsi
movq %r14, %rdx
callq 0x2310
movq (%rbx), %rcx
leaq 0x3eb8(%rip), %rdi      # 0x1ae4d
pushq $0x3d
popq %rsi
movq %r14, %rdx
callq 0x2310
movq (%rbx), %rdi
leaq 0x3ee1(%rip), %rsi      # 0x1ae8b
movl %r12d, %edx
xorl %eax, %eax
callq 0x21c0
movq (%rbx), %rdi
leaq 0x3f0d(%rip), %rsi      # 0x1aecb
movl %ebp, %edx
xorl %eax, %eax
callq 0x21c0
movq (%rbx), %rdi
leaq 0x3f1e(%rip), %rsi      # 0x1aeef
movl 0xc(%rsp), %edx
xorl %eax, %eax
callq 0x21c0
movq (%rbx), %rcx
leaq 0x3f26(%rip), %rdi      # 0x1af0c
pushq $0x24
popq %rsi
movq %r14, %rdx
callq 0x2310
movq (%rbx), %rdi
leaq 0x3f36(%rip), %rsi      # 0x1af31
movl %r13d, %edx
xorl %eax, %eax
callq 0x21c0
movq (%rbx), %rdi
leaq 0x3f6e(%rip), %rsi      # 0x1af7d
movl %r15d, %edx
xorl %eax, %eax
callq 0x21c0
movq (%rbx), %rdi
leaq 0x3f7c(%rip), %rsi      # 0x1af9f
movq 0x98(%rsp), %rdx
xorl %eax, %eax
callq 0x21c0
movq (%rbx), %rcx
leaq 0x3f80(%rip), %rdi      # 0x1afbc
pushq $0xf
popq %rsi
movq %r14, %rdx
callq 0x2310
movq (%rbx), %rcx
leaq 0x3f7b(%rip), %rdi      # 0x1afcc
pushq $0x17
popq %rsi
movq %r14, %rdx
callq 0x2310
movq (%rbx), %rcx
leaq 0x3f7e(%rip), %rdi      # 0x1afe4
pushq $0x2f
popq %rsi
movq %r14, %rdx
callq 0x2310
jmp 0x170e4
movq 0xaf7e(%rip), %rax      # 0x21ff8
movq (%rax), %rdi
leaq 0x3f90(%rip), %rsi      # 0x1b014
leaq 0x3fb3(%rip), %rdx      # 0x1b03e
xorl %eax, %eax
callq 0x21c0
jmp 0x170e4
movq 0xaf5d(%rip), %rax      # 0x21ff8
movq (%rax), %rdi
leaq 0x3fa4(%rip), %rsi      # 0x1b049
leaq 0x3f92(%rip), %rdx      # 0x1b03e
xorl %eax, %eax
callq 0x21c0
jmp 0x170dc
movq 0xaf3c(%rip), %rax      # 0x21ff8
movq (%rax), %rdi
leaq 0x3fe2(%rip), %rsi      # 0x1b0a8
leaq 0x3f71(%rip), %rdx      # 0x1b03e
xorl %eax, %eax
callq 0x21c0
movq %r14, %rdi
callq 0x26e6
movq %r12, %rdi
callq 0x2030
pushq $0x1
popq %rax
addq $0xa8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq