// File: /workspace/github_c_makefile_star2_O3/Tarsnap[P]kivaloo/kvlds/btree_balance.c
// Function: domergenode
static int
domergenode(struct balance_cookie * B, struct node * N)
{
	size_t nmerges, i, j;
	size_t nmerge;
	int failed = 0;		/* We haven't failed yet. */
	int merging;
	struct node * NC;

	/*
	 * As far as we know, we've done all possibly merges under this
	 * subtree.  (We'll adjust this later if necessary).
	 */
	N->needmerge = 0;

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

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

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

		/* If this child needs to be remerged, so do we. */
		if (N->v.children[i]->needmerge)
			N->needmerge = 1;
	}

	/* Count how many of our children will be merged. */
	for (nmerges = i = 0; i <= N->nkeys; i++) {
		if (N->v.children[i]->merging) {
			/* We have a merge required. */
			nmerges++;

			/* We might need to do a merge in the new child. */
			N->needmerge = 1;
		}
	}

	/* If we don't need to do any merges, we're done. */
	if (nmerges == 0)
		goto done;

	/* Iterate through the children, dirtying and unlocking them. */
	for (merging = 0, i = 0;
	    i <= N->nkeys;
	    merging = N->v.children[i]->merging, i++) {
		/*
		 * Grab a pointer to the node.  Note that if we dirty NC, it
		 * will no longer be the same as N->v.children[i].
		 */
		NC = N->v.children[i];

		/* If this node isn't being merged, move on. */
		if ((NC->merging == 0) && (merging == 0))
			continue;

		/* If this node isn't dirty, make it dirty. */
		if (NC->state != NODE_STATE_DIRTY) {
			if (btree_node_dirty(B->T, NC) == NULL)
				failed = 1;

			/* The dirty node is being merged, not the shadow. */
			N->v.children[i]->merging = NC->merging;
			NC->merging = 0;
		}

		/*
		 * Release the lock we picked up in planmergenode or which
		 * was picked up for us by btree_node_fetch.
		 */
		btree_node_unlock(B->T, NC);
	}

	/* If we failed to dirty a node, give up now. */
	if (failed)
		goto err0;

	/* Iterate through the children, merging them as necessary. */
	for (nmerge = 0, j = i = 0; i <= N->nkeys; i++) {
		/* If this node is being merged into the next, move on. */
		if (N->v.children[i]->merging) {
			nmerge++;
			continue;
		}

		/* If we're not merging, just copy the child and key. */
		if (nmerge == 0) {
			N->v.children[j] = N->v.children[i];
			if (i < N->nkeys)
				N->u.keys[j] = N->u.keys[i];
			j += 1;
			continue;
		}

		/* Merge children. */
		if (btree_node_merge(B->T,
		    &N->v.children[i - nmerge], &N->u.keys[i - nmerge],
		    &N->v.children[j], &N->u.keys[j], nmerge)) {
			j += nmerge;
			failed = 1;
		}

		/* Copy the separator key. */
		if (i < N->nkeys)
			N->u.keys[j] = N->u.keys[i];
		j += 1;

		/* We've merged this batch; start over. */
		nmerge = 0;
	}

	/* Store number of keys. */
	N->nkeys = j - 1;

	/* The size of this node has changed. */
	N->pagesize = (uint32_t)(-1);

	/* Did we fail? */
	if (failed)
		goto err0;

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

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

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
pushq %rax
movb 0x1c(%rsi), %al
movl %eax, %ecx
andb $-0x41, %cl
movb %cl, 0x1c(%rsi)
andb $0xf, %al
cmpb $0x8, %al
jne 0x6e6d
movq %rsi, %rbx
movq %rdi, %r14
movq 0x48(%rsi), %rcx
xorl %r15d, %r15d
movq (%rcx,%r15,8), %rsi
movq %r14, %rdi
callq 0x6c7d
testl %eax, %eax
jne 0x6e66
movq 0x48(%rbx), %rcx
movq (%rcx,%r15,8), %rax
testb $0x40, 0x1c(%rax)
je 0x6cd0
orb $0x40, 0x1c(%rbx)
incq %r15
movq 0x38(%rbx), %rax
cmpq %rax, %r15
jbe 0x6caa
incq %rax
xorl %edx, %edx
xorl %esi, %esi
movq (%rcx,%rdx,8), %rdi
testb $0x20, 0x1c(%rdi)
je 0x6cf4
incq %rsi
orb $0x40, 0x1c(%rbx)
incq %rdx
cmpq %rdx, %rax
jne 0x6ce3
testq %rsi, %rsi
je 0x6e6d
xorl %edx, %edx
movl $0x1, %ebp
xorl %r12d, %r12d
xorl %r13d, %r13d
movq (%rcx,%r13,8), %r15
movb 0x1c(%r15), %al
testb $0x20, %al
jne 0x6d22
testl %edx, %edx
je 0x6d85
andb $0xc, %al
movq 0x10(%r14), %rdi
cmpb $0x8, %al
je 0x6d5d
movq %r15, %rsi
callq 0x8f61
testq %rax, %rax
cmovel %ebp, %r12d
movb 0x1c(%r15), %al
andb $0x20, %al
movq 0x48(%rbx), %rcx
movq (%rcx,%r13,8), %rcx
movb 0x1c(%rcx), %dl
andb $-0x21, %dl
orb %al, %dl
movb %dl, 0x1c(%rcx)
andb $-0x21, 0x1c(%r15)
movq 0x10(%r14), %rdi
movq 0x30(%rdi), %rdi
movq 0x20(%rdi), %rax
movq (%r15,%rax), %rax
movq (%rax), %rcx
testq %rcx, %rcx
je 0x6e7e
decq %rcx
movq %rcx, (%rax)
jne 0x6d85
movq %r15, %rsi
callq 0x107ea
movq 0x38(%rbx), %rax
movq 0x48(%rbx), %rcx
movq (%rcx,%r13,8), %rdx
movl 0x1c(%rdx), %edx
shrl $0x5, %edx
andl $0x1, %edx
incq %r13
cmpq %rax, %r13
jbe 0x6d12
testl %r12d, %r12d
jne 0x6e66
xorl %r12d, %r12d
xorl %r15d, %r15d
xorl %ebp, %ebp
xorl %r13d, %r13d
movq 0x48(%rbx), %rcx
movq (%rcx,%r13,8), %rdx
testb $0x20, 0x1c(%rdx)
jne 0x6e27
testq %r15, %r15
je 0x6e2c
movq 0x10(%r14), %rdi
movq %r13, %rax
subq %r15, %rax
leaq (%rcx,%rax,8), %rsi
movq 0x40(%rbx), %r8
leaq (%r8,%rax,8), %rdx
leaq (%rcx,%rbp,8), %rcx
leaq (%r8,%rbp,8), %r8
movq %r15, %r9
callq 0x9d40
testl %eax, %eax
movl $0x0, %ecx
cmovneq %r15, %rcx
movl $0x1, %eax
cmovnel %eax, %r12d
addq %rbp, %rcx
movq 0x38(%rbx), %rax
cmpq %rax, %r13
jae 0x6e1f
movq 0x40(%rbx), %rdx
movq (%rdx,%r13,8), %rsi
movq %rsi, (%rdx,%rcx,8)
incq %rcx
movq %rcx, %rbp
jmp 0x6e44
incq %r15
jmp 0x6e47
movq %rdx, (%rcx,%rbp,8)
cmpq %rax, %r13
jae 0x6e41
movq 0x40(%rbx), %rcx
movq (%rcx,%r13,8), %rdx
movq %rdx, (%rcx,%rbp,8)
incq %rbp
xorl %r15d, %r15d
incq %r13
cmpq %rax, %r13
jbe 0x6dba
decq %rbp
movq %rbp, 0x38(%rbx)
movl $0xffffffff, 0x18(%rbx) # imm = 0xFFFFFFFF
testl %r12d, %r12d
je 0x6e6d
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
jmp 0x6e6f
xorl %eax, %eax
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0xd7cb(%rip), %rdi      # 0x14650
leaq 0xd7ea(%rip), %rsi      # 0x14676
leaq 0xd7fc(%rip), %rcx      # 0x1468f
movl $0x88, %edx
callq 0x21c0
nopl (%rax)