// File: /workspace/github_cpp_makefile_star2_O1/jvanns[P]verbatim/sub/lmdb/libraries/liblmdb/mdb.c
// Function: mdb_txn_commit
int
mdb_txn_commit(MDB_txn *txn)
{
	int		rc;
	unsigned int i, end_mode;
	MDB_env	*env;

	if (txn == NULL)
		return EINVAL;

	/* mdb_txn_end() mode for a commit which writes nothing */
	end_mode = MDB_END_EMPTY_COMMIT|MDB_END_UPDATE|MDB_END_SLOT|MDB_END_FREE;

	if (txn->mt_child) {
		rc = mdb_txn_commit(txn->mt_child);
		if (rc)
			goto fail;
	}

	env = txn->mt_env;

	if (F_ISSET(txn->mt_flags, MDB_TXN_RDONLY)) {
		goto done;
	}

	if (txn->mt_flags & (MDB_TXN_FINISHED|MDB_TXN_ERROR)) {
		DPUTS("txn has failed/finished, can't commit");
		if (txn->mt_parent)
			txn->mt_parent->mt_flags |= MDB_TXN_ERROR;
		rc = MDB_BAD_TXN;
		goto fail;
	}

	if (txn->mt_parent) {
		MDB_txn *parent = txn->mt_parent;
		MDB_page **lp;
		MDB_ID2L dst, src;
		MDB_IDL pspill;
		unsigned x, y, len, ps_len;

		/* Append our free list to parent's */
		rc = mdb_midl_append_list(&parent->mt_free_pgs, txn->mt_free_pgs);
		if (rc)
			goto fail;
		mdb_midl_free(txn->mt_free_pgs);
		/* Failures after this must either undo the changes
		 * to the parent or set MDB_TXN_ERROR in the parent.
		 */

		parent->mt_next_pgno = txn->mt_next_pgno;
		parent->mt_flags = txn->mt_flags;

		/* Merge our cursors into parent's and close them */
		mdb_cursors_close(txn, 1);

		/* Update parent's DB table. */
		memcpy(parent->mt_dbs, txn->mt_dbs, txn->mt_numdbs * sizeof(MDB_db));
		parent->mt_numdbs = txn->mt_numdbs;
		parent->mt_dbflags[FREE_DBI] = txn->mt_dbflags[FREE_DBI];
		parent->mt_dbflags[MAIN_DBI] = txn->mt_dbflags[MAIN_DBI];
		for (i=CORE_DBS; i<txn->mt_numdbs; i++) {
			/* preserve parent's DB_NEW status */
			x = parent->mt_dbflags[i] & DB_NEW;
			parent->mt_dbflags[i] = txn->mt_dbflags[i] | x;
		}

		dst = parent->mt_u.dirty_list;
		src = txn->mt_u.dirty_list;
		/* Remove anything in our dirty list from parent's spill list */
		if ((pspill = parent->mt_spill_pgs) && (ps_len = pspill[0])) {
			x = y = ps_len;
			pspill[0] = (pgno_t)-1;
			/* Mark our dirty pages as deleted in parent spill list */
			for (i=0, len=src[0].mid; ++i <= len; ) {
				MDB_ID pn = src[i].mid << 1;
				while (pn > pspill[x])
					x--;
				if (pn == pspill[x]) {
					pspill[x] = 1;
					y = --x;
				}
			}
			/* Squash deleted pagenums if we deleted any */
			for (x=y; ++x <= ps_len; )
				if (!(pspill[x] & 1))
					pspill[++y] = pspill[x];
			pspill[0] = y;
		}

		/* Find len = length of merging our dirty list with parent's */
		x = dst[0].mid;
		dst[0].mid = 0;		/* simplify loops */
		if (parent->mt_parent) {
			len = x + src[0].mid;
			y = mdb_mid2l_search(src, dst[x].mid + 1) - 1;
			for (i = x; y && i; y--) {
				pgno_t yp = src[y].mid;
				while (yp < dst[i].mid)
					i--;
				if (yp == dst[i].mid) {
					i--;
					len--;
				}
			}
		} else { /* Simplify the above for single-ancestor case */
			len = MDB_IDL_UM_MAX - txn->mt_dirty_room;
		}
		/* Merge our dirty list with parent's */
		y = src[0].mid;
		for (i = len; y; dst[i--] = src[y--]) {
			pgno_t yp = src[y].mid;
			while (yp < dst[x].mid)
				dst[i--] = dst[x--];
			if (yp == dst[x].mid)
				free(dst[x--].mptr);
		}
		mdb_tassert(txn, i == x);
		dst[0].mid = len;
		free(txn->mt_u.dirty_list);
		parent->mt_dirty_room = txn->mt_dirty_room;
		if (txn->mt_spill_pgs) {
			if (parent->mt_spill_pgs) {
				/* TODO: Prevent failure here, so parent does not fail */
				rc = mdb_midl_append_list(&parent->mt_spill_pgs, txn->mt_spill_pgs);
				if (rc)
					parent->mt_flags |= MDB_TXN_ERROR;
				mdb_midl_free(txn->mt_spill_pgs);
				mdb_midl_sort(parent->mt_spill_pgs);
			} else {
				parent->mt_spill_pgs = txn->mt_spill_pgs;
			}
		}

		/* Append our loose page list to parent's */
		for (lp = &parent->mt_loose_pgs; *lp; lp = &NEXT_LOOSE_PAGE(lp))
			;
		*lp = txn->mt_loose_pgs;
		parent->mt_loose_count += txn->mt_loose_count;

		parent->mt_child = NULL;
		mdb_midl_free(((MDB_ntxn *)txn)->mnt_pgstate.mf_pghead);
		free(txn);
		return rc;
	}

	if (txn != env->me_txn) {
		DPUTS("attempt to commit unknown transaction");
		rc = EINVAL;
		goto fail;
	}

	mdb_cursors_close(txn, 0);

	if (!txn->mt_u.dirty_list[0].mid &&
		!(txn->mt_flags & (MDB_TXN_DIRTY|MDB_TXN_SPILLS)))
		goto done;

	DPRINTF(("committing txn %"Z"u %p on mdbenv %p, root page %"Z"u",
	    txn->mt_txnid, (void*)txn, (void*)env, txn->mt_dbs[MAIN_DBI].md_root));

	/* Update DB root pointers */
	if (txn->mt_numdbs > CORE_DBS) {
		MDB_cursor mc;
		MDB_dbi i;
		MDB_val data;
		data.mv_size = sizeof(MDB_db);

		mdb_cursor_init(&mc, txn, MAIN_DBI, NULL);
		for (i = CORE_DBS; i < txn->mt_numdbs; i++) {
			if (txn->mt_dbflags[i] & DB_DIRTY) {
				if (TXN_DBI_CHANGED(txn, i)) {
					rc = MDB_BAD_DBI;
					goto fail;
				}
				data.mv_data = &txn->mt_dbs[i];
				rc = mdb_cursor_put(&mc, &txn->mt_dbxs[i].md_name, &data,
					F_SUBDATA);
				if (rc)
					goto fail;
			}
		}
	}

	rc = mdb_freelist_save(txn);
	if (rc)
		goto fail;

	mdb_midl_free(env->me_pghead);
	env->me_pghead = NULL;
	mdb_midl_shrink(&txn->mt_free_pgs);

#if (MDB_DEBUG) > 2
	mdb_audit(txn);
#endif

	if ((rc = mdb_page_flush(txn, 0)))
		goto fail;
	if (!F_ISSET(txn->mt_flags, MDB_TXN_NOSYNC) &&
		(rc = mdb_env_sync(env, 0)))
		goto fail;
	if ((rc = mdb_env_write_meta(txn)))
		goto fail;
	end_mode = MDB_END_COMMITTED|MDB_END_UPDATE;

done:
	mdb_txn_end(txn, end_mode);
	return MDB_SUCCESS;

fail:
	mdb_txn_abort(txn);
	return rc;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x1b8, %rsp            # imm = 0x1B8
testq %rdi, %rdi
je 0x3ba5
movq %rdi, %rbx
movq 0x8(%rdi), %rdi
testq %rdi, %rdi
je 0x3b72
callq 0x3b3f
testl %eax, %eax
je 0x3b72
movl %eax, %r14d
jmp 0x3fcd
movl 0x7c(%rbx), %eax
movl $0x200031, %ebp         # imm = 0x200031
btl $0x11, %eax
jb 0x405a
movq (%rbx), %r12
testb $0x3, %al
je 0x3bb0
movl $0xffff87c2, %r14d      # imm = 0xFFFF87C2
testq %r12, %r12
je 0x3fcd
orb $0x2, 0x7c(%r12)
jmp 0x3fcd
movl $0x16, %r14d
jmp 0x4067
testq %r12, %r12
je 0x3bd3
leaq 0x28(%r12), %rdi
movq 0x28(%rbx), %rsi
callq 0xc061
testl %eax, %eax
je 0x3cb8
movl %eax, %r14d
jmp 0x3fc5
movq 0x20(%rbx), %r15
movl $0x16, %r14d
cmpq %rbx, 0x60(%r15)
jne 0x3fcd
movq %rbx, %rdi
xorl %esi, %esi
callq 0x4098
movq 0x48(%rbx), %rax
cmpq $0x0, (%rax)
jne 0x3c05
testb $0xc, 0x7c(%rbx)
je 0x405a
cmpl $0x3, 0x78(%rbx)
jb 0x3feb
movq $0x30, 0x20(%rsp)
xorl %r14d, %r14d
leaq 0x30(%rsp), %rdi
movq %rbx, %rsi
movl $0x1, %edx
xorl %ecx, %ecx
callq 0x4177
cmpl $0x3, 0x78(%rbx)
setae %bpl
jb 0x3fe5
movl $0x2, %r12d
movl $0x60, %r13d
movq 0x70(%rbx), %rax
testb $0x1, (%rax,%r12)
je 0x3ca0
movq 0x20(%rbx), %rax
movq 0x60(%rbx), %rcx
movl (%rcx,%r12,4), %ecx
movq 0x98(%rax), %rax
cmpl (%rax,%r12,4), %ecx
jne 0x3fda
movq 0x58(%rbx), %rax
addq %r13, %rax
movq %rax, 0x28(%rsp)
movq 0x50(%rbx), %rsi
addq %r13, %rsi
leaq 0x30(%rsp), %rdi
leaq 0x20(%rsp), %rdx
movl $0x2, %ecx
callq 0x427c
testl %eax, %eax
jne 0x3fe2
incq %r12
movl 0x78(%rbx), %eax
addq $0x30, %r13
cmpq %rax, %r12
setb %bpl
jb 0x3c49
jmp 0x3fe5
movl %eax, 0x14(%rsp)
movq 0x28(%rbx), %rdi
callq 0xbf2d
movq 0x10(%rbx), %rax
movq %rax, 0x10(%r12)
movl 0x7c(%rbx), %eax
movl %eax, 0x7c(%r12)
movq %rbx, %rdi
movl $0x1, %esi
callq 0x4098
movq 0x58(%r12), %rdi
movq 0x58(%rbx), %rsi
movl 0x78(%rbx), %eax
shlq $0x4, %rax
leaq (%rax,%rax,2), %rdx
callq 0x2240
movl 0x78(%rbx), %eax
movl %eax, 0x78(%r12)
movq 0x70(%rbx), %rax
movb (%rax), %al
movq 0x70(%r12), %rcx
movb %al, (%rcx)
movq 0x70(%rbx), %rax
movb 0x1(%rax), %al
movq 0x70(%r12), %rcx
movb %al, 0x1(%rcx)
cmpl $0x3, 0x78(%rbx)
jb 0x3d4b
movl $0x2, %eax
movq 0x70(%r12), %rcx
movb (%rcx,%rax), %dl
andb $0x4, %dl
movq 0x70(%rbx), %rsi
orb (%rsi,%rax), %dl
movb %dl, (%rcx,%rax)
incq %rax
movl 0x78(%rbx), %ecx
cmpq %rcx, %rax
jb 0x3d2b
movq 0x40(%r12), %rax
movq 0x48(%r12), %r15
movq 0x48(%rbx), %rdi
testq %rax, %rax
movq %rdi, 0x8(%rsp)
je 0x3dfc
movl (%rax), %ecx
testl %ecx, %ecx
je 0x3dfc
movq $-0x1, (%rax)
movl (%rdi), %r8d
movl %ecx, %edx
testl %r8d, %r8d
je 0x3dd9
incl %r8d
cmpl $0x3, %r8d
movl $0x2, %esi
cmovael %r8d, %esi
movl $0x1, %r14d
movl %ecx, %edx
movl %ecx, %r8d
movq %r14, %r9
shlq $0x4, %r9
movq (%rdi,%r9), %r9
addq %r9, %r9
movl %r8d, %r10d
movq (%rax,%r10,8), %r11
decl %r8d
cmpq %r11, %r9
ja 0x3dab
jne 0x3dc9
movq $0x1, (%rax,%r10,8)
movl %r8d, %edx
jmp 0x3dcc
incl %r8d
incq %r14
cmpq %rsi, %r14
movq 0x8(%rsp), %rdi
jne 0x3d9d
leal 0x1(%rdx), %esi
cmpl %ecx, %esi
ja 0x3df7
movl %esi, %r8d
movq (%rax,%r8,8), %r8
testb $0x1, %r8b
jne 0x3df3
incl %edx
movq %r8, (%rax,%rdx,8)
incl %esi
jmp 0x3ddc
movl %edx, %ecx
movq %rcx, (%rax)
movq (%r15), %r13
movq $0x0, (%r15)
cmpq $0x0, (%r12)
je 0x3e69
movl %r13d, %ebp
addl (%rdi), %ebp
movl %r13d, %eax
shlq $0x4, %rax
movq (%r15,%rax), %rsi
incq %rsi
callq 0xc310
decl %eax
je 0x3e76
testl %r13d, %r13d
je 0x3e76
movl %r13d, %ecx
movq 0x8(%rsp), %rdi
movl %eax, %edx
shlq $0x4, %rdx
movq (%rdi,%rdx), %rsi
movl %ecx, %edx
notl %edx
movl %ecx, %r8d
shlq $0x4, %r8
decl %ecx
incl %edx
cmpq (%r15,%r8), %rsi
jb 0x3e44
sete %cl
movzbl %cl, %ecx
subl %ecx, %ebp
decl %eax
je 0x3e7b
negl %ecx
subl %edx, %ecx
jne 0x3e36
jmp 0x3e7b
movl $0x1ffff, %ebp          # imm = 0x1FFFF
subl 0x80(%rbx), %ebp
jmp 0x3e7b
movq 0x8(%rsp), %rdi
movq %r12, 0x18(%rsp)
movl (%rdi), %r14d
testq %r14, %r14
movl %ebp, 0x10(%rsp)
je 0x3f17
movq %r14, %r12
shlq $0x4, %r12
movq (%rdi,%r12), %rax
movl %r13d, %edx
movq %rdx, %rcx
shlq $0x4, %rcx
movq (%r15,%rcx), %rsi
cmpq %rsi, %rax
jae 0x3edb
addq %r15, %rcx
movl %ebp, %edx
decl %ebp
shlq $0x4, %rdx
decl %r13d
movups (%rcx), %xmm0
movups %xmm0, (%r15,%rdx)
movq %r13, %rdx
shlq $0x4, %rdx
leaq (%r15,%rdx), %rcx
movq (%r15,%rdx), %rsi
movq %r13, %rdx
cmpq %rsi, %rax
jb 0x3eb1
cmpq %rsi, %rax
jne 0x3ef6
decl %r13d
shlq $0x4, %rdx
movq 0x8(%r15,%rdx), %rdi
callq 0x2030
movq 0x8(%rsp), %rdi
addq %rdi, %r12
movl %ebp, %eax
decl %ebp
shlq $0x4, %rax
decq %r14
movups (%r12), %xmm0
movups %xmm0, (%r15,%rax)
testl %r14d, %r14d
jne 0x3e90
cmpl %r13d, %ebp
jne 0x407c
movl 0x10(%rsp), %eax
movq %rax, (%r15)
movq 0x48(%rbx), %rdi
callq 0x2030
movl 0x80(%rbx), %eax
movq 0x18(%rsp), %r12
movl %eax, 0x80(%r12)
movq 0x40(%rbx), %rsi
xorl %r14d, %r14d
testq %rsi, %rsi
je 0x3f85
leaq 0x40(%r12), %r15
cmpq $0x0, (%r15)
je 0x3f82
movq %r15, %rdi
callq 0xc061
movl %eax, %r14d
testl %eax, %eax
je 0x3f6f
orb $0x2, 0x7c(%r12)
movq 0x40(%rbx), %rdi
callq 0xbf2d
movq (%r15), %rdi
callq 0xc17a
jmp 0x3f85
movq %rsi, (%r15)
leaq 0x30(%r12), %rax
cmpq $0x0, (%rax)
leaq 0x10(%rax), %rax
jne 0x3f8a
movq 0x30(%rbx), %rcx
movq %rcx, -0x10(%rax)
movl 0x38(%rbx), %eax
addl %eax, 0x38(%r12)
movq $0x0, 0x8(%r12)
movq 0x88(%rbx), %rdi
callq 0xbf2d
movq %rbx, %rdi
callq 0x2030
movl 0x14(%rsp), %eax
testl %eax, %eax
je 0x4067
movq %rbx, %rdi
callq 0x3b19
jmp 0x4067
movl $0xffff87c4, %r14d      # imm = 0xFFFF87C4
jmp 0x3fe5
movl %eax, %r14d
testb $0x1, %bpl
jne 0x3fcd
movq %rbx, %rdi
callq 0x50e2
testl %eax, %eax
jne 0x3b6a
movq 0xb0(%r15), %rdi
callq 0xbf2d
movq $0x0, 0xb0(%r15)
leaq 0x28(%rbx), %rdi
callq 0xbf3c
movq %rbx, %rdi
xorl %esi, %esi
callq 0x56d7
testl %eax, %eax
jne 0x3b6a
testb $0x1, 0x7e(%rbx)
jne 0x4045
movq %r15, %rdi
xorl %esi, %esi
callq 0x306f
testl %eax, %eax
jne 0x3b6a
movq %rbx, %rdi
callq 0x5a4d
testl %eax, %eax
jne 0x3b6a
movl $0x10, %ebp
movq %rbx, %rdi
movl %ebp, %esi
callq 0x3884
xorl %r14d, %r14d
movl %r14d, %eax
addq $0x1b8, %rsp            # imm = 0x1B8
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq 0x20(%rbx), %rdi
leaq 0xb356(%rip), %rsi      # 0xf3dd
leaq 0xb356(%rip), %rdx      # 0xf3e4
movl $0xda3, %ecx            # imm = 0xDA3
callq 0xc43e