From c3547e81f3fcefac2dc66f8dfff64025eb41cc36 Mon Sep 17 00:00:00 2001 From: Hallvard Furuseth Date: Thu, 8 Aug 2013 19:57:51 +0200 Subject: [PATCH] Fix page spilling when MDB_WRITEMAP. mdb_page_spill(): Don't binary-search the unsorted dirty_list. mdb_page_flush(): Don't overwrite unprocessed dirty_list items. --- libraries/liblmdb/mdb.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/libraries/liblmdb/mdb.c b/libraries/liblmdb/mdb.c index aeaf4df..46df800 100644 --- a/libraries/liblmdb/mdb.c +++ b/libraries/liblmdb/mdb.c @@ -1434,7 +1434,7 @@ mdb_page_spill(MDB_cursor *m0, MDB_val *key, MDB_val *data) MDB_page *dp; MDB_ID2L dl = txn->mt_u.dirty_list; unsigned int i, j; - int rc; + int rc, level; if (m0->mc_flags & C_SUB) return MDB_SUCCESS; @@ -1461,11 +1461,13 @@ mdb_page_spill(MDB_cursor *m0, MDB_val *key, MDB_val *data) /* Mark all the dirty root pages we want to preserve */ for (i=0; imt_numdbs; i++) { if (txn->mt_dbflags[i] & DB_DIRTY) { - j = mdb_mid2l_search(dl, txn->mt_dbs[i].md_root); - if (j <= dl[0].mid) { - dp = dl[j].mptr; + pgno_t pgno = txn->mt_dbs[i].md_root; + if (pgno == P_INVALID) + continue; + if ((rc = mdb_page_get(txn, pgno, &dp, &level)) != MDB_SUCCESS) + goto done; + if ((dp->mp_flags & P_DIRTY) && level <= 1) dp->mp_flags |= P_KEEP; - } } } @@ -2592,7 +2594,7 @@ mdb_page_flush(MDB_txn *txn) j = 0; if (env->me_flags & MDB_WRITEMAP) { /* Clear dirty flags */ - for (i = pagecount; i; i--) { + for (i=1; i<=pagecount; i++) { dp = dl[i].mptr; /* Don't flush this page yet */ if (dp->mp_flags & P_KEEP) {