// File: /workspace/github_c_makefile_star2_O3/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, %r12
movq %rsi, %r15
movl %edi, %ebp
cmpl $0x0, 0x98(%rsp)
leaq 0xc28f(%rip), %rax      # 0x420a5
leaq 0xc28c(%rip), %rcx      # 0x420a9
cmoveq %rax, %rcx
movq %rcx, 0x40(%rsp)
cmpl $0x2, %r9d
movl $0x1, %ebx
cmovgel %r9d, %ebx
movl 0x90(%rsp), %eax
movq %rax, 0x38(%rsp)
movl %edi, 0x1b52b(%rip)     # 0x51370
cmpb $0x2d, (%rsi)
jne 0x35e55
cmpb $0x0, 0x1(%r15)
je 0x360de
leaq 0xfef3(%rip), %rsi      # 0x45d4f
movq %r15, %rdi
callq 0x20308
testq %rax, %rax
je 0x36100
movq %r12, 0x20(%rsp)
movq %rbx, 0x28(%rsp)
movq 0x8(%rsp), %rcx
imulq %rbx, %rcx
movq %rcx, 0x8(%rsp)
movq %rax, 0x48(%rsp)
movq %rax, %rdi
callq 0x235fb
movq %rax, %rdi
movl %ebp, 0x1c(%rsp)
testl %ebp, %ebp
leaq 0xf739(%rip), %rax      # 0x455db
leaq 0xf728(%rip), %rsi      # 0x455d1
cmoveq %rax, %rsi
movq %rdi, 0x30(%rsp)
callq 0x3626c
xorl %r12d, %r12d
xorl %r14d, %r14d
xorl %r15d, %r15d
xorl %ebp, %ebp
xorl %ebx, %ebx
cmpq %r12, %rbp
jne 0x35f05
leaq (,%rbp,2), %r12
testq %rbp, %rbp
movl $0x10000, %eax          # imm = 0x10000
cmoveq %rax, %r12
leaq (,%r12,8), %rsi
movq %r15, %rdi
callq 0x3720
movq %rax, %r15
leaq (%rax,%rbp,8), %rdi
movq %r12, %rdx
subq %rbp, %rdx
shlq $0x3, %rdx
xorl %esi, %esi
callq 0x3080
movq (%r15,%rbp,8), %r13
testq %r13, %r13
jne 0x35f24
movl $0x1, %edi
movl $0x38, %esi
callq 0x3610
movq %rax, %r13
movq %rax, (%r15,%rbp,8)
movq 0x48(%rsp), %rdi
movq %r13, %rsi
callq 0x2393b
testl %eax, %eax
js 0x35fc5
movl 0x24(%r13), %eax
movl 0x28(%r13), %ecx
movl %ecx, %edx
sarl $0x2, %edx
cmpl %edx, %eax
jge 0x35f88
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)
movl 0x28(%r13), %ecx
movslq %ecx, %rax
addq %rax, %rbx
addq $0x48, %rbx
incq %rbp
cmpq 0x8(%rsp), %rbx
jb 0x35ec4
movl %r14d, %edi
movq %rbp, %rsi
movq %r15, %rdx
movq 0x20(%rsp), %rcx
movq 0x30(%rsp), %r8
movq 0x28(%rsp), %r9
callq 0x363de
movl %eax, %r14d
jmp 0x35ec0
cmpl $-0x1, %eax
jne 0x36129
movq 0x20(%rsp), %rbx
movq %rbx, %rdi
callq 0x3360
leaq 0x14(%rax), %rdi
movl $0x1, %esi
callq 0x3610
movq %rax, %r13
cmpl $0x0, 0x10(%rsp)
movq 0x28(%rsp), %r9
je 0x36001
movw $0x2d, (%r13)
jmp 0x3601f
leaq 0xf610(%rip), %rsi      # 0x45618
movq %r13, %rdi
movq %rbx, %rdx
movq 0x40(%rsp), %rcx
xorl %eax, %eax
callq 0x3400
movq 0x28(%rsp), %r9
testl %r14d, %r14d
movq 0x38(%rsp), %rax
jne 0x36133
movq %r9, %rbx
movw $0x77, 0x50(%rsp)
testl %eax, %eax
js 0x36059
leaq 0x51(%rsp), %rdi
cmpl $0x9, %eax
movl $0x9, %edx
cmovbl %eax, %edx
leaq 0xe322(%rip), %rsi      # 0x44374
xorl %eax, %eax
callq 0x3400
movq %rbp, %rdi
movq %r15, %rsi
xorl %edx, %edx
callq 0x34a02
leaq 0x50(%rsp), %rsi
movq %r13, %rdi
movq %rbp, %rdx
movq %r15, %rcx
movq 0x30(%rsp), %r8
movl %ebx, %r9d
callq 0x364ff
movq %r13, %rdi
callq 0x3350
testq %r12, %r12
je 0x360b3
xorl %ebx, %ebx
movq (%r15,%rbx,8), %rax
testq %rax, %rax
je 0x360ab
movq 0x30(%rax), %rdi
callq 0x3350
movq (%r15,%rbx,8), %rdi
callq 0x3350
incq %rbx
cmpq %rbx, %r12
jne 0x36090
movq %r15, %rdi
callq 0x3350
movq 0x30(%rsp), %rdi
callq 0x23577
movq 0x48(%rsp), %rdi
callq 0x21311
addq $0x58, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq 0x19eeb(%rip), %rax     # 0x4ffd0
movq (%rax), %rdi
callq 0x3030
leaq 0xfc5b(%rip), %rsi      # 0x45d4f
movl %eax, %edi
callq 0x20487
jmp 0x35e64
movq 0x19ee1(%rip), %rax     # 0x4ffe8
movq (%rax), %rdi
leaq 0xf49a(%rip), %rsi      # 0x455ab
movq %r15, %rdx
xorl %eax, %eax
addq $0x58, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x3750
callq 0x59bf
jmp 0x35fce
movq %r13, 0x10(%rsp)
movl %r14d, %edi
movq %rbp, %rsi
movq %r15, %rdx
movq 0x20(%rsp), %rcx
movq 0x30(%rsp), %r8
movq %r9, %rbx
callq 0x363de
movl %eax, %ebp
movl %eax, %eax
movq %rax, 0x8(%rsp)
movq 0x19e85(%rip), %rax     # 0x4ffe8
movq (%rax), %rdi
leaq 0xf4b0(%rip), %rsi      # 0x4561d
movl %ebp, %edx
xorl %eax, %eax
callq 0x3750
movslq %ebp, %r13
movl $0x8, %esi
movq %r13, %rdi
callq 0x3610
movq %rax, %r14
testl %r13d, %r13d
jle 0x36230
xorl %r13d, %r13d
movq 0x40(%rsp), %rbp
movq 0x20(%rsp), %rbx
movq %rbx, %rdi
callq 0x3360
leaq 0x14(%rax), %rdi
movl $0x1, %esi
callq 0x3610
movq %rax, (%r14,%r13,8)
movq %rax, %rdi
leaq 0xf484(%rip), %rsi      # 0x45647
movq %rbx, %rdx
movl %r13d, %ecx
movq %rbp, %r8
xorl %eax, %eax
callq 0x3400
incq %r13
cmpq %r13, 0x8(%rsp)
jne 0x3619f
subq $0x8, %rsp
movl 0x24(%rsp), %edi
movq 0x18(%rsp), %rsi
xorl %edx, %edx
movq 0x10(%rsp), %rbp
movl %ebp, %ecx
movq %r14, %r8
xorl %r9d, %r9d
pushq 0x40(%rsp)
pushq 0x38(%rsp)
pushq $0x0
callq 0x33f31
addq $0x20, %rsp
testl %ebp, %ebp
jle 0x3625a
xorl %ebx, %ebx
movq (%r14,%rbx,8), %r13
movq %r13, %rdi
callq 0x3250
movq %r13, %rdi
callq 0x3350
incq %rbx
cmpq %rbx, %rbp
jne 0x36212
jmp 0x3625a
subq $0x8, %rsp
movl 0x24(%rsp), %edi
movq 0x18(%rsp), %rsi
xorl %edx, %edx
movq 0x10(%rsp), %rcx
movq %r14, %r8
xorl %r9d, %r9d
pushq 0x40(%rsp)
pushq %rbx
pushq $0x0
callq 0x33f31
addq $0x20, %rsp
movq %r14, %rdi
callq 0x3350
movq 0x10(%rsp), %r13
jmp 0x36081