// File: /workspace/github_c_makefile_star2_O0/jsummers[P]deark/modules/hlp.c
// Function: do_bplustree
static void do_bplustree(deark *c, lctx *d, i64 pos1, i64 len,
	int is_internaldir)
{
	i64 pos = pos1;
	i64 n;
	int saved_indent_level;
	u8 *page_seen = NULL;
	struct de_stringreaderdata *structure = NULL;

	if(!is_internaldir) return;

	de_dbg_indent_save(c, &saved_indent_level);

	n = de_getu16le_p(&pos);
	if(n != 0x293b) {
		de_err(c, "Expected B+ tree structure at %"I64_FMT" not found", pos1);
		goto done;
	}

	//de_dbg(c, "B+ tree at %"I64_FMT, pos1);
	de_dbg_indent(c, 1);

	d->bpt.flags = (UI)de_getu16le_p(&pos);
	de_dbg(c, "Btree flags: 0x%04x", d->bpt.flags);

	d->bpt.pagesize = de_getu16le_p(&pos);
	de_dbg(c, "PageSize: %d", (int)d->bpt.pagesize);

	// TODO: Understand the Structure field
	structure = dbuf_read_string(c->infile, pos, 16, 16, DE_CONVFLAG_STOP_AT_NUL,
		DE_ENCODING_ASCII);
	de_dbg(c, "Structure: \"%s\"", ucstring_getpsz_d(structure->str));
	de_destroy_stringreaderdata(c, structure);
	structure = NULL;
	pos += 16;

	pos += 2; // MustBeZero
	pos += 2; // PageSplits

	d->bpt.root_page = de_geti16le_p(&pos);
	de_dbg(c, "RootPage: %d", (int)d->bpt.root_page);

	pos += 2; // MustBeNegOne

	d->bpt.num_pages = de_geti16le_p(&pos);
	de_dbg(c, "TotalPages: %d", (int)d->bpt.num_pages);

	d->bpt.num_levels = de_geti16le_p(&pos);
	de_dbg(c, "NLevels: %d", (int)d->bpt.num_levels);
	if(is_internaldir) d->internal_dir_num_levels = d->bpt.num_levels;

	d->bpt.num_entries = de_geti32le_p(&pos);
	de_dbg(c, "TotalBtreeEntries: %d", (int)d->bpt.num_entries);

	d->bpt.pagesdata_pos = pos;
	de_dbg(c, "num pages: %d, %d bytes each, at %"I64_FMT" (total size=%"I64_FMT")",
		(int)d->bpt.num_pages, (int)d->bpt.pagesize, d->bpt.pagesdata_pos,
		(i64)(d->bpt.num_pages * d->bpt.pagesize));

	if(!find_first_leaf_page(c, d)) goto done;

	page_seen = de_malloc(c, d->bpt.num_pages); // For loop detection

	for(d->pass=1; d->pass<=2; d->pass++) {
		i64 curr_page;

		de_zeromem(page_seen, (size_t)d->bpt.num_pages);

		de_dbg(c, "pass %d", d->pass);
		de_dbg_indent(c, 1);

		curr_page = d->bpt.first_leaf_page;

		while(1) {
			i64 page_pos;
			i64 next_page;

			if(curr_page<0) break;
			if(curr_page>d->bpt.num_pages) goto done;

			if(d->pass==1 && page_seen[curr_page]) {
				de_err(c, "Page loop detected");
				goto done;
			}
			page_seen[curr_page] = 1;

			page_pos = d->bpt.pagesdata_pos + curr_page*d->bpt.pagesize;

			de_dbg(c, "page[%d] at %"I64_FMT" (leaf page)", (int)curr_page, page_pos);

			next_page = -1;
			de_dbg_indent(c, 1);
			do_leaf_page(c, d, page_pos, &next_page);
			de_dbg_indent(c, -1);

			curr_page = next_page;
		}

		de_dbg_indent(c, -1);

		if(d->pass==1) {
			de_dbg(c, "reading items after pass 1");
			de_dbg_indent(c, 1);
			do_after_pass_1(c, d);
			de_dbg_indent(c, -1);
		}
	}

done:
	de_free(c, page_seen);
	if(structure) de_destroy_stringreaderdata(c, structure);
	de_dbg_indent_restore(c, saved_indent_level);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x70, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq %rcx, -0x20(%rbp)
movl %r8d, -0x24(%rbp)
movq -0x18(%rbp), %rax
movq %rax, -0x30(%rbp)
movq $0x0, -0x48(%rbp)
movq $0x0, -0x50(%rbp)
cmpl $0x0, -0x24(%rbp)
jne 0x7c7af
jmp 0x7cc59
movq -0x8(%rbp), %rdi
leaq -0x3c(%rbp), %rsi
callq 0x15b580
movq -0x8(%rbp), %rax
movq 0x18(%rax), %rdi
leaq -0x30(%rbp), %rsi
callq 0x1652c0
movq %rax, -0x38(%rbp)
cmpq $0x293b, -0x38(%rbp)    # imm = 0x293B
je 0x7c7f6
movq -0x8(%rbp), %rdi
movq -0x18(%rbp), %rdx
leaq 0x130629(%rip), %rsi    # 0x1ace13
movb $0x0, %al
callq 0x15bfb0
jmp 0x7cc2c
movq -0x8(%rbp), %rdi
movl $0x1, %esi
callq 0x15b560
movq -0x8(%rbp), %rax
movq 0x18(%rax), %rdi
leaq -0x30(%rbp), %rsi
callq 0x1652c0
movl %eax, %ecx
movq -0x10(%rbp), %rax
movl %ecx, 0x18(%rax)
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rax
movl 0x18(%rax), %edx
leaq 0x13060f(%rip), %rsi    # 0x1ace3f
movb $0x0, %al
callq 0x15b0d0
movq -0x8(%rbp), %rax
movq 0x18(%rax), %rdi
leaq -0x30(%rbp), %rsi
callq 0x1652c0
movq %rax, %rcx
movq -0x10(%rbp), %rax
movq %rcx, 0x20(%rax)
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rax
movq 0x20(%rax), %rax
movl %eax, %edx
leaq 0x1305eb(%rip), %rsi    # 0x1ace53
movb $0x0, %al
callq 0x15b0d0
movq -0x8(%rbp), %rax
movq 0x18(%rax), %rdi
movq -0x30(%rbp), %rsi
movl $0x10, %ecx
movl $0x1, %r9d
movq %rcx, %rdx
movl %r9d, %r8d
callq 0x1664c0
movq %rax, -0x50(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x70(%rbp)
movq -0x50(%rbp), %rax
movq 0x18(%rax), %rdi
callq 0x172650
movq -0x70(%rbp), %rdi
movq %rax, %rdx
leaq 0x1305a8(%rip), %rsi    # 0x1ace60
movb $0x0, %al
callq 0x15b0d0
movq -0x8(%rbp), %rdi
movq -0x50(%rbp), %rsi
callq 0x166830
movq $0x0, -0x50(%rbp)
movq -0x30(%rbp), %rax
addq $0x10, %rax
movq %rax, -0x30(%rbp)
movq -0x30(%rbp), %rax
addq $0x2, %rax
movq %rax, -0x30(%rbp)
movq -0x30(%rbp), %rax
addq $0x2, %rax
movq %rax, -0x30(%rbp)
movq -0x8(%rbp), %rax
movq 0x18(%rax), %rdi
leaq -0x30(%rbp), %rsi
callq 0x1653f0
movq %rax, %rcx
movq -0x10(%rbp), %rax
movq %rcx, 0x28(%rax)
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rax
movq 0x28(%rax), %rax
movl %eax, %edx
leaq 0x130547(%rip), %rsi    # 0x1ace70
movb $0x0, %al
callq 0x15b0d0
movq -0x30(%rbp), %rax
addq $0x2, %rax
movq %rax, -0x30(%rbp)
movq -0x8(%rbp), %rax
movq 0x18(%rax), %rdi
leaq -0x30(%rbp), %rsi
callq 0x1653f0
movq %rax, %rcx
movq -0x10(%rbp), %rax
movq %rcx, 0x38(%rax)
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rax
movq 0x38(%rax), %rax
movl %eax, %edx
leaq 0x130510(%rip), %rsi    # 0x1ace7d
movb $0x0, %al
callq 0x15b0d0
movq -0x8(%rbp), %rax
movq 0x18(%rax), %rdi
leaq -0x30(%rbp), %rsi
callq 0x1653f0
movq %rax, %rcx
movq -0x10(%rbp), %rax
movq %rcx, 0x30(%rax)
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rax
movq 0x30(%rax), %rax
movl %eax, %edx
leaq 0x1304e7(%rip), %rsi    # 0x1ace8c
movb $0x0, %al
callq 0x15b0d0
cmpl $0x0, -0x24(%rbp)
je 0x7c9c5
movq -0x10(%rbp), %rax
movq 0x30(%rax), %rcx
movq -0x10(%rbp), %rax
movq %rcx, 0xb8(%rax)
movq -0x8(%rbp), %rax
movq 0x18(%rax), %rdi
leaq -0x30(%rbp), %rsi
callq 0x165670
movq %rax, %rcx
movq -0x10(%rbp), %rax
movq %rcx, 0x40(%rax)
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rax
movq 0x40(%rax), %rax
movl %eax, %edx
leaq 0x1304a2(%rip), %rsi    # 0x1ace98
movb $0x0, %al
callq 0x15b0d0
movq -0x30(%rbp), %rcx
movq -0x10(%rbp), %rax
movq %rcx, 0x48(%rax)
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rax
movq 0x38(%rax), %rax
movl %eax, %edx
movq -0x10(%rbp), %rax
movq 0x20(%rax), %rax
movl %eax, %ecx
movq -0x10(%rbp), %rax
movq 0x48(%rax), %r8
movq -0x10(%rbp), %rax
movq 0x38(%rax), %r9
movq -0x10(%rbp), %rax
imulq 0x20(%rax), %r9
leaq 0x13046d(%rip), %rsi    # 0x1aceae
movb $0x0, %al
callq 0x15b0d0
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
callq 0x7cc60
cmpl $0x0, %eax
jne 0x7ca5f
jmp 0x7cc2c
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rax
movq 0x38(%rax), %rsi
callq 0x15b780
movq %rax, -0x48(%rbp)
movq -0x10(%rbp), %rax
movl $0x1, 0xa4(%rax)
movq -0x10(%rbp), %rax
cmpl $0x2, 0xa4(%rax)
jg 0x7cc2a
movq -0x48(%rbp), %rdi
movq -0x10(%rbp), %rax
movq 0x38(%rax), %rdx
xorl %esi, %esi
callq 0x19140
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rax
movl 0xa4(%rax), %edx
leaq 0x130085(%rip), %rsi    # 0x1acb40
movb $0x0, %al
callq 0x15b0d0
movq -0x8(%rbp), %rdi
movl $0x1, %esi
callq 0x15b560
movq -0x10(%rbp), %rax
movq 0x50(%rax), %rax
movq %rax, -0x58(%rbp)
cmpq $0x0, -0x58(%rbp)
jge 0x7cae8
jmp 0x7cbba
movq -0x58(%rbp), %rax
movq -0x10(%rbp), %rcx
cmpq 0x38(%rcx), %rax
jle 0x7cafb
jmp 0x7cc2c
movq -0x10(%rbp), %rax
cmpl $0x1, 0xa4(%rax)
jne 0x7cb30
movq -0x48(%rbp), %rax
movq -0x58(%rbp), %rcx
movzbl (%rax,%rcx), %eax
cmpl $0x0, %eax
je 0x7cb30
movq -0x8(%rbp), %rdi
leaq 0x1303c0(%rip), %rsi    # 0x1acee4
movb $0x0, %al
callq 0x15bfb0
jmp 0x7cc2c
movq -0x48(%rbp), %rax
movq -0x58(%rbp), %rcx
movb $0x1, (%rax,%rcx)
movq -0x10(%rbp), %rax
movq 0x48(%rax), %rax
movq -0x58(%rbp), %rcx
movq -0x10(%rbp), %rdx
imulq 0x20(%rdx), %rcx
addq %rcx, %rax
movq %rax, -0x60(%rbp)
movq -0x8(%rbp), %rdi
movq -0x58(%rbp), %rax
movl %eax, %edx
movq -0x60(%rbp), %rcx
leaq 0x13038a(%rip), %rsi    # 0x1acef7
movb $0x0, %al
callq 0x15b0d0
movq $-0x1, -0x68(%rbp)
movq -0x8(%rbp), %rdi
movl $0x1, %esi
callq 0x15b560
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
movq -0x60(%rbp), %rdx
leaq -0x68(%rbp), %rcx
callq 0x7cda0
movq -0x8(%rbp), %rdi
movl $0xffffffff, %esi       # imm = 0xFFFFFFFF
callq 0x15b560
movq -0x68(%rbp), %rax
movq %rax, -0x58(%rbp)
jmp 0x7cadc
movq -0x8(%rbp), %rdi
movl $0xffffffff, %esi       # imm = 0xFFFFFFFF
callq 0x15b560
movq -0x10(%rbp), %rax
cmpl $0x1, 0xa4(%rax)
jne 0x7cc10
movq -0x8(%rbp), %rdi
leaq 0x130333(%rip), %rsi    # 0x1acf13
movb $0x0, %al
callq 0x15b0d0
movq -0x8(%rbp), %rdi
movl $0x1, %esi
callq 0x15b560
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
callq 0x7d150
movq -0x8(%rbp), %rdi
movl $0xffffffff, %esi       # imm = 0xFFFFFFFF
callq 0x15b560
jmp 0x7cc12
movq -0x10(%rbp), %rax
movl 0xa4(%rax), %ecx
addl $0x1, %ecx
movl %ecx, 0xa4(%rax)
jmp 0x7ca82
jmp 0x7cc2c
movq -0x8(%rbp), %rdi
movq -0x48(%rbp), %rsi
callq 0x15b820
cmpq $0x0, -0x50(%rbp)
je 0x7cc4d
movq -0x8(%rbp), %rdi
movq -0x50(%rbp), %rsi
callq 0x166830
movq -0x8(%rbp), %rdi
movl -0x3c(%rbp), %esi
callq 0x15b5a0
addq $0x70, %rsp
popq %rbp
retq
nop