ITS#8756 remove loose pg from dirty list in freelist_save

mdb.RE/0.9
Howard Chu 7 years ago
parent 9e859dd1ca
commit 1f33a6d910
  1. 33
      libraries/liblmdb/mdb.c

@ -3094,10 +3094,41 @@ mdb_freelist_save(MDB_txn *txn)
* we may be unable to return them to me_pghead. * we may be unable to return them to me_pghead.
*/ */
MDB_page *mp = txn->mt_loose_pgs; MDB_page *mp = txn->mt_loose_pgs;
MDB_ID2 *dl = txn->mt_u.dirty_list;
unsigned x;
if ((rc = mdb_midl_need(&txn->mt_free_pgs, txn->mt_loose_count)) != 0) if ((rc = mdb_midl_need(&txn->mt_free_pgs, txn->mt_loose_count)) != 0)
return rc; return rc;
for (; mp; mp = NEXT_LOOSE_PAGE(mp)) for (; mp; mp = NEXT_LOOSE_PAGE(mp)) {
mdb_midl_xappend(txn->mt_free_pgs, mp->mp_pgno); mdb_midl_xappend(txn->mt_free_pgs, mp->mp_pgno);
/* must also remove from dirty list */
if (txn->mt_flags & MDB_TXN_WRITEMAP) {
for (x=1; x<=dl[0].mid; x++)
if (dl[x].mid == mp->mp_pgno)
break;
mdb_tassert(txn, x <= dl[0].mid);
} else {
x = mdb_mid2l_search(dl, mp->mp_pgno);
mdb_tassert(txn, dl[x].mid == mp->mp_pgno);
}
dl[x].mptr = NULL;
mdb_dpage_free(env, mp);
}
{
/* squash freed slots out of the dirty list */
unsigned y;
for (y=1; dl[y].mptr && y <= dl[0].mid; y++);
if (y <= dl[0].mid) {
for(x=y, y++;;) {
while (!dl[y].mptr && y <= dl[0].mid) y++;
if (y > dl[0].mid) break;
dl[x++] = dl[y++];
}
dl[0].mid = x-1;
} else {
/* all slots freed */
dl[0].mid = 0;
}
}
txn->mt_loose_pgs = NULL; txn->mt_loose_pgs = NULL;
txn->mt_loose_count = 0; txn->mt_loose_count = 0;
} }

Loading…
Cancel
Save