// File: /workspace/github_cpp_makefile_star2_O3/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 0x3b31
movq %rdi, %rbx
movq 0x8(%rdi), %rdi
testq %rdi, %rdi
je 0x3afb
callq 0x3acc
testl %eax, %eax
je 0x3afb
movl %eax, %ebp
jmp 0x3b24
movl 0x7c(%rbx), %eax
movl $0x200031, %r15d        # imm = 0x200031
btl $0x11, %eax
jb 0x3dda
movq (%rbx), %r14
testb $0x3, %al
je 0x3b3b
movl $0xffff87c2, %ebp       # imm = 0xFFFF87C2
testq %r14, %r14
je 0x3b24
orb $0x2, 0x7c(%r14)
movq %rbx, %rdi
callq 0x3aa6
jmp 0x3de7
movl $0x16, %ebp
jmp 0x3de7
testq %r14, %r14
je 0x3c8f
leaq 0x28(%r14), %rdi
movq 0x28(%rbx), %rsi
callq 0xbb5d
testl %eax, %eax
jne 0x3af7
movq 0x28(%rbx), %rdi
callq 0xba29
movq 0x10(%rbx), %rax
movq %rax, 0x10(%r14)
movl 0x7c(%rbx), %eax
movl %eax, 0x7c(%r14)
movq 0x68(%rbx), %rdi
movl 0x78(%rbx), %esi
movl $0x1, %edx
callq 0x3fe7
movq 0x58(%r14), %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(%r14)
movq 0x70(%rbx), %rax
movb (%rax), %al
movq 0x70(%r14), %rcx
movb %al, (%rcx)
movq 0x70(%rbx), %rax
movb 0x1(%rax), %al
movq 0x70(%r14), %rcx
movb %al, 0x1(%rcx)
cmpl $0x3, 0x78(%rbx)
jb 0x3be1
movl $0x2, %eax
movq 0x70(%r14), %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 0x3bc2
movq 0x40(%r14), %rax
movq 0x48(%r14), %r15
movq 0x48(%rbx), %rdi
testq %rax, %rax
movq %rdi, 0x8(%rsp)
je 0x3e00
movl (%rax), %ecx
testl %ecx, %ecx
je 0x3e00
movq $-0x1, (%rax)
movl (%rdi), %r8d
movl %ecx, %edx
testl %r8d, %r8d
je 0x3c6d
incl %r8d
cmpl $0x3, %r8d
movl $0x2, %esi
cmovael %r8d, %esi
movl $0x1, %r12d
movl %ecx, %edx
movl %ecx, %r8d
movq %r12, %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 0x3c3f
jne 0x3c5d
movq $0x1, (%rax,%r10,8)
movl %r8d, %edx
jmp 0x3c60
incl %r8d
incq %r12
cmpq %rsi, %r12
movq 0x8(%rsp), %rdi
jne 0x3c31
leal 0x1(%rdx), %esi
cmpl %ecx, %esi
ja 0x3dfb
movl %esi, %r8d
movq (%rax,%r8,8), %r8
testb $0x1, %r8b
jne 0x3c8b
incl %edx
movq %r8, (%rax,%rdx,8)
incl %esi
jmp 0x3c70
movq 0x20(%rbx), %r14
movl $0x16, %ebp
cmpq %rbx, 0x60(%r14)
jne 0x3b24
movq 0x68(%rbx), %rdi
movl 0x78(%rbx), %esi
xorl %edx, %edx
callq 0x3fe7
movq 0x48(%rbx), %rax
cmpq $0x0, (%rax)
jne 0x3cc4
testb $0xc, 0x7c(%rbx)
je 0x3dda
cmpl $0x3, 0x78(%rbx)
jb 0x3d6a
movq $0x30, 0x20(%rsp)
leaq 0x30(%rsp), %rdi
movq %rbx, %rsi
movl $0x1, %edx
xorl %ecx, %ecx
callq 0x40be
movl 0x78(%rbx), %eax
cmpl $0x3, %eax
jb 0x3d6a
movl $0x2, %r13d
movl $0x60, %r15d
leaq 0x20(%rsp), %r12
movq 0x70(%rbx), %rcx
testb $0x1, (%rcx,%r13)
je 0x3d5c
movq 0x20(%rbx), %rax
movq 0x60(%rbx), %rcx
movl (%rcx,%r13,4), %ecx
movq 0x98(%rax), %rax
cmpl (%rax,%r13,4), %ecx
jne 0x3fc1
movq 0x58(%rbx), %rax
addq %r15, %rax
movq %rax, 0x28(%rsp)
movq 0x50(%rbx), %rsi
addq %r15, %rsi
leaq 0x30(%rsp), %rdi
movq %r12, %rdx
movl $0x2, %ecx
callq 0x41b9
testl %eax, %eax
jne 0x3af7
movl 0x78(%rbx), %eax
incq %r13
movl %eax, %ecx
addq $0x30, %r15
cmpq %rcx, %r13
jb 0x3d04
movq %rbx, %rdi
callq 0x4f8c
testl %eax, %eax
jne 0x3af7
movq 0xb0(%r14), %rdi
callq 0xba29
movq $0x0, 0xb0(%r14)
leaq 0x28(%rbx), %rdi
callq 0xba38
movq %rbx, %rdi
xorl %esi, %esi
callq 0x54a6
testl %eax, %eax
jne 0x3af7
testb $0x1, 0x7e(%rbx)
jne 0x3dc4
movq %r14, %rdi
xorl %esi, %esi
callq 0x305f
testl %eax, %eax
jne 0x3af7
movq %rbx, %rdi
callq 0x5833
testl %eax, %eax
jne 0x3af7
movl $0x10, %r15d
movq %rbx, %rdi
movl %r15d, %esi
callq 0x380d
xorl %ebp, %ebp
movl %ebp, %eax
addq $0x1b8, %rsp            # imm = 0x1B8
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movl %edx, %ecx
movq %rcx, (%rax)
movq (%r15), %r13
movq $0x0, (%r15)
cmpq $0x0, (%r14)
je 0x3e6c
movl %r13d, %ebp
addl (%rdi), %ebp
movl %r13d, %eax
shlq $0x4, %rax
movq (%r15,%rax), %rsi
incq %rsi
callq 0xbea3
decl %eax
je 0x3e79
testl %r13d, %r13d
je 0x3e79
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 0x3e47
sete %cl
movzbl %cl, %ecx
subl %ecx, %ebp
decl %eax
je 0x3e7e
negl %ecx
subl %edx, %ecx
jne 0x3e39
jmp 0x3e7e
movl $0x1ffff, %ebp          # imm = 0x1FFFF
subl 0x80(%rbx), %ebp
jmp 0x3e7e
movq 0x8(%rsp), %rdi
movq %r14, 0x18(%rsp)
movl (%rdi), %r14d
testq %r14, %r14
movl %ebp, 0x14(%rsp)
je 0x3f1a
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 0x3ede
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 0x3eb4
cmpq %rsi, %rax
jne 0x3ef9
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 0x3e93
cmpl %r13d, %ebp
jne 0x3fcb
movl 0x14(%rsp), %eax
movq %rax, (%r15)
movq 0x48(%rbx), %rdi
callq 0x2030
movl 0x80(%rbx), %eax
movq 0x18(%rsp), %r15
movl %eax, 0x80(%r15)
movq 0x40(%rbx), %rsi
xorl %ebp, %ebp
testq %rsi, %rsi
je 0x3f83
leaq 0x40(%r15), %r14
cmpq $0x0, (%r14)
je 0x3f80
movq %r14, %rdi
callq 0xbb5d
movl %eax, %ebp
testl %eax, %eax
je 0x3f6d
orb $0x2, 0x7c(%r15)
movq 0x40(%rbx), %rdi
callq 0xba29
movq (%r14), %rdi
callq 0xbd0b
jmp 0x3f83
movq %rsi, (%r14)
leaq 0x30(%r15), %rax
cmpq $0x0, (%rax)
leaq 0x10(%rax), %rax
jne 0x3f87
movq 0x30(%rbx), %rcx
movq %rcx, -0x10(%rax)
movl 0x38(%rbx), %eax
addl %eax, 0x38(%r15)
movq $0x0, 0x8(%r15)
movq 0x88(%rbx), %rdi
callq 0xba29
movq %rbx, %rdi
callq 0x2030
jmp 0x3de7
movl $0xffff87c4, %ebp       # imm = 0xFFFF87C4
jmp 0x3b24
movq 0x20(%rbx), %rdi
leaq 0xb447(%rip), %rsi      # 0xf41d
leaq 0xb447(%rip), %rdx      # 0xf424
movl $0xda3, %ecx            # imm = 0xDA3
callq 0xbfbd