// File: jvanns[P]verbatim/sub/lmdb/libraries/liblmdb/mdb.c
// Function: mdb_node_search
static MDB_node *
mdb_node_search(MDB_cursor *mc, MDB_val *key, int *exactp)
{
	unsigned int	 i = 0, nkeys;
	int		 low, high;
	int		 rc = 0;
	MDB_page *mp = mc->mc_pg[mc->mc_top];
	MDB_node	*node = NULL;
	MDB_val	 nodekey;
	MDB_cmp_func *cmp;
	DKBUF;

	nkeys = NUMKEYS(mp);

	DPRINTF(("searching %u keys in %s %spage %"Z"u",
	    nkeys, IS_LEAF(mp) ? "leaf" : "branch", IS_SUBP(mp) ? "sub-" : "",
	    mdb_dbg_pgno(mp)));

	low = IS_LEAF(mp) ? 0 : 1;
	high = nkeys - 1;
	cmp = mc->mc_dbx->md_cmp;

	/* Branch pages have no data, so if using integer keys,
	 * alignment is guaranteed. Use faster mdb_cmp_int.
	 */
	if (cmp == mdb_cmp_cint && IS_BRANCH(mp)) {
		if (NODEPTR(mp, 1)->mn_ksize == sizeof(size_t))
			cmp = mdb_cmp_long;
		else
			cmp = mdb_cmp_int;
	}

	if (IS_LEAF2(mp)) {
		nodekey.mv_size = mc->mc_db->md_pad;
		node = NODEPTR(mp, 0);	/* fake */
		while (low <= high) {
			i = (low + high) >> 1;
			nodekey.mv_data = LEAF2KEY(mp, i, nodekey.mv_size);
			rc = cmp(key, &nodekey);
			DPRINTF(("found leaf index %u [%s], rc = %i",
			    i, DKEY(&nodekey), rc));
			if (rc == 0)
				break;
			if (rc > 0)
				low = i + 1;
			else
				high = i - 1;
		}
	} else {
		while (low <= high) {
			i = (low + high) >> 1;

			node = NODEPTR(mp, i);
			nodekey.mv_size = NODEKSZ(node);
			nodekey.mv_data = NODEKEY(node);

			rc = cmp(key, &nodekey);
#if MDB_DEBUG
			if (IS_LEAF(mp))
				DPRINTF(("found leaf index %u [%s], rc = %i",
				    i, DKEY(&nodekey), rc));
			else
				DPRINTF(("found branch index %u [%s -> %"Z"u], rc = %i",
				    i, DKEY(&nodekey), NODEPGNO(node), rc));
#endif
			if (rc == 0)
				break;
			if (rc > 0)
				low = i + 1;
			else
				high = i - 1;
		}
	}

	if (rc > 0) {	/* Found entry is less than the key. */
		i++;	/* Skip to get the smallest entry larger than key. */
		if (!IS_LEAF2(mp))
			node = NODEPTR(mp, i);
	}
	if (exactp)
		*exactp = (rc == 0 && nkeys > 0);
	/* store the key index */
	mc->mc_ki[mc->mc_top] = i;
	if (i >= nkeys)
		/* There is no entry larger or equal to the key. */
		return NULL;

	/* nodeptr is fake for LEAF2 */
	return node;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x70, %rsp
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movq %rdx, -0x20(%rbp)
movl $0x0, -0x24(%rbp)
movl $0x0, -0x34(%rbp)
movq -0x10(%rbp), %rax
movq -0x10(%rbp), %rcx
movzwl 0x42(%rcx), %ecx
movq 0x48(%rax,%rcx,8), %rax
movq %rax, -0x40(%rbp)
movq $0x0, -0x48(%rbp)
movq -0x40(%rbp), %rax
movzwl 0xc(%rax), %eax
subl $0x10, %eax
shrl %eax
movl %eax, -0x28(%rbp)
movq -0x40(%rbp), %rax
movzwl 0xa(%rax), %edx
andl $0x2, %edx
movl $0x1, %eax
xorl %ecx, %ecx
cmpl $0x2, %edx
cmovel %ecx, %eax
movl %eax, -0x2c(%rbp)
movl -0x28(%rbp), %eax
subl $0x1, %eax
movl %eax, -0x30(%rbp)
movq -0x10(%rbp), %rax
movq 0x30(%rax), %rax
movq 0x10(%rax), %rax
movq %rax, -0x60(%rbp)
leaq 0xa76(%rip), %rax       # 0xfca0
cmpq %rax, -0x60(%rbp)
jne 0xf274
movq -0x40(%rbp), %rax
movzwl 0xa(%rax), %eax
andl $0x1, %eax
cmpl $0x1, %eax
jne 0xf274
movq -0x40(%rbp), %rax
movq -0x40(%rbp), %rcx
movzwl 0x12(%rcx), %ecx
movslq %ecx, %rcx
movzwl 0x6(%rax,%rcx), %eax
cmpq $0x8, %rax
jne 0xf267
leaq -0xbf81(%rip), %rax     # 0x32e0
movq %rax, -0x60(%rbp)
jmp 0xf272
leaq -0xbfde(%rip), %rax     # 0x3290
movq %rax, -0x60(%rbp)
jmp 0xf274
movq -0x40(%rbp), %rax
movzwl 0xa(%rax), %eax
andl $0x20, %eax
cmpl $0x20, %eax
jne 0xf30d
movq -0x10(%rbp), %rax
movq 0x28(%rax), %rax
movl (%rax), %eax
movq %rax, -0x58(%rbp)
movq -0x40(%rbp), %rax
movq -0x40(%rbp), %rcx
movzwl 0x10(%rcx), %ecx
movslq %ecx, %rcx
addq %rcx, %rax
movq %rax, -0x48(%rbp)
movl -0x2c(%rbp), %eax
cmpl -0x30(%rbp), %eax
jg 0xf30b
movl -0x2c(%rbp), %eax
addl -0x30(%rbp), %eax
sarl %eax
movl %eax, -0x24(%rbp)
movq -0x40(%rbp), %rax
addq $0x10, %rax
movl -0x24(%rbp), %ecx
imulq -0x58(%rbp), %rcx
addq %rcx, %rax
movq %rax, -0x50(%rbp)
movq -0x60(%rbp), %rax
movq -0x18(%rbp), %rdi
leaq -0x58(%rbp), %rsi
callq *%rax
movl %eax, -0x34(%rbp)
cmpl $0x0, -0x34(%rbp)
jne 0xf2ef
jmp 0xf30b
cmpl $0x0, -0x34(%rbp)
jle 0xf300
movl -0x24(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x2c(%rbp)
jmp 0xf309
movl -0x24(%rbp), %eax
subl $0x1, %eax
movl %eax, -0x30(%rbp)
jmp 0xf2ac
jmp 0xf38b
jmp 0xf30f
movl -0x2c(%rbp), %eax
cmpl -0x30(%rbp), %eax
jg 0xf389
movl -0x2c(%rbp), %eax
addl -0x30(%rbp), %eax
sarl %eax
movl %eax, -0x24(%rbp)
movq -0x40(%rbp), %rax
movq -0x40(%rbp), %rcx
movl -0x24(%rbp), %edx
movzwl 0x10(%rcx,%rdx,2), %ecx
movslq %ecx, %rcx
addq %rcx, %rax
movq %rax, -0x48(%rbp)
movq -0x48(%rbp), %rax
movzwl 0x6(%rax), %eax
movq %rax, -0x58(%rbp)
movq -0x48(%rbp), %rax
addq $0x8, %rax
movq %rax, -0x50(%rbp)
movq -0x60(%rbp), %rax
movq -0x18(%rbp), %rdi
leaq -0x58(%rbp), %rsi
callq *%rax
movl %eax, -0x34(%rbp)
cmpl $0x0, -0x34(%rbp)
jne 0xf36d
jmp 0xf389
cmpl $0x0, -0x34(%rbp)
jle 0xf37e
movl -0x24(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x2c(%rbp)
jmp 0xf387
movl -0x24(%rbp), %eax
subl $0x1, %eax
movl %eax, -0x30(%rbp)
jmp 0xf30f
jmp 0xf38b
cmpl $0x0, -0x34(%rbp)
jle 0xf3c6
movl -0x24(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x24(%rbp)
movq -0x40(%rbp), %rax
movzwl 0xa(%rax), %eax
andl $0x20, %eax
cmpl $0x20, %eax
je 0xf3c4
movq -0x40(%rbp), %rax
movq -0x40(%rbp), %rcx
movl -0x24(%rbp), %edx
movzwl 0x10(%rcx,%rdx,2), %ecx
movslq %ecx, %rcx
addq %rcx, %rax
movq %rax, -0x48(%rbp)
jmp 0xf3c6
cmpq $0x0, -0x20(%rbp)
je 0xf3f0
xorl %eax, %eax
cmpl $0x0, -0x34(%rbp)
movb %al, -0x61(%rbp)
jne 0xf3e2
cmpl $0x0, -0x28(%rbp)
seta %al
movb %al, -0x61(%rbp)
movb -0x61(%rbp), %al
andb $0x1, %al
movzbl %al, %ecx
movq -0x20(%rbp), %rax
movl %ecx, (%rax)
movl -0x24(%rbp), %eax
movw %ax, %dx
movq -0x10(%rbp), %rax
movq -0x10(%rbp), %rcx
movzwl 0x42(%rcx), %ecx
movw %dx, 0x148(%rax,%rcx,2)
movl -0x24(%rbp), %eax
cmpl -0x28(%rbp), %eax
jb 0xf41c
movq $0x0, -0x8(%rbp)
jmp 0xf424
movq -0x48(%rbp), %rax
movq %rax, -0x8(%rbp)
movq -0x8(%rbp), %rax
addq $0x70, %rsp
popq %rbp
retq
nop