// File: /workspace/github_c_makefile_star2_O1/ToniWestbrook[P]paladin/bwamem.c
// Function: mem_chain_flt
int mem_chain_flt(const mem_opt_t *opt, int n_chn, mem_chain_t *a)
{
	int i, k;
	kvec_t(int) chains = {0,0,0}; // this keeps int indices of the non-overlapping chains
	if (n_chn == 0) return 0; // no need to filter
	// compute the weight of each chain and drop chains with small weight
	for (i = k = 0; i < n_chn; ++i) {
		mem_chain_t *c = &a[i];
		c->first = -1; c->kept = 0;
		c->w = mem_chain_weight(c);
		if (c->w < opt->min_chain_weight) free(c->seeds);
		else a[k++] = *c;
	}
	n_chn = k;
	ks_introsort(mem_flt, n_chn, a);
	// pairwise chain comparisons
	a[0].kept = 3;
	kv_push(int, chains, 0);
	for (i = 1; i < n_chn; ++i) {
		int large_ovlp = 0;
		for (k = 0; k < chains.n; ++k) {
			int j = chains.a[k];
			int b_max = chn_beg(a[j]) > chn_beg(a[i])? chn_beg(a[j]) : chn_beg(a[i]);
			int e_min = chn_end(a[j]) < chn_end(a[i])? chn_end(a[j]) : chn_end(a[i]);
			if (e_min > b_max && (!a[j].is_alt || a[i].is_alt)) { // have overlap; don't consider ovlp where the kept chain is ALT while the current chain is primary
				int li = chn_end(a[i]) - chn_beg(a[i]);
				int lj = chn_end(a[j]) - chn_beg(a[j]);
				int min_l = li < lj? li : lj;
				if (e_min - b_max >= min_l * opt->mask_level && min_l < opt->max_chain_gap) { // significant overlap
					large_ovlp = 1;
					if (a[j].first < 0) a[j].first = i; // keep the first shadowed hit s.t. mapq can be more accurate
					if (a[i].w < a[j].w * opt->drop_ratio && a[j].w - a[i].w >= opt->min_seed_len<<1)
						break;
				}
			}
		}
		if (k == chains.n) {
			kv_push(int, chains, i);
			a[i].kept = large_ovlp? 2 : 3;
		}
	}
	for (i = 0; i < chains.n; ++i) {
		mem_chain_t *c = &a[chains.a[i]];
		if (c->first >= 0) a[c->first].kept = 1;
	}
	free(chains.a);
	for (i = k = 0; i < n_chn; ++i) { // don't extend more than opt->max_chain_extend .kept=1/2 chains
		if (a[i].kept == 0 || a[i].kept == 3) continue;
		if (++k >= opt->max_chain_extend) break;
	}
	for (; i < n_chn; ++i)
		if (a[i].kept < 3) a[i].kept = 0;
	for (i = k = 0; i < n_chn; ++i) { // free discarded chains
		mem_chain_t *c = &a[i];
		if (c->kept == 0) free(c->seeds);
		else a[k++] = a[i];
	}
	return k;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x28, %rsp
testl %esi, %esi
je 0x162c1
movq %rdx, %rbx
movq %rdi, 0x10(%rsp)
jle 0x15f79
movl %esi, %r12d
xorl %ebp, %ebp
movq %rbx, %r15
movl $0xffffffff, 0x8(%r15)  # imm = 0xFFFFFFFF
movl 0x10(%r15), %r14d
movl %r14d, %eax
andl $0x9fffffff, %eax       # imm = 0x9FFFFFFF
movl %eax, 0x10(%r15)
movq %r15, %rdi
callq 0x142c3
andl $0x1fffffff, %eax       # imm = 0x1FFFFFFF
andl $0x80000000, %r14d      # imm = 0x80000000
orl %eax, %r14d
movl %r14d, 0x10(%r15)
movq 0x10(%rsp), %rcx
cmpl 0x7c(%rcx), %eax
jge 0x15f4a
movq 0x20(%r15), %rdi
callq 0x3390
jmp 0x15f6e
movslq %ebp, %rax
incl %ebp
leaq (%rax,%rax,4), %rax
movq 0x20(%r15), %rcx
movq %rcx, 0x20(%rbx,%rax,8)
movups (%r15), %xmm0
movups 0x10(%r15), %xmm1
movups %xmm1, 0x10(%rbx,%rax,8)
movups %xmm0, (%rbx,%rax,8)
addq $0x28, %r15
decq %r12
jne 0x15f02
jmp 0x15f7b
xorl %ebp, %ebp
movl %ebp, %r14d
movslq %ebp, %r15
movq %r15, %rdi
movq %rbx, %rsi
callq 0x157ea
orb $0x60, 0x13(%rbx)
leaq 0x12839(%rip), %rdx     # 0x287d0
leaq 0x1291c(%rip), %r8      # 0x288ba
movl $0x8, %esi
xorl %edi, %edi
movl $0x1a6, %ecx            # imm = 0x1A6
callq 0x22d64
movl $0x0, (%rax)
movl $0x1, %ebp
cmpl $0x2, %r15d
jl 0x161ac
movl $0x1, %r15d
movl $0x2, %edi
movq %r14, 0x18(%rsp)
testq %rbp, %rbp
je 0x16136
movq %rdi, 0x20(%rsp)
leaq (%r15,%r15,4), %rcx
leaq (%rbx,%rcx,8), %rsi
movq 0x20(%rsi), %rcx
movl 0x8(%rcx), %r14d
movslq (%rsi), %rdx
leaq (%rdx,%rdx,2), %rdx
movl -0xc(%rcx,%rdx,8), %r9d
addl -0x10(%rcx,%rdx,8), %r9d
movl %r9d, %r10d
subl %r14d, %r10d
xorl %edx, %edx
movl $0x0, 0xc(%rsp)
movslq (%rax,%rdx,4), %rcx
leaq (%rcx,%rcx,4), %r12
movq 0x20(%rbx,%r12,8), %r8
movl 0x8(%r8), %ecx
movl %ecx, %edi
cmpl %r14d, %ecx
jg 0x1602e
movl %r14d, %edi
movslq (%rbx,%r12,8), %r11
leaq (%r11,%r11,2), %r11
movl -0xc(%r8,%r11,8), %r13d
addl -0x10(%r8,%r11,8), %r13d
movl %r13d, %r8d
cmpl %r9d, %r13d
jl 0x1604b
movl %r9d, %r8d
movb $0x1, %r11b
subl %edi, %r8d
jle 0x16102
leaq (%rbx,%r12,8), %r12
cmpl $0x0, 0x10(%r12)
js 0x160f8
subl %ecx, %r13d
movl %r10d, %ecx
cmpl %r13d, %r10d
jl 0x16075
movl %r13d, %ecx
xorps %xmm0, %xmm0
cvtsi2ss %r8d, %xmm0
xorps %xmm1, %xmm1
cvtsi2ss %ecx, %xmm1
movq 0x10(%rsp), %rdi
mulss 0x9c(%rdi), %xmm1
ucomiss %xmm1, %xmm0
jb 0x16102
cmpl 0x90(%rdi), %ecx
jge 0x16102
cmpl $0x0, 0x8(%r12)
jns 0x160ab
movl %r15d, 0x8(%r12)
movl 0x10(%rsi), %ecx
movl $0x1fffffff, %r8d       # imm = 0x1FFFFFFF
andl %r8d, %ecx
xorps %xmm0, %xmm0
cvtsi2ss %ecx, %xmm0
movl 0x10(%r12), %edi
andl %r8d, %edi
xorps %xmm1, %xmm1
cvtsi2ss %edi, %xmm1
movq 0x10(%rsp), %r8
mulss 0xa0(%r8), %xmm1
movl $0x1, 0xc(%rsp)
ucomiss %xmm0, %xmm1
jbe 0x16102
subl %ecx, %edi
movl 0x78(%r8), %ecx
addl %ecx, %ecx
cmpl %ecx, %edi
setl %r11b
jmp 0x16102
cmpl $0x0, 0x10(%rsi)
js 0x16067
testb %r11b, %r11b
je 0x16116
incq %rdx
cmpq %rdx, %rbp
jne 0x16013
movq %rbp, %rdx
xorl %r12d, %r12d
cmpl $0x0, 0xc(%rsp)
sete %r12b
orl $0x2, %r12d
shll $0x1d, %r12d
movq 0x18(%rsp), %r14
movq 0x20(%rsp), %rdi
jmp 0x1613e
movl $0x60000000, %r12d      # imm = 0x60000000
xorl %edx, %edx
cmpq %rdx, %rbp
jne 0x161a0
cmpq %rdi, %rbp
jne 0x16183
leaq (%rdi,%rdi), %r14
testq %rdi, %rdi
movl $0x2, %ecx
cmoveq %rcx, %r14
leaq (,%r14,4), %rsi
movq %rax, %rdi
leaq 0x12666(%rip), %rdx     # 0x287d0
movl $0x1ba, %ecx            # imm = 0x1BA
leaq 0x12744(%rip), %r8      # 0x288ba
callq 0x22d64
movq %r14, %rdi
movq 0x18(%rsp), %r14
movl %r15d, (%rax,%rbp,4)
incq %rbp
leaq (%r15,%r15,4), %rcx
movl 0x10(%rbx,%rcx,8), %edx
movl $0x9fffffff, %esi       # imm = 0x9FFFFFFF
andl %esi, %edx
orl %r12d, %edx
movl %edx, 0x10(%rbx,%rcx,8)
incq %r15
cmpq %r14, %r15
jne 0x15fd4
testq %rbp, %rbp
je 0x161e6
xorl %ecx, %ecx
movl $0x9fffffff, %edx       # imm = 0x9FFFFFFF
movslq (%rax,%rcx,4), %rsi
leaq (%rsi,%rsi,4), %rsi
movslq 0x8(%rbx,%rsi,8), %rsi
testq %rsi, %rsi
js 0x161de
leaq (%rsi,%rsi,4), %rsi
movl 0x10(%rbx,%rsi,8), %edi
andl %edx, %edi
orl $0x20000000, %edi       # imm = 0x20000000
movl %edi, 0x10(%rbx,%rsi,8)
incq %rcx
cmpq %rcx, %rbp
jne 0x161b8
movq %rax, %rdi
callq 0x3390
testl %r14d, %r14d
jle 0x1622a
leaq 0x10(%rbx), %rcx
xorl %eax, %eax
xorl %edx, %edx
movq 0x10(%rsp), %rdi
movl (%rcx), %esi
shrl $0x1d, %esi
andl $0x3, %esi
je 0x16219
cmpl $0x3, %esi
je 0x16219
incl %edx
cmpl 0x80(%rdi), %edx
jge 0x1622c
incq %rax
addq $0x28, %rcx
cmpq %rax, %r14
jne 0x16200
movl %r14d, %eax
jmp 0x1622c
xorl %eax, %eax
cmpl %r14d, %eax
jge 0x16260
movl %eax, %ecx
leaq (%rcx,%rcx,4), %rcx
leaq (%rbx,%rcx,8), %rcx
addq $0x10, %rcx
movl (%rcx), %edx
movl %edx, %esi
notl %esi
testl $0x60000000, %esi       # imm = 0x60000000
je 0x16255
andl $0x9fffffff, %edx       # imm = 0x9FFFFFFF
movl %edx, (%rcx)
addq $0x28, %rcx
incl %eax
cmpl %eax, %r14d
jg 0x1623f
testl %r14d, %r14d
jle 0x162c1
movq %r14, %rax
leaq 0x20(%rbx), %r14
shlq $0x3, %rax
leaq (%rax,%rax,4), %r15
xorl %r12d, %r12d
xorl %ebp, %ebp
testb $0x60, -0xd(%r14,%r12)
je 0x162ad
leaq (%r14,%r12), %rax
addq $-0x20, %rax
movslq %ebp, %rcx
incl %ebp
leaq (%rcx,%rcx,4), %rcx
movq 0x20(%rax), %rdx
movq %rdx, 0x20(%rbx,%rcx,8)
movups (%rax), %xmm0
movups 0x10(%rax), %xmm1
movups %xmm1, 0x10(%rbx,%rcx,8)
movups %xmm0, (%rbx,%rcx,8)
jmp 0x162b6
movq (%r14,%r12), %rdi
callq 0x3390
addq $0x28, %r12
cmpq %r12, %r15
jne 0x16279
jmp 0x162c3
xorl %ebp, %ebp
movl %ebp, %eax
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq