// File: /workspace/github_c_makefile_star2_O1/xiongxu[P]bam2bedGraph2/samtools-0.1.19/bam_sort.c
// Function: bam_sort_core_ext
void bam_sort_core_ext(int is_by_qname, const char *fn, const char *prefix, size_t _max_mem, int is_stdout, int n_threads, int level, int full_path)
{
	int ret, i, n_files = 0;
	size_t mem, max_k, k, max_mem;
	bam_header_t *header;
	bamFile fp;
	bam1_t *b, **buf;
	char *fnout = 0;
	char const *suffix = ".bam";
	if (full_path) suffix += 4;

	if (n_threads < 2) n_threads = 1;
	g_is_by_qname = is_by_qname;
	max_k = k = 0; mem = 0;
	max_mem = _max_mem * n_threads;
	buf = 0;
	fp = strcmp(fn, "-")? bam_open(fn, "r") : bam_dopen(fileno(stdin), "r");
	if (fp == 0) {
		fprintf(stderr, "[bam_sort_core] fail to open file %s\n", fn);
		return;
	}
	header = bam_header_read(fp);
	if (is_by_qname) change_SO(header, "queryname");
	else change_SO(header, "coordinate");
	// write sub files
	for (;;) {
		if (k == max_k) {
			size_t old_max = max_k;
			max_k = max_k? max_k<<1 : 0x10000;
			buf = realloc(buf, max_k * sizeof(void*));
			memset(buf + old_max, 0, sizeof(void*) * (max_k - old_max));
		}
		if (buf[k] == 0) buf[k] = (bam1_t*)calloc(1, sizeof(bam1_t));
		b = buf[k];
		if ((ret = bam_read1(fp, b)) < 0) break;
		if (b->data_len < b->m_data>>2) { // shrink
			b->m_data = b->data_len;
			kroundup32(b->m_data);
			b->data = realloc(b->data, b->m_data);
		}
		mem += sizeof(bam1_t) + b->m_data + sizeof(void*) + sizeof(void*); // two sizeof(void*) for the data allocated to pointer arrays
		++k;
		if (mem >= max_mem) {
			n_files = sort_blocks(n_files, k, buf, prefix, header, n_threads);
			mem = k = 0;
		}
	}
	if (ret != -1)
		fprintf(stderr, "[bam_sort_core] truncated file. Continue anyway.\n");
	// output file name
	fnout = calloc(strlen(prefix) + 20, 1);
	if (is_stdout) sprintf(fnout, "-");
	else sprintf(fnout, "%s%s", prefix, suffix);
	// write the final output
	if (n_files == 0) { // a single block
		char mode[8];
		strcpy(mode, "w");
		if (level >= 0) sprintf(mode + 1, "%d", level < 9? level : 9);
		ks_mergesort(sort, k, buf, 0);
		write_buffer(fnout, mode, k, buf, header, n_threads);
	} else { // then merge
		char **fns;
		n_files = sort_blocks(n_files, k, buf, prefix, header, n_threads);
		fprintf(stderr, "[bam_sort_core] merging from %d files...\n", n_files);
		fns = (char**)calloc(n_files, sizeof(char*));
		for (i = 0; i < n_files; ++i) {
			fns[i] = (char*)calloc(strlen(prefix) + 20, 1);
			sprintf(fns[i], "%s.%.4d%s", prefix, i, suffix);
		}
		bam_merge_core2(is_by_qname, fnout, 0, n_files, fns, 0, 0, n_threads, level);
		for (i = 0; i < n_files; ++i) {
			unlink(fns[i]);
			free(fns[i]);
		}
		free(fns);
	}
	free(fnout);
	// free
	for (k = 0; k < max_k; ++k) {
		if (!buf[k]) continue;
		free(buf[k]->data);
		free(buf[k]);
	}
	free(buf);
	bam_header_destroy(header);
	bam_close(fp);
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x58, %rsp
movl %r8d, 0x10(%rsp)
movq %rcx, 0x8(%rsp)
movq %rdx, 0x40(%rsp)
movq %rsi, %r15
movl %edi, %ebp
movl 0x90(%rsp), %eax
movq %rax, 0x38(%rsp)
cmpl $0x0, 0x98(%rsp)
leaq 0xbb35(%rip), %rax      # 0x41055
leaq 0xbb32(%rip), %r12      # 0x41059
cmoveq %rax, %r12
cmpl $0x2, %r9d
movl $0x1, %ebx
cmovgel %r9d, %ebx
movl %edi, 0x1ae32(%rip)     # 0x50370
leaq 0x9913(%rip), %rsi      # 0x3ee58
movq %r15, %rdi
callq 0x35a0
testl %eax, %eax
je 0x35562
leaq 0xf717(%rip), %rsi      # 0x44c6f
movq %r15, %rdi
callq 0x1fdb8
jmp 0x3557f
movq 0x19a67(%rip), %rax     # 0x4efd0
movq (%rax), %rdi
callq 0x3030
leaq 0xf6f7(%rip), %rsi      # 0x44c6f
movl %eax, %edi
callq 0x1ff6b
testq %rax, %rax
je 0x357e7
movq %r12, 0x30(%rsp)
movq %rbx, 0x18(%rsp)
movq 0x8(%rsp), %rcx
imulq %rbx, %rcx
movq %rcx, 0x8(%rsp)
movq %rax, 0x48(%rsp)
movq %rax, %rdi
callq 0x22efa
movq %rax, %rdi
movl %ebp, 0x2c(%rsp)
testl %ebp, %ebp
leaq 0xef3e(%rip), %rax      # 0x444fb
leaq 0xef2d(%rip), %rsi      # 0x444f1
cmoveq %rax, %rsi
movq %rdi, 0x20(%rsp)
callq 0x35925
xorl %r15d, %r15d
xorl %r14d, %r14d
xorl %r12d, %r12d
xorl %ebp, %ebp
xorl %ebx, %ebx
cmpq %r15, %rbp
jne 0x3561f
leaq (%r15,%r15), %r13
testq %r15, %r15
movl $0x10000, %eax          # imm = 0x10000
cmoveq %rax, %r13
leaq (,%r13,8), %rsi
movq %r12, %rdi
callq 0x3720
movq %rax, %r12
leaq (%rax,%r15,8), %rdi
movq %r13, %rdx
subq %r15, %rdx
shlq $0x3, %rdx
xorl %esi, %esi
callq 0x3080
movq %r13, %r15
cmpq $0x0, (%r12,%rbp,8)
jne 0x35639
movl $0x1, %edi
movl $0x38, %esi
callq 0x3610
movq %rax, (%r12,%rbp,8)
movq (%r12,%rbp,8), %r13
movq 0x48(%rsp), %rdi
movq %r13, %rsi
callq 0x23238
testl %eax, %eax
js 0x356d9
movl 0x24(%r13), %eax
movl 0x28(%r13), %ecx
sarl $0x2, %ecx
cmpl %ecx, %eax
jge 0x3569b
decl %eax
movl %eax, %ecx
sarl %ecx
orl %eax, %ecx
movl %ecx, %eax
sarl $0x2, %eax
orl %ecx, %eax
movl %eax, %ecx
sarl $0x4, %ecx
orl %eax, %ecx
movl %ecx, %eax
sarl $0x8, %eax
orl %ecx, %eax
movl %eax, %ecx
sarl $0x10, %ecx
orl %eax, %ecx
incl %ecx
movl %ecx, 0x28(%r13)
movq 0x30(%r13), %rdi
movslq %ecx, %rsi
callq 0x3720
movq %rax, 0x30(%r13)
movslq 0x28(%r13), %rax
addq %rax, %rbx
addq $0x48, %rbx
incq %rbp
cmpq 0x8(%rsp), %rbx
jb 0x355df
movl %r14d, %edi
movq %rbp, %rsi
movq %r12, %rdx
movq 0x40(%rsp), %rcx
movq 0x20(%rsp), %r8
movq 0x18(%rsp), %r9
callq 0x35a95
movl %eax, %r14d
jmp 0x355db
cmpl $-0x1, %eax
jne 0x35810
movq 0x40(%rsp), %rbx
movq %rbx, %rdi
callq 0x3360
leaq 0x14(%rax), %rdi
movl $0x1, %esi
callq 0x3610
movq %rax, %r13
cmpl $0x0, 0x10(%rsp)
je 0x35710
movw $0x2d, (%r13)
jmp 0x35729
leaq 0xee21(%rip), %rsi      # 0x44538
movq %r13, %rdi
movq %rbx, %rdx
movq 0x30(%rsp), %rcx
xorl %eax, %eax
callq 0x3400
testl %r14d, %r14d
movq 0x38(%rsp), %rax
jne 0x3581a
movw $0x77, 0x50(%rsp)
testl %eax, %eax
js 0x35760
leaq 0x51(%rsp), %rdi
cmpl $0x9, %eax
movl $0x9, %edx
cmovll %eax, %edx
leaq 0xdb39(%rip), %rsi      # 0x43292
xorl %eax, %eax
callq 0x3400
movq %rbp, %rdi
movq %r12, %rsi
xorl %edx, %edx
callq 0x340f7
leaq 0x50(%rsp), %rsi
movq %r13, %rdi
movq %rbp, %rdx
movq %r12, %rcx
movq 0x20(%rsp), %r8
movq 0x18(%rsp), %r9
callq 0x35bb6
movq %r13, %rdi
callq 0x3350
testq %r15, %r15
je 0x357bc
xorl %ebx, %ebx
movq (%r12,%rbx,8), %rax
testq %rax, %rax
je 0x357b4
movq 0x30(%rax), %rdi
callq 0x3350
movq (%r12,%rbx,8), %rdi
callq 0x3350
incq %rbx
cmpq %rbx, %r15
jne 0x35799
movq %r12, %rdi
callq 0x3350
movq 0x20(%rsp), %rdi
callq 0x22e78
movq 0x48(%rsp), %rdi
callq 0x20aae
addq $0x58, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq 0x197fa(%rip), %rax     # 0x4efe8
movq (%rax), %rdi
leaq 0xecd3(%rip), %rsi      # 0x444cb
movq %r15, %rdx
xorl %eax, %eax
addq $0x58, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x3750
callq 0x575e
jmp 0x356e2
movq %r13, 0x10(%rsp)
movl %r14d, %edi
movq %rbp, %rsi
movq %r12, %rdx
movq %rbx, %rcx
movq 0x20(%rsp), %r8
movq 0x18(%rsp), %r9
callq 0x35a95
movl %eax, %ebp
movq 0x197a5(%rip), %rax     # 0x4efe8
movq (%rax), %rdi
leaq 0xecf0(%rip), %rsi      # 0x4453d
movl %ebp, %edx
xorl %eax, %eax
callq 0x3750
movl %ebp, 0x28(%rsp)
movslq %ebp, %r13
movl $0x8, %esi
movq %r13, %rdi
callq 0x3610
movq %rax, %r14
movl %r13d, %eax
movq %rax, 0x8(%rsp)
testl %r13d, %r13d
movq 0x30(%rsp), %r13
jle 0x358be
xorl %ebp, %ebp
movq %rbx, %rdi
callq 0x3360
leaq 0x14(%rax), %rdi
movl $0x1, %esi
callq 0x3610
movq %rax, (%r14,%rbp,8)
movq %rax, %rdi
leaq 0xecc2(%rip), %rsi      # 0x44567
movq %rbx, %rdx
movl %ebp, %ecx
movq %r13, %r8
xorl %eax, %eax
callq 0x3400
incq %rbp
cmpq %rbp, 0x8(%rsp)
jne 0x35881
subq $0x8, %rsp
movl 0x34(%rsp), %edi
movq 0x18(%rsp), %rsi
xorl %edx, %edx
movl 0x30(%rsp), %ebx
movl %ebx, %ecx
movq %r14, %r8
xorl %r9d, %r9d
pushq 0x40(%rsp)
pushq 0x28(%rsp)
pushq $0x0
callq 0x3363c
addq $0x20, %rsp
testl %ebx, %ebx
movq 0x8(%rsp), %rbx
jle 0x35913
xorl %ebp, %ebp
movq (%r14,%rbp,8), %r13
movq %r13, %rdi
callq 0x3250
movq %r13, %rdi
callq 0x3350
incq %rbp
cmpq %rbp, %rbx
jne 0x358f7
movq %r14, %rdi
callq 0x3350
movq 0x10(%rsp), %r13
jmp 0x3578a