// File: /workspace/github_c_makefile_star2_O0/Tarsnap[P]kivaloo/kvlds/btree_balance.c
// Function: planmergenode
static int
planmergenode(struct balance_cookie * B, struct node * N)
{
	size_t maxplen = (B->T->pagelen * 2) / 3;
	size_t i;
	size_t plen;
	int gotdirty;
	int leafchild;
	int merging;

	/* If this node has no children, do nothing. */
	if (N->type != NODE_TYPE_PARENT)
		goto done;

	/* If this node is not dirty, it doesn't need splitting. */
	if (N->state != NODE_STATE_DIRTY)
		goto done;

	/* Plan merges under our children first. */
	for (i = 0; i <= N->nkeys; i++) {
		if (planmergenode(B, N->v.children[i]))
			goto err0;
	}

	/* Scan this node to see if we can merge any of its children. */
	/*
	 * Child number N->nkeys can't be merged into a higher-numbered child
	 * so we jump directly to nomerge.  This could be done using an
	 * "are we on the first pass through the loop" test inside the loop,
	 * but this confuses gcc.
	 */
	i = N->nkeys;
	goto nomerge;
	for (/* i = N->nkeys; */; i <= N->nkeys; i--) {
		/* Have we seen a dirty node yet? */
		if (N->v.children[i]->state == NODE_STATE_DIRTY) {
			gotdirty = 1;
			leafchild = (N->v.children[i]->type == NODE_TYPE_LEAF);
		}

		/*
		 * If we haven't seen a dirty node, we can't possibly need to
		 * merge this into the previous node.
		 */
		if (!gotdirty)
			goto nomerge;

		/*
		 * Figure out how large a node we'll produce if we merge this
		 * node into the next one.
		 */
		if (!leafchild)
			plen += kvldskey_serial_size(N->u.keys[i]);
		plen += serialize_merge_size(N->v.children[i]);

		/* Would the resulting node be too big? */
		if (plen > maxplen)
			goto nomerge;

		/* Mark this node as requiring merging. */
		N->v.children[i]->merging = 1;

		/* Move on to considering the next child. */
		continue;

nomerge:
		/*
		 * We're not merging this node into the next one.  Reset the
		 * state we're tracking so we can check if other nodes should
		 * be merged into this one.
		 */
		plen = serialize_size(N->v.children[i]);
		gotdirty = (N->v.children[i]->state == NODE_STATE_DIRTY);
		leafchild = (N->v.children[i]->type == NODE_TYPE_LEAF);
	}

	/* Page in any nodes which are needed for merging. */
	for (merging = i = 0; i <= N->nkeys; i++) {
		/* Do we need this node? */
		if (merging || N->v.children[i]->merging) {
			/* Is it present? */
			if (node_present(N->v.children[i])) {
				/* Make sure it stays present. */
				btree_node_lock(B->T, N->v.children[i]);
			} else {
				/* Fetch it. */
				B->nmergefetch += 1;
				if (btree_node_fetch(B->T, N->v.children[i],
				    merge_fetch, B))
					goto err0;
			}
		}

		/* Are we in the middle of a merging range? */
		merging = N->v.children[i]->merging;
	}

done:
	/* Success! */
	return (0);

err0:
	/* Failure! */
	return (-1);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x40, %rsp
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movq -0x10(%rbp), %rax
movq 0x10(%rax), %rax
movq (%rax), %rax
shlq %rax
movl $0x3, %ecx
xorl %edx, %edx
divq %rcx
movq %rax, -0x20(%rbp)
movq -0x18(%rbp), %rax
movb 0x1c(%rax), %al
andb $0x3, %al
movzbl %al, %eax
cmpl $0x0, %eax
je 0x8812
jmp 0x8ac5
movq -0x18(%rbp), %rax
movb 0x1c(%rax), %al
shrb $0x2, %al
andb $0x3, %al
movzbl %al, %eax
cmpl $0x2, %eax
je 0x882b
jmp 0x8ac5
movq $0x0, -0x28(%rbp)
movq -0x28(%rbp), %rax
movq -0x18(%rbp), %rcx
cmpq 0x38(%rcx), %rax
ja 0x8874
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rax
movq 0x48(%rax), %rax
movq -0x28(%rbp), %rcx
movq (%rax,%rcx,8), %rsi
callq 0x87d0
cmpl $0x0, %eax
je 0x8864
jmp 0x8ace
jmp 0x8866
movq -0x28(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x28(%rbp)
jmp 0x8833
movq -0x18(%rbp), %rax
movq 0x38(%rax), %rax
movq %rax, -0x28(%rbp)
jmp 0x8958
movq -0x28(%rbp), %rax
movq -0x18(%rbp), %rcx
cmpq 0x38(%rcx), %rax
ja 0x89d1
movq -0x18(%rbp), %rax
movq 0x48(%rax), %rax
movq -0x28(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movb 0x1c(%rax), %al
shrb $0x2, %al
andb $0x3, %al
movzbl %al, %eax
cmpl $0x2, %eax
jne 0x88e4
movl $0x1, -0x34(%rbp)
movq -0x18(%rbp), %rax
movq 0x48(%rax), %rax
movq -0x28(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movb 0x1c(%rax), %al
andb $0x3, %al
movzbl %al, %eax
cmpl $0x1, %eax
sete %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, -0x38(%rbp)
cmpl $0x0, -0x34(%rbp)
jne 0x88ec
jmp 0x8958
cmpl $0x0, -0x38(%rbp)
jne 0x8911
movq -0x18(%rbp), %rax
movq 0x40(%rax), %rax
movq -0x28(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movzbl (%rax), %eax
addq $0x1, %rax
addq -0x30(%rbp), %rax
movq %rax, -0x30(%rbp)
movq -0x18(%rbp), %rax
movq 0x48(%rax), %rax
movq -0x28(%rbp), %rcx
movq (%rax,%rcx,8), %rdi
callq 0xfa20
addq -0x30(%rbp), %rax
movq %rax, -0x30(%rbp)
movq -0x30(%rbp), %rax
cmpq -0x20(%rbp), %rax
jbe 0x893a
jmp 0x8958
movq -0x18(%rbp), %rax
movq 0x48(%rax), %rax
movq -0x28(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movb 0x1c(%rax), %cl
andb $-0x21, %cl
orb $0x20, %cl
movb %cl, 0x1c(%rax)
jmp 0x89c0
movq -0x18(%rbp), %rax
movq 0x48(%rax), %rax
movq -0x28(%rbp), %rcx
movq (%rax,%rcx,8), %rdi
callq 0xecb0
movq %rax, -0x30(%rbp)
movq -0x18(%rbp), %rax
movq 0x48(%rax), %rax
movq -0x28(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movb 0x1c(%rax), %al
shrb $0x2, %al
andb $0x3, %al
movzbl %al, %eax
cmpl $0x2, %eax
sete %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, -0x34(%rbp)
movq -0x18(%rbp), %rax
movq 0x48(%rax), %rax
movq -0x28(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movb 0x1c(%rax), %al
andb $0x3, %al
movzbl %al, %eax
cmpl $0x1, %eax
sete %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, -0x38(%rbp)
movq -0x28(%rbp), %rax
addq $-0x1, %rax
movq %rax, -0x28(%rbp)
jmp 0x8885
movq $0x0, -0x28(%rbp)
movl $0x0, -0x3c(%rbp)
movq -0x28(%rbp), %rax
movq -0x18(%rbp), %rcx
cmpq 0x38(%rcx), %rax
ja 0x8ac3
cmpl $0x0, -0x3c(%rbp)
jne 0x8a18
movq -0x18(%rbp), %rax
movq 0x48(%rax), %rax
movq -0x28(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movb 0x1c(%rax), %al
shrb $0x5, %al
andb $0x1, %al
movzbl %al, %eax
cmpl $0x0, %eax
je 0x8a94
movq -0x18(%rbp), %rax
movq 0x48(%rax), %rax
movq -0x28(%rbp), %rcx
movq (%rax,%rcx,8), %rdi
callq 0x8570
cmpl $0x0, %eax
je 0x8a51
movq -0x10(%rbp), %rax
movq 0x10(%rax), %rdi
movq -0x18(%rbp), %rax
movq 0x48(%rax), %rax
movq -0x28(%rbp), %rcx
movq (%rax,%rcx,8), %rsi
callq 0x8650
jmp 0x8a92
movq -0x10(%rbp), %rax
movq 0x18(%rax), %rcx
addq $0x1, %rcx
movq %rcx, 0x18(%rax)
movq -0x10(%rbp), %rax
movq 0x10(%rax), %rdi
movq -0x18(%rbp), %rax
movq 0x48(%rax), %rax
movq -0x28(%rbp), %rcx
movq (%rax,%rcx,8), %rsi
movq -0x10(%rbp), %rcx
leaq 0x13c(%rip), %rdx       # 0x8bc0
callq 0xc060
cmpl $0x0, %eax
je 0x8a90
jmp 0x8ace
jmp 0x8a92
jmp 0x8a94
movq -0x18(%rbp), %rax
movq 0x48(%rax), %rax
movq -0x28(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movb 0x1c(%rax), %al
shrb $0x5, %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, -0x3c(%rbp)
movq -0x28(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x28(%rbp)
jmp 0x89e0
jmp 0x8ac5
movl $0x0, -0x4(%rbp)
jmp 0x8ad5
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
movl -0x4(%rbp), %eax
addq $0x40, %rsp
popq %rbp
retq
nop