// File: jvanns[P]verbatim/sub/lmdb/libraries/liblmdb/mdb.c
// Function: mdb_page_merge
static int
mdb_page_merge(MDB_cursor *csrc, MDB_cursor *cdst)
{
	MDB_page	*psrc, *pdst;
	MDB_node	*srcnode;
	MDB_val		 key, data;
	unsigned	 nkeys;
	int			 rc;
	indx_t		 i, j;

	psrc = csrc->mc_pg[csrc->mc_top];
	pdst = cdst->mc_pg[cdst->mc_top];

	DPRINTF(("merging page %"Z"u into %"Z"u", psrc->mp_pgno, pdst->mp_pgno));

	mdb_cassert(csrc, csrc->mc_snum > 1);	/* can't merge root page */
	mdb_cassert(csrc, cdst->mc_snum > 1);

	/* Mark dst as dirty. */
	if ((rc = mdb_page_touch(cdst)))
		return rc;

	/* Move all nodes from src to dst.
	 */
	j = nkeys = NUMKEYS(pdst);
	if (IS_LEAF2(psrc)) {
		key.mv_size = csrc->mc_db->md_pad;
		key.mv_data = METADATA(psrc);
		for (i = 0; i < NUMKEYS(psrc); i++, j++) {
			rc = mdb_node_add(cdst, j, &key, NULL, 0, 0);
			if (rc != MDB_SUCCESS)
				return rc;
			key.mv_data = (char *)key.mv_data + key.mv_size;
		}
	} else {
		for (i = 0; i < NUMKEYS(psrc); i++, j++) {
			srcnode = NODEPTR(psrc, i);
			if (i == 0 && IS_BRANCH(psrc)) {
				MDB_cursor mn;
				MDB_node *s2;
				mdb_cursor_copy(csrc, &mn);
				/* must find the lowest key below src */
				rc = mdb_page_search_lowest(&mn);
				if (rc)
					return rc;
				if (IS_LEAF2(mn.mc_pg[mn.mc_top])) {
					key.mv_size = mn.mc_db->md_pad;
					key.mv_data = LEAF2KEY(mn.mc_pg[mn.mc_top], 0, key.mv_size);
				} else {
					s2 = NODEPTR(mn.mc_pg[mn.mc_top], 0);
					key.mv_size = NODEKSZ(s2);
					key.mv_data = NODEKEY(s2);
				}
			} else {
				key.mv_size = srcnode->mn_ksize;
				key.mv_data = NODEKEY(srcnode);
			}

			data.mv_size = NODEDSZ(srcnode);
			data.mv_data = NODEDATA(srcnode);
			rc = mdb_node_add(cdst, j, &key, &data, NODEPGNO(srcnode), srcnode->mn_flags);
			if (rc != MDB_SUCCESS)
				return rc;
		}
	}

	DPRINTF(("dst page %"Z"u now has %u keys (%.1f%% filled)",
	    pdst->mp_pgno, NUMKEYS(pdst),
		(float)PAGEFILL(cdst->mc_txn->mt_env, pdst) / 10));

	/* Unlink the src page from parent and add to free list.
	 */
	csrc->mc_top--;
	mdb_node_del(csrc, 0);
	if (csrc->mc_ki[csrc->mc_top] == 0) {
		key.mv_size = 0;
		rc = mdb_update_key(csrc, &key);
		if (rc) {
			csrc->mc_top++;
			return rc;
		}
	}
	csrc->mc_top++;

	psrc = csrc->mc_pg[csrc->mc_top];
	/* If not operating on FreeDB, allow this page to be reused
	 * in this txn. Otherwise just add to free list.
	 */
	rc = mdb_page_loose(csrc, psrc);
	if (rc)
		return rc;
	if (IS_LEAF(psrc))
		csrc->mc_db->md_leaf_pages--;
	else
		csrc->mc_db->md_branch_pages--;
	{
		/* Adjust other cursors pointing to mp */
		MDB_cursor *m2, *m3;
		MDB_dbi dbi = csrc->mc_dbi;

		for (m2 = csrc->mc_txn->mt_cursors[dbi]; m2; m2=m2->mc_next) {
			if (csrc->mc_flags & C_SUB)
				m3 = &m2->mc_xcursor->mx_cursor;
			else
				m3 = m2;
			if (m3 == csrc) continue;
			if (m3->mc_snum < csrc->mc_snum) continue;
			if (m3->mc_pg[csrc->mc_top] == psrc) {
				m3->mc_pg[csrc->mc_top] = pdst;
				m3->mc_ki[csrc->mc_top] += nkeys;
			}
		}
	}
	{
		unsigned int snum = cdst->mc_snum;
		uint16_t depth = cdst->mc_db->md_depth;
		mdb_cursor_pop(cdst);
		rc = mdb_rebalance(cdst);
		/* Did the tree shrink? */
		if (depth > cdst->mc_db->md_depth)
			snum--;
		cdst->mc_snum = snum;
		cdst->mc_top = snum-1;
	}
	return rc;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x210, %rsp            # imm = 0x210
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movq -0x10(%rbp), %rax
movq -0x10(%rbp), %rcx
movzwl 0x42(%rcx), %ecx
movq 0x48(%rax,%rcx,8), %rax
movq %rax, -0x20(%rbp)
movq -0x18(%rbp), %rax
movq -0x18(%rbp), %rcx
movzwl 0x42(%rcx), %ecx
movq 0x48(%rax,%rcx,8), %rax
movq %rax, -0x28(%rbp)
movq -0x10(%rbp), %rax
movzwl 0x40(%rax), %eax
cmpl $0x1, %eax
jle 0x11bec
jmp 0x11c18
movq -0x10(%rbp), %rax
movq 0x18(%rax), %rax
movq 0x20(%rax), %rdi
leaq 0x603f(%rip), %rsi      # 0x17c3e
leaq 0x604a(%rip), %rdx      # 0x17c50
leaq 0x5802(%rip), %rcx      # 0x1740f
movl $0x1e3f, %r8d           # imm = 0x1E3F
callq 0x133a0
movq -0x18(%rbp), %rax
movzwl 0x40(%rax), %eax
cmpl $0x1, %eax
jle 0x11c27
jmp 0x11c53
movq -0x10(%rbp), %rax
movq 0x18(%rax), %rax
movq 0x20(%rax), %rdi
leaq 0x6025(%rip), %rsi      # 0x17c5f
leaq 0x600f(%rip), %rdx      # 0x17c50
leaq 0x57c7(%rip), %rcx      # 0x1740f
movl $0x1e40, %r8d           # imm = 0x1E40
callq 0x133a0
movq -0x18(%rbp), %rdi
callq 0xf430
movl %eax, -0x58(%rbp)
cmpl $0x0, %eax
je 0x11c6f
movl -0x58(%rbp), %eax
movl %eax, -0x4(%rbp)
jmp 0x12189
movq -0x28(%rbp), %rax
movzwl 0xc(%rax), %eax
subl $0x10, %eax
shrl %eax
movl %eax, -0x54(%rbp)
movw %ax, -0x5c(%rbp)
movq -0x20(%rbp), %rax
movzwl 0xa(%rax), %eax
andl $0x20, %eax
cmpl $0x20, %eax
jne 0x11d27
movq -0x10(%rbp), %rax
movq 0x28(%rax), %rax
movl (%rax), %eax
movq %rax, -0x40(%rbp)
movq -0x20(%rbp), %rax
addq $0x10, %rax
movq %rax, -0x38(%rbp)
movw $0x0, -0x5a(%rbp)
movzwl -0x5a(%rbp), %eax
movq -0x20(%rbp), %rcx
movzwl 0xc(%rcx), %ecx
subl $0x10, %ecx
shrl %ecx
cmpl %ecx, %eax
jae 0x11d22
movq -0x18(%rbp), %rdi
leaq -0x40(%rbp), %rdx
xorl %eax, %eax
movl %eax, %r8d
xorl %r9d, %r9d
movzwl -0x5c(%rbp), %esi
movq %r8, %rcx
callq 0xc5d0
movl %eax, -0x58(%rbp)
cmpl $0x0, -0x58(%rbp)
je 0x11cfc
movl -0x58(%rbp), %eax
movl %eax, -0x4(%rbp)
jmp 0x12189
movq -0x38(%rbp), %rax
addq -0x40(%rbp), %rax
movq %rax, -0x38(%rbp)
movw -0x5a(%rbp), %ax
addw $0x1, %ax
movw %ax, -0x5a(%rbp)
movw -0x5c(%rbp), %ax
addw $0x1, %ax
movw %ax, -0x5c(%rbp)
jmp 0x11cb7
jmp 0x11f14
movw $0x0, -0x5a(%rbp)
movzwl -0x5a(%rbp), %eax
movq -0x20(%rbp), %rcx
movzwl 0xc(%rcx), %ecx
subl $0x10, %ecx
shrl %ecx
cmpl %ecx, %eax
jae 0x11f12
movq -0x20(%rbp), %rax
movq -0x20(%rbp), %rcx
movzwl -0x5a(%rbp), %edx
movzwl 0x10(%rcx,%rdx,2), %ecx
movslq %ecx, %rcx
addq %rcx, %rax
movq %rax, -0x30(%rbp)
movzwl -0x5a(%rbp), %eax
cmpl $0x0, %eax
jne 0x11e4a
movq -0x20(%rbp), %rax
movzwl 0xa(%rax), %eax
andl $0x1, %eax
cmpl $0x1, %eax
jne 0x11e4a
movq -0x10(%rbp), %rdi
leaq -0x1e8(%rbp), %rsi
callq 0x11080
leaq -0x1e8(%rbp), %rdi
callq 0x121a0
movl %eax, -0x58(%rbp)
cmpl $0x0, -0x58(%rbp)
je 0x11db2
movl -0x58(%rbp), %eax
movl %eax, -0x4(%rbp)
jmp 0x12189
movzwl -0x1a6(%rbp), %eax
movq -0x1a0(%rbp,%rax,8), %rax
movzwl 0xa(%rax), %eax
andl $0x20, %eax
cmpl $0x20, %eax
jne 0x11dfb
movq -0x1c0(%rbp), %rax
movl (%rax), %eax
movq %rax, -0x40(%rbp)
movzwl -0x1a6(%rbp), %eax
movq -0x1a0(%rbp,%rax,8), %rax
addq $0x10, %rax
imulq $0x0, -0x40(%rbp), %rcx
addq %rcx, %rax
movq %rax, -0x38(%rbp)
jmp 0x11e48
movzwl -0x1a6(%rbp), %eax
movq -0x1a0(%rbp,%rax,8), %rax
movzwl -0x1a6(%rbp), %ecx
movq -0x1a0(%rbp,%rcx,8), %rcx
movzwl 0x10(%rcx), %ecx
movslq %ecx, %rcx
addq %rcx, %rax
movq %rax, -0x1f0(%rbp)
movq -0x1f0(%rbp), %rax
movzwl 0x6(%rax), %eax
movq %rax, -0x40(%rbp)
movq -0x1f0(%rbp), %rax
addq $0x8, %rax
movq %rax, -0x38(%rbp)
jmp 0x11e62
movq -0x30(%rbp), %rax
movzwl 0x6(%rax), %eax
movq %rax, -0x40(%rbp)
movq -0x30(%rbp), %rax
addq $0x8, %rax
movq %rax, -0x38(%rbp)
movq -0x30(%rbp), %rax
movzwl (%rax), %eax
movq -0x30(%rbp), %rcx
movzwl 0x2(%rcx), %ecx
shll $0x10, %ecx
orl %ecx, %eax
movl %eax, %eax
movq %rax, -0x50(%rbp)
movq -0x30(%rbp), %rax
addq $0x8, %rax
movq -0x30(%rbp), %rcx
movzwl 0x6(%rcx), %ecx
movslq %ecx, %rcx
addq %rcx, %rax
movq %rax, -0x48(%rbp)
movq -0x18(%rbp), %rdi
movw -0x5c(%rbp), %ax
movq -0x30(%rbp), %rcx
movzwl (%rcx), %ecx
movl %ecx, %r8d
movq -0x30(%rbp), %rcx
movzwl 0x2(%rcx), %ecx
shlq $0x10, %rcx
orq %rcx, %r8
movq -0x30(%rbp), %rcx
movzwl 0x4(%rcx), %ecx
shlq $0x20, %rcx
orq %rcx, %r8
movq -0x30(%rbp), %rcx
movzwl 0x4(%rcx), %r9d
leaq -0x40(%rbp), %rdx
leaq -0x50(%rbp), %rcx
movzwl %ax, %esi
callq 0xc5d0
movl %eax, -0x58(%rbp)
cmpl $0x0, -0x58(%rbp)
je 0x11ef3
movl -0x58(%rbp), %eax
movl %eax, -0x4(%rbp)
jmp 0x12189
jmp 0x11ef5
movw -0x5a(%rbp), %ax
addw $0x1, %ax
movw %ax, -0x5a(%rbp)
movw -0x5c(%rbp), %ax
addw $0x1, %ax
movw %ax, -0x5c(%rbp)
jmp 0x11d2d
jmp 0x11f14
movq -0x10(%rbp), %rax
movw 0x42(%rax), %cx
addw $-0x1, %cx
movw %cx, 0x42(%rax)
movq -0x10(%rbp), %rdi
xorl %esi, %esi
callq 0xa4b0
movq -0x10(%rbp), %rax
movq -0x10(%rbp), %rcx
movzwl 0x42(%rcx), %ecx
movzwl 0x148(%rax,%rcx,2), %eax
cmpl $0x0, %eax
jne 0x11f83
movq $0x0, -0x40(%rbp)
movq -0x10(%rbp), %rdi
leaq -0x40(%rbp), %rsi
callq 0x9d50
movl %eax, -0x58(%rbp)
cmpl $0x0, -0x58(%rbp)
je 0x11f81
movq -0x10(%rbp), %rax
movw 0x42(%rax), %cx
addw $0x1, %cx
movw %cx, 0x42(%rax)
movl -0x58(%rbp), %eax
movl %eax, -0x4(%rbp)
jmp 0x12189
jmp 0x11f83
movq -0x10(%rbp), %rax
movw 0x42(%rax), %cx
addw $0x1, %cx
movw %cx, 0x42(%rax)
movq -0x10(%rbp), %rax
movq -0x10(%rbp), %rcx
movzwl 0x42(%rcx), %ecx
movq 0x48(%rax,%rcx,8), %rax
movq %rax, -0x20(%rbp)
movq -0x10(%rbp), %rdi
movq -0x20(%rbp), %rsi
callq 0x12280
movl %eax, -0x58(%rbp)
cmpl $0x0, -0x58(%rbp)
je 0x11fc9
movl -0x58(%rbp), %eax
movl %eax, -0x4(%rbp)
jmp 0x12189
movq -0x20(%rbp), %rax
movzwl 0xa(%rax), %eax
andl $0x2, %eax
cmpl $0x2, %eax
jne 0x11fef
movq -0x10(%rbp), %rax
movq 0x28(%rax), %rax
movq 0x10(%rax), %rcx
addq $-0x1, %rcx
movq %rcx, 0x10(%rax)
jmp 0x12003
movq -0x10(%rbp), %rax
movq 0x28(%rax), %rax
movq 0x8(%rax), %rcx
addq $-0x1, %rcx
movq %rcx, 0x8(%rax)
movq -0x10(%rbp), %rax
movl 0x20(%rax), %eax
movl %eax, -0x204(%rbp)
movq -0x10(%rbp), %rax
movq 0x18(%rax), %rax
movq 0x68(%rax), %rax
movl -0x204(%rbp), %ecx
movq (%rax,%rcx,8), %rax
movq %rax, -0x1f8(%rbp)
cmpq $0x0, -0x1f8(%rbp)
je 0x12102
movq -0x10(%rbp), %rax
movl 0x44(%rax), %eax
andl $0x4, %eax
cmpl $0x0, %eax
je 0x1205e
movq -0x1f8(%rbp), %rax
movq 0x10(%rax), %rax
movq %rax, -0x200(%rbp)
jmp 0x1206c
movq -0x1f8(%rbp), %rax
movq %rax, -0x200(%rbp)
movq -0x200(%rbp), %rax
cmpq -0x10(%rbp), %rax
jne 0x1207b
jmp 0x120ec
movq -0x200(%rbp), %rax
movzwl 0x40(%rax), %eax
movq -0x10(%rbp), %rcx
movzwl 0x40(%rcx), %ecx
cmpl %ecx, %eax
jge 0x12094
jmp 0x120ec
movq -0x200(%rbp), %rax
movq -0x10(%rbp), %rcx
movzwl 0x42(%rcx), %ecx
movq 0x48(%rax,%rcx,8), %rax
cmpq -0x20(%rbp), %rax
jne 0x120ea
movq -0x28(%rbp), %rdx
movq -0x200(%rbp), %rax
movq -0x10(%rbp), %rcx
movzwl 0x42(%rcx), %ecx
movq %rdx, 0x48(%rax,%rcx,8)
movl -0x54(%rbp), %esi
movq -0x200(%rbp), %rax
movq -0x10(%rbp), %rcx
movzwl 0x42(%rcx), %ecx
movzwl 0x148(%rax,%rcx,2), %edx
addl %esi, %edx
movw %dx, 0x148(%rax,%rcx,2)
jmp 0x120ec
movq -0x1f8(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x1f8(%rbp)
jmp 0x1202d
movq -0x18(%rbp), %rax
movzwl 0x40(%rax), %eax
movl %eax, -0x208(%rbp)
movq -0x18(%rbp), %rax
movq 0x28(%rax), %rax
movw 0x6(%rax), %ax
movw %ax, -0x20a(%rbp)
movq -0x18(%rbp), %rdi
callq 0x10080
movq -0x18(%rbp), %rdi
callq 0x10590
movl %eax, -0x58(%rbp)
movzwl -0x20a(%rbp), %eax
movq -0x18(%rbp), %rcx
movq 0x28(%rcx), %rcx
movzwl 0x6(%rcx), %ecx
cmpl %ecx, %eax
jle 0x1215e
movl -0x208(%rbp), %eax
addl $-0x1, %eax
movl %eax, -0x208(%rbp)
movl -0x208(%rbp), %eax
movw %ax, %cx
movq -0x18(%rbp), %rax
movw %cx, 0x40(%rax)
movl -0x208(%rbp), %eax
subl $0x1, %eax
movw %ax, %cx
movq -0x18(%rbp), %rax
movw %cx, 0x42(%rax)
movl -0x58(%rbp), %eax
movl %eax, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0x210, %rsp            # imm = 0x210
popq %rbp
retq
nopw %cs:(%rax,%rax)