MDB_db *me_dbs[2];
MDB_oldpages *me_pghead;
pthread_key_t me_txkey; /* thread-key for readers */
+ MDB_dpage *me_dpages;
pgno_t me_free_pgs[MDB_IDL_UM_SIZE];
MIDL2 me_dirty_list[MDB_IDL_DB_SIZE];
};
if (txn->mt_next_pgno + num >= txn->mt_env->me_maxpg)
return NULL;
}
- if ((dp = malloc(txn->mt_env->me_psize * num + sizeof(MDB_dhead))) == NULL)
- return NULL;
+ if (txn->mt_env->me_dpages && num == 1) {
+ dp = txn->mt_env->me_dpages;
+ txn->mt_env->me_dpages = (MDB_dpage *)dp->h.md_parent;
+ } else {
+ if ((dp = malloc(txn->mt_env->me_psize * num + sizeof(MDB_dhead))) == NULL)
+ return NULL;
+ }
dp->h.md_num = num;
dp->h.md_parent = parent;
dp->h.md_pi = parent_idx;
txn->mt_u.reader->mr_txnid = 0;
} else {
MDB_oldpages *mop;
+ MDB_dpage *dp;
unsigned int i;
- /* Discard all dirty pages. */
- for (i=1; i<=txn->mt_u.dirty_list[0].mid; i++)
- free(txn->mt_u.dirty_list[i].mptr);
+ /* return all dirty pages to dpage list */
+ for (i=1; i<=txn->mt_u.dirty_list[0].mid; i++) {
+ dp = txn->mt_u.dirty_list[i].mptr;
+ if (dp->h.md_num == 1) {
+ dp->h.md_parent = (MDB_page *)txn->mt_env->me_dpages;
+ txn->mt_env->me_dpages = dp;
+ } else {
+ /* large pages just get freed directly */
+ free(dp);
+ }
+ }
while ((mop = txn->mt_env->me_pghead)) {
txn->mt_env->me_pghead = mop->mo_next;
/* Drop the dirty pages.
*/
- for (i=1; i<=txn->mt_u.dirty_list[0].mid; i++)
- free(txn->mt_u.dirty_list[i].mptr);
+ for (i=1; i<=txn->mt_u.dirty_list[0].mid; i++) {
+ dp = txn->mt_u.dirty_list[i].mptr;
+ if (dp->h.md_num == 1) {
+ dp->h.md_parent = (MDB_page *)txn->mt_env->me_dpages;
+ txn->mt_env->me_dpages = dp;
+ } else {
+ free(dp);
+ }
+ txn->mt_u.dirty_list[i].mid = 0;
+ }
if ((n = mdb_env_sync(env, 0)) != 0 ||
(n = mdb_env_write_meta(txn)) != MDB_SUCCESS) {
void
mdb_env_close(MDB_env *env)
{
+ MDB_dpage *dp;
+
if (env == NULL)
return;
+ while (env->me_dpages) {
+ dp = env->me_dpages;
+ env->me_dpages = (MDB_dpage *)dp->h.md_parent;
+ free(dp);
+ }
+
free(env->me_dbs[1]);
free(env->me_dbs[0]);
free(env->me_dbxs);