// File: /workspace/github_cpp_makefile_star2_O2/jvanns[P]verbatim/sub/lmdb/libraries/liblmdb/mdb.c
// Function: mdb_update_key
static int
mdb_update_key(MDB_cursor *mc, MDB_val *key)
{
	MDB_page		*mp;
	MDB_node		*node;
	char			*base;
	size_t			 len;
	int				 delta, ksize, oksize;
	indx_t			 ptr, i, numkeys, indx;
	DKBUF;

	indx = mc->mc_ki[mc->mc_top];
	mp = mc->mc_pg[mc->mc_top];
	node = NODEPTR(mp, indx);
	ptr = mp->mp_ptrs[indx];
#if MDB_DEBUG
	{
		MDB_val	k2;
		char kbuf2[DKBUF_MAXKEYSIZE*2+1];
		k2.mv_data = NODEKEY(node);
		k2.mv_size = node->mn_ksize;
		DPRINTF(("update key %u (ofs %u) [%s] to [%s] on page %"Z"u",
			indx, ptr,
			mdb_dkey(&k2, kbuf2),
			DKEY(key),
			mp->mp_pgno));
	}
#endif

	/* Sizes must be 2-byte aligned. */
	ksize = EVEN(key->mv_size);
	oksize = EVEN(node->mn_ksize);
	delta = ksize - oksize;

	/* Shift node contents if EVEN(key length) changed. */
	if (delta) {
		if (delta > 0 && SIZELEFT(mp) < delta) {
			pgno_t pgno;
			/* not enough space left, do a delete and split */
			DPRINTF(("Not enough room, delta = %d, splitting...", delta));
			pgno = NODEPGNO(node);
			mdb_node_del(mc, 0);
			return mdb_page_split(mc, key, NULL, pgno, MDB_SPLIT_REPLACE);
		}

		numkeys = NUMKEYS(mp);
		for (i = 0; i < numkeys; i++) {
			if (mp->mp_ptrs[i] <= ptr)
				mp->mp_ptrs[i] -= delta;
		}

		base = (char *)mp + mp->mp_upper + PAGEBASE;
		len = ptr - mp->mp_upper + NODESIZE;
		memmove(base - delta, base, len);
		mp->mp_upper -= delta;

		node = NODEPTR(mp, indx);
	}

	/* But even if no shift was needed, update ksize */
	if (node->mn_ksize != key->mv_size)
		node->mn_ksize = key->mv_size;

	if (key->mv_size)
		memcpy(NODEKEY(node), key->mv_data, key->mv_size);

	return MDB_SUCCESS;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r12
pushq %rbx
movq %rsi, %rbx
movq %rdi, %r14
movzwl 0x42(%rdi), %eax
movzwl 0x148(%rdi,%rax,2), %r12d
movq 0x48(%rdi,%rax,8), %r15
movzwl 0x10(%r15,%r12,2), %edx
leaq (%r15,%rdx), %rdi
movq (%rsi), %rax
leal 0x1(%rax), %ebp
andl $-0x2, %ebp
movzwl 0x6(%r15,%rdx), %ecx
movl %ecx, %esi
incl %esi
andl $-0x2, %esi
subl %esi, %ebp
je 0x6a95
testl %ebp, %ebp
jle 0x6a2e
movzwl 0xe(%r15), %ecx
movl 0xc(%r15), %eax
subl %eax, %ecx
movzwl %cx, %ecx
cmpl %ecx, %ebp
jbe 0x6a33
movl (%rdi), %eax
movzwl 0x4(%rdi), %r15d
shlq $0x20, %r15
orq %rax, %r15
movq %r14, %rdi
xorl %esi, %esi
callq 0x6e79
movq %r14, %rdi
movq %rbx, %rsi
xorl %edx, %edx
movq %r15, %rcx
movl $0x40000, %r8d          # imm = 0x40000
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
jmp 0x742d
movzwl 0xc(%r15), %eax
movzwl %ax, %eax
addl $0x1fff0, %eax          # imm = 0x1FFF0
shrl %eax
movzwl %ax, %eax
xorl %ecx, %ecx
cmpq %rcx, %rax
je 0x6a5f
movzwl 0x10(%r15,%rcx,2), %esi
cmpw %dx, %si
ja 0x6a5a
subl %ebp, %esi
movw %si, 0x10(%r15,%rcx,2)
incq %rcx
jmp 0x6a42
movzwl 0xe(%r15), %eax
leaq (%r15,%rax), %rsi
subq %rax, %rdx
addq $0x8, %rdx
movslq %ebp, %rax
movq %rsi, %rdi
subq %rax, %rdi
callq 0x22e0
subw %bp, 0xe(%r15)
movzwl 0x10(%r15,%r12,2), %eax
leaq (%r15,%rax), %rdi
movzwl 0x6(%r15,%rax), %ecx
movq (%rbx), %rax
movzwl %cx, %ecx
cmpq %rcx, %rax
je 0x6aa1
movw %ax, 0x6(%rdi)
testq %rax, %rax
je 0x6ab6
addq $0x8, %rdi
movq 0x8(%rbx), %rsi
movq %rax, %rdx
callq 0x2240
xorl %eax, %eax
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
retq