// File: /workspace/github_c_makefile_star2_O3/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 0x1689d
movq %rdx, %rbx
movq %rdi, 0x18(%rsp)
jle 0x16540
movl %esi, %r12d
movl $0x0, 0x4(%rsp)
movq %rbx, %r15
movl $0xffffffff, 0x8(%r15)  # imm = 0xFFFFFFFF
movl 0x10(%r15), %ebp
movl %ebp, %eax
andl $0x9fffffff, %eax       # imm = 0x9FFFFFFF
movl %eax, 0x10(%r15)
movq %r15, %rdi
callq 0x14632
andl $0x1fffffff, %eax       # imm = 0x1FFFFFFF
andl $0x80000000, %ebp       # imm = 0x80000000
orl %eax, %ebp
movl %ebp, 0x10(%r15)
movq 0x18(%rsp), %rcx
cmpl 0x7c(%rcx), %eax
jge 0x16509
movq 0x20(%r15), %rdi
callq 0x3390
jmp 0x16535
movl 0x4(%rsp), %ecx
movslq %ecx, %rax
incl %ecx
movl %ecx, 0x4(%rsp)
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 0x164c4
jmp 0x16548
movl $0x0, 0x4(%rsp)
movl 0x4(%rsp), %ebp
movslq %ebp, %r15
movq %r15, %rdi
movq %rbx, %rsi
callq 0x15da2
orb $0x60, 0x13(%rbx)
leaq 0x1235b(%rip), %rdx     # 0x288c0
leaq 0x1243e(%rip), %r8      # 0x289aa
movl $0x8, %esi
xorl %edi, %edi
movl $0x1a6, %ecx            # imm = 0x1A6
callq 0x2324c
movl $0x0, (%rax)
movl $0x1, %r12d
movl %ebp, %esi
cmpl $0x2, %r15d
movq %rsi, 0x8(%rsp)
jl 0x1677e
movl $0x1, %r15d
movl $0x2, %ecx
movq %rcx, 0x20(%rsp)
testq %r12, %r12
je 0x166fa
leaq (%r15,%r15,4), %rcx
leaq (%rbx,%rcx,8), %rdx
movq 0x20(%rdx), %rcx
movl 0x8(%rcx), %esi
movslq (%rdx), %rdi
leaq (%rdi,%rdi,2), %rdi
movl -0xc(%rcx,%rdi,8), %r8d
addl -0x10(%rcx,%rdi,8), %r8d
movl %r8d, %r9d
subl %esi, %r9d
xorl %ecx, %ecx
movl $0x0, 0x14(%rsp)
movslq (%rax,%rcx,4), %rdi
leaq (%rdi,%rdi,4), %r10
movq 0x20(%rbx,%r10,8), %rdi
movl 0x8(%rdi), %r11d
movl %r11d, %ebp
cmpl %esi, %r11d
jg 0x165fe
movl %esi, %ebp
movslq (%rbx,%r10,8), %r13
leaq (,%r13,2), %r14
addq %r13, %r14
movl -0xc(%rdi,%r14,8), %r13d
addl -0x10(%rdi,%r14,8), %r13d
movl %r13d, %edi
cmpl %r8d, %r13d
jl 0x16622
movl %r8d, %edi
subl %ebp, %edi
jle 0x166d3
leaq (%rbx,%r10,8), %rbp
movl 0x10(%rbp), %r10d
testl %r10d, %r10d
js 0x166c9
subl %r11d, %r13d
movl %r9d, %r11d
cmpl %r13d, %r9d
jl 0x16649
movl %r13d, %r11d
xorps %xmm0, %xmm0
cvtsi2ss %edi, %xmm0
xorps %xmm1, %xmm1
cvtsi2ss %r11d, %xmm1
movq 0x18(%rsp), %rdi
mulss 0x9c(%rdi), %xmm1
ucomiss %xmm1, %xmm0
jb 0x166d3
cmpl 0x90(%rdi), %r11d
jge 0x166d3
cmpl $0x0, 0x8(%rbp)
jns 0x1667d
movl %r15d, 0x8(%rbp)
movl 0x10(%rdx), %edi
movl $0x1fffffff, %r11d      # imm = 0x1FFFFFFF
andl %r11d, %edi
xorps %xmm0, %xmm0
cvtsi2ss %edi, %xmm0
andl %r11d, %r10d
xorps %xmm1, %xmm1
cvtsi2ss %r10d, %xmm1
movq 0x18(%rsp), %r11
mulss 0xa0(%r11), %xmm1
movl $0x1, 0x14(%rsp)
ucomiss %xmm0, %xmm1
jbe 0x166d3
subl %edi, %r10d
movl 0x78(%r11), %edi
addl %edi, %edi
cmpl %edi, %r10d
jl 0x166d3
jmp 0x16774
cmpl $0x0, 0x10(%rdx)
js 0x1663b
incq %rcx
cmpq %rcx, %r12
jne 0x165e3
xorl %ebp, %ebp
cmpl $0x0, 0x14(%rsp)
sete %bpl
orl $0x2, %ebp
shll $0x1d, %ebp
movq %r12, %rcx
movq 0x8(%rsp), %rsi
jmp 0x16701
movl $0x60000000, %ebp       # imm = 0x60000000
xorl %ecx, %ecx
cmpq %rcx, %r12
jne 0x16766
cmpq 0x20(%rsp), %r12
jne 0x1674a
leaq (%r12,%r12), %rdx
testq %r12, %r12
movl $0x2, %ecx
cmoveq %rcx, %rdx
movq %rdx, 0x20(%rsp)
leaq (,%rdx,4), %rsi
movq %rax, %rdi
leaq 0x1218c(%rip), %rdx     # 0x288c0
movl $0x1ba, %ecx            # imm = 0x1BA
leaq 0x1226a(%rip), %r8      # 0x289aa
callq 0x2324c
movq 0x8(%rsp), %rsi
movl %r15d, (%rax,%r12,4)
incq %r12
leaq (%r15,%r15,4), %rcx
movl 0x10(%rbx,%rcx,8), %edx
movl $0x9fffffff, %edi       # imm = 0x9FFFFFFF
andl %edi, %edx
orl %ebp, %edx
movl %edx, 0x10(%rbx,%rcx,8)
incq %r15
cmpq %rsi, %r15
jne 0x165aa
jmp 0x16784
movl $0x40000000, %ebp       # imm = 0x40000000
jmp 0x166f3
movl 0x4(%rsp), %ebp
jmp 0x1678d
testq %r12, %r12
movl 0x4(%rsp), %ebp
je 0x167c2
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 0x167ba
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, %r12
jne 0x16794
movq %rax, %rdi
callq 0x3390
testl %ebp, %ebp
jle 0x16807
leaq 0x10(%rbx), %rcx
xorl %eax, %eax
xorl %edx, %edx
movq 0x18(%rsp), %rdi
movq 0x8(%rsp), %r8
movl (%rcx), %esi
shrl $0x1d, %esi
andl $0x3, %esi
je 0x167f9
cmpl $0x3, %esi
je 0x167f9
incl %edx
cmpl 0x80(%rdi), %edx
jge 0x1680e
incq %rax
addq $0x28, %rcx
cmpq %rax, %r8
jne 0x167e0
jmp 0x16840
xorl %eax, %eax
movq 0x8(%rsp), %r8
cmpl %ebp, %eax
jge 0x16840
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 0x16836
andl $0x9fffffff, %edx       # imm = 0x9FFFFFFF
movl %edx, (%rcx)
addq $0x28, %rcx
incl %eax
cmpl %eax, %ebp
jg 0x16820
testl %ebp, %ebp
jle 0x1689d
leaq 0x20(%rbx), %r14
shlq $0x3, %r8
leaq (%r8,%r8,4), %r15
xorl %r12d, %r12d
xorl %ebp, %ebp
testb $0x60, -0xd(%r14,%r12)
je 0x16889
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 0x16892
movq (%r14,%r12), %rdi
callq 0x3390
addq $0x28, %r12
cmpq %r12, %r15
jne 0x16855
jmp 0x1689f
xorl %ebp, %ebp
movl %ebp, %eax
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq