// File: jvanns[P]verbatim/sub/lmdb/libraries/liblmdb/mdb.c
// Function: mdb_dbi_open
int mdb_dbi_open(MDB_txn *txn, const char *name, unsigned int flags, MDB_dbi *dbi)
{
	MDB_val key, data;
	MDB_dbi i;
	MDB_cursor mc;
	MDB_db dummy;
	int rc, dbflag, exact;
	unsigned int unused = 0, seq;
	size_t len;

	if (flags & ~VALID_FLAGS)
		return EINVAL;
	if (txn->mt_flags & MDB_TXN_BLOCKED)
		return MDB_BAD_TXN;

	/* main DB? */
	if (!name) {
		*dbi = MAIN_DBI;
		if (flags & PERSISTENT_FLAGS) {
			uint16_t f2 = flags & PERSISTENT_FLAGS;
			/* make sure flag changes get committed */
			if ((txn->mt_dbs[MAIN_DBI].md_flags | f2) != txn->mt_dbs[MAIN_DBI].md_flags) {
				txn->mt_dbs[MAIN_DBI].md_flags |= f2;
				txn->mt_flags |= MDB_TXN_DIRTY;
			}
		}
		mdb_default_cmp(txn, MAIN_DBI);
		return MDB_SUCCESS;
	}

	if (txn->mt_dbxs[MAIN_DBI].md_cmp == NULL) {
		mdb_default_cmp(txn, MAIN_DBI);
	}

	/* Is the DB already open? */
	len = strlen(name);
	for (i=CORE_DBS; i<txn->mt_numdbs; i++) {
		if (!txn->mt_dbxs[i].md_name.mv_size) {
			/* Remember this free slot */
			if (!unused) unused = i;
			continue;
		}
		if (len == txn->mt_dbxs[i].md_name.mv_size &&
			!strncmp(name, txn->mt_dbxs[i].md_name.mv_data, len)) {
			*dbi = i;
			return MDB_SUCCESS;
		}
	}

	/* If no free slot and max hit, fail */
	if (!unused && txn->mt_numdbs >= txn->mt_env->me_maxdbs)
		return MDB_DBS_FULL;

	/* Cannot mix named databases with some mainDB flags */
	if (txn->mt_dbs[MAIN_DBI].md_flags & (MDB_DUPSORT|MDB_INTEGERKEY))
		return (flags & MDB_CREATE) ? MDB_INCOMPATIBLE : MDB_NOTFOUND;

	/* Find the DB info */
	dbflag = DB_NEW|DB_VALID|DB_USRVALID;
	exact = 0;
	key.mv_size = len;
	key.mv_data = (void *)name;
	mdb_cursor_init(&mc, txn, MAIN_DBI, NULL);
	rc = mdb_cursor_set(&mc, &key, &data, MDB_SET, &exact);
	if (rc == MDB_SUCCESS) {
		/* make sure this is actually a DB */
		MDB_node *node = NODEPTR(mc.mc_pg[mc.mc_top], mc.mc_ki[mc.mc_top]);
		if ((node->mn_flags & (F_DUPDATA|F_SUBDATA)) != F_SUBDATA)
			return MDB_INCOMPATIBLE;
	} else if (rc == MDB_NOTFOUND && (flags & MDB_CREATE)) {
		/* Create if requested */
		data.mv_size = sizeof(MDB_db);
		data.mv_data = &dummy;
		memset(&dummy, 0, sizeof(dummy));
		dummy.md_root = P_INVALID;
		dummy.md_flags = flags & PERSISTENT_FLAGS;
		rc = mdb_cursor_put(&mc, &key, &data, F_SUBDATA);
		dbflag |= DB_DIRTY;
	}

	/* OK, got info, add to table */
	if (rc == MDB_SUCCESS) {
		unsigned int slot = unused ? unused : txn->mt_numdbs;
		txn->mt_dbxs[slot].md_name.mv_data = strdup(name);
		txn->mt_dbxs[slot].md_name.mv_size = len;
		txn->mt_dbxs[slot].md_rel = NULL;
		txn->mt_dbflags[slot] = dbflag;
		/* txn-> and env-> are the same in read txns, use
		 * tmp variable to avoid undefined assignment
		 */
		seq = ++txn->mt_env->me_dbiseqs[slot];
		txn->mt_dbiseqs[slot] = seq;

		memcpy(&txn->mt_dbs[slot], data.mv_data, sizeof(MDB_db));
		*dbi = slot;
		mdb_default_cmp(txn, slot);
		if (!unused) {
			txn->mt_numdbs++;
		}
	}

	return rc;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x240, %rsp            # imm = 0x240
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movl %edx, -0x1c(%rbp)
movq %rcx, -0x28(%rbp)
movl $0x0, -0x218(%rbp)
movl -0x1c(%rbp), %eax
andl $0xfffbff81, %eax       # imm = 0xFFFBFF81
cmpl $0x0, %eax
je 0xe0cd
movl $0x16, -0x4(%rbp)
jmp 0xe56a
movq -0x10(%rbp), %rax
movl 0x7c(%rax), %eax
andl $0x13, %eax
cmpl $0x0, %eax
je 0xe0e8
movl $0xffff87c2, -0x4(%rbp) # imm = 0xFFFF87C2
jmp 0xe56a
cmpq $0x0, -0x18(%rbp)
jne 0xe180
movq -0x28(%rbp), %rax
movl $0x1, (%rax)
movl -0x1c(%rbp), %eax
andl $0x7fff, %eax           # imm = 0x7FFF
cmpl $0x0, %eax
je 0xe166
movl -0x1c(%rbp), %eax
andl $0x7fff, %eax           # imm = 0x7FFF
movw %ax, -0x22a(%rbp)
movq -0x10(%rbp), %rax
movq 0x58(%rax), %rax
movzwl 0x34(%rax), %eax
movzwl -0x22a(%rbp), %ecx
orl %ecx, %eax
movq -0x10(%rbp), %rcx
movq 0x58(%rcx), %rcx
movzwl 0x34(%rcx), %ecx
cmpl %ecx, %eax
je 0xe164
movzwl -0x22a(%rbp), %edx
movq -0x10(%rbp), %rax
movq 0x58(%rax), %rax
movzwl 0x34(%rax), %ecx
orl %edx, %ecx
movw %cx, 0x34(%rax)
movq -0x10(%rbp), %rax
movl 0x7c(%rax), %ecx
orl $0x4, %ecx
movl %ecx, 0x7c(%rax)
jmp 0xe166
movq -0x10(%rbp), %rdi
movl $0x1, %esi
callq 0xe580
movl $0x0, -0x4(%rbp)
jmp 0xe56a
movq -0x10(%rbp), %rax
movq 0x50(%rax), %rax
cmpq $0x0, 0x40(%rax)
jne 0xe19d
movq -0x10(%rbp), %rdi
movl $0x1, %esi
callq 0xe580
movq -0x18(%rbp), %rdi
callq 0x2100
movq %rax, -0x228(%rbp)
movl $0x2, -0x4c(%rbp)
movl -0x4c(%rbp), %eax
movq -0x10(%rbp), %rcx
cmpl 0x78(%rcx), %eax
jae 0xe25e
movq -0x10(%rbp), %rax
movq 0x50(%rax), %rax
movl -0x4c(%rbp), %ecx
imulq $0x30, %rcx, %rcx
addq %rcx, %rax
cmpq $0x0, (%rax)
jne 0xe1f0
cmpl $0x0, -0x218(%rbp)
jne 0xe1ee
movl -0x4c(%rbp), %eax
movl %eax, -0x218(%rbp)
jmp 0xe250
movq -0x228(%rbp), %rax
movq -0x10(%rbp), %rcx
movq 0x50(%rcx), %rcx
movl -0x4c(%rbp), %edx
imulq $0x30, %rdx, %rdx
addq %rdx, %rcx
cmpq (%rcx), %rax
jne 0xe24e
movq -0x18(%rbp), %rdi
movq -0x10(%rbp), %rax
movq 0x50(%rax), %rax
movl -0x4c(%rbp), %ecx
imulq $0x30, %rcx, %rcx
addq %rcx, %rax
movq 0x8(%rax), %rsi
movq -0x228(%rbp), %rdx
callq 0x2070
cmpl $0x0, %eax
jne 0xe24e
movl -0x4c(%rbp), %ecx
movq -0x28(%rbp), %rax
movl %ecx, (%rax)
movl $0x0, -0x4(%rbp)
jmp 0xe56a
jmp 0xe250
movl -0x4c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x4c(%rbp)
jmp 0xe1b4
cmpl $0x0, -0x218(%rbp)
jne 0xe287
movq -0x10(%rbp), %rax
movl 0x78(%rax), %eax
movq -0x10(%rbp), %rcx
movq 0x20(%rcx), %rcx
cmpl 0x24(%rcx), %eax
jb 0xe287
movl $0xffff87b9, -0x4(%rbp) # imm = 0xFFFF87B9
jmp 0xe56a
movq -0x10(%rbp), %rax
movq 0x58(%rax), %rax
movzwl 0x34(%rax), %eax
andl $0xc, %eax
cmpl $0x0, %eax
je 0xe2bc
movl -0x1c(%rbp), %edx
andl $0x40000, %edx          # imm = 0x40000
movl $0xffff87b2, %eax       # imm = 0xFFFF87B2
movl $0xffff87c0, %ecx       # imm = 0xFFFF87C0
cmpl $0x0, %edx
cmovnel %ecx, %eax
movl %eax, -0x4(%rbp)
jmp 0xe56a
movl $0x1c, -0x210(%rbp)
movl $0x0, -0x214(%rbp)
movq -0x228(%rbp), %rax
movq %rax, -0x38(%rbp)
movq -0x18(%rbp), %rax
movq %rax, -0x30(%rbp)
movq -0x10(%rbp), %rsi
leaq -0x1d8(%rbp), %rdi
movl $0x1, %edx
xorl %eax, %eax
movl %eax, %ecx
callq 0x4d40
leaq -0x1d8(%rbp), %rdi
leaq -0x38(%rbp), %rsi
leaq -0x48(%rbp), %rdx
movl $0xf, %ecx
leaq -0x214(%rbp), %r8
callq 0x7970
movl %eax, -0x20c(%rbp)
cmpl $0x0, -0x20c(%rbp)
jne 0xe38e
movzwl -0x196(%rbp), %eax
movq -0x190(%rbp,%rax,8), %rax
movzwl -0x196(%rbp), %ecx
movq -0x190(%rbp,%rcx,8), %rcx
movzwl -0x196(%rbp), %edx
movzwl -0x90(%rbp,%rdx,2), %edx
movzwl 0x10(%rcx,%rdx,2), %ecx
movslq %ecx, %rcx
addq %rcx, %rax
movq %rax, -0x238(%rbp)
movq -0x238(%rbp), %rax
movzwl 0x4(%rax), %eax
andl $0x6, %eax
cmpl $0x2, %eax
je 0xe389
movl $0xffff87c0, -0x4(%rbp) # imm = 0xFFFF87C0
jmp 0xe56a
jmp 0xe417
cmpl $0xffff87b2, -0x20c(%rbp) # imm = 0xFFFF87B2
jne 0xe415
movl -0x1c(%rbp), %eax
andl $0x40000, %eax          # imm = 0x40000
cmpl $0x0, %eax
je 0xe415
movq $0x30, -0x48(%rbp)
leaq -0x208(%rbp), %rax
movq %rax, -0x40(%rbp)
leaq -0x208(%rbp), %rdi
xorl %esi, %esi
movl $0x30, %edx
callq 0x2180
movq $-0x1, -0x1e0(%rbp)
movl -0x1c(%rbp), %eax
andl $0x7fff, %eax           # imm = 0x7FFF
movw %ax, -0x204(%rbp)
leaq -0x1d8(%rbp), %rdi
leaq -0x38(%rbp), %rsi
leaq -0x48(%rbp), %rdx
movl $0x2, %ecx
callq 0x4eb0
movl %eax, -0x20c(%rbp)
movl -0x210(%rbp), %eax
orl $0x1, %eax
movl %eax, -0x210(%rbp)
jmp 0xe417
cmpl $0x0, -0x20c(%rbp)
jne 0xe561
cmpl $0x0, -0x218(%rbp)
je 0xe43b
movl -0x218(%rbp), %eax
movl %eax, -0x240(%rbp)
jmp 0xe448
movq -0x10(%rbp), %rax
movl 0x78(%rax), %eax
movl %eax, -0x240(%rbp)
movl -0x240(%rbp), %eax
movl %eax, -0x23c(%rbp)
movq -0x18(%rbp), %rdi
callq 0x23b0
movq %rax, %rcx
movq -0x10(%rbp), %rax
movq 0x50(%rax), %rax
movl -0x23c(%rbp), %edx
imulq $0x30, %rdx, %rdx
addq %rdx, %rax
movq %rcx, 0x8(%rax)
movq -0x228(%rbp), %rcx
movq -0x10(%rbp), %rax
movq 0x50(%rax), %rax
movl -0x23c(%rbp), %edx
imulq $0x30, %rdx, %rdx
addq %rdx, %rax
movq %rcx, (%rax)
movq -0x10(%rbp), %rax
movq 0x50(%rax), %rax
movl -0x23c(%rbp), %ecx
imulq $0x30, %rcx, %rcx
addq %rcx, %rax
movq $0x0, 0x20(%rax)
movl -0x210(%rbp), %eax
movb %al, %dl
movq -0x10(%rbp), %rax
movq 0x70(%rax), %rax
movl -0x23c(%rbp), %ecx
movb %dl, (%rax,%rcx)
movq -0x10(%rbp), %rax
movq 0x20(%rax), %rax
movq 0x98(%rax), %rcx
movl -0x23c(%rbp), %eax
movl %eax, %edx
movl (%rcx,%rdx,4), %eax
addl $0x1, %eax
movl %eax, (%rcx,%rdx,4)
movl %eax, -0x21c(%rbp)
movl -0x21c(%rbp), %edx
movq -0x10(%rbp), %rax
movq 0x60(%rax), %rax
movl -0x23c(%rbp), %ecx
movl %edx, (%rax,%rcx,4)
movq -0x10(%rbp), %rax
movq 0x58(%rax), %rdi
movl -0x23c(%rbp), %eax
imulq $0x30, %rax, %rax
addq %rax, %rdi
movq -0x40(%rbp), %rsi
movl $0x30, %edx
callq 0x2230
movl -0x23c(%rbp), %ecx
movq -0x28(%rbp), %rax
movl %ecx, (%rax)
movq -0x10(%rbp), %rdi
movl -0x23c(%rbp), %esi
callq 0xe580
cmpl $0x0, -0x218(%rbp)
jne 0xe55f
movq -0x10(%rbp), %rax
movl 0x78(%rax), %ecx
addl $0x1, %ecx
movl %ecx, 0x78(%rax)
jmp 0xe561
movl -0x20c(%rbp), %eax
movl %eax, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0x240, %rsp            # imm = 0x240
popq %rbp
retq
nopw %cs:(%rax,%rax)