Support MDB_NOSYNC on mdb_txn_begin()
authorHoward Chu <hyc@openldap.org>
Fri, 30 Jan 2015 09:21:05 +0000 (09:21 +0000)
committerHoward Chu <hyc@openldap.org>
Fri, 30 Jan 2015 09:21:39 +0000 (09:21 +0000)
libraries/liblmdb/lmdb.h
libraries/liblmdb/mdb.c

index 4f85720..61318ff 100644 (file)
@@ -930,6 +930,8 @@ int  mdb_env_set_assert(MDB_env *env, MDB_assert_func *func);
         * <ul>
         *      <li>#MDB_RDONLY
         *              This transaction will not perform any write operations.
+        *      <li>#MDB_NOSYNC
+        *              Don't flush system buffers to disk when committing this transaction.
         * </ul>
         * @param[out] txn Address where the new #MDB_txn handle will be stored
         * @return A non-zero error value on failure and 0 on success. Some possible
index 7175276..984a5bd 100644 (file)
@@ -1084,6 +1084,7 @@ struct MDB_txn {
 #define MDB_TXN_ERROR          0x02            /**< txn is unusable after an error */
 #define MDB_TXN_DIRTY          0x04            /**< must write, even if dirty list is empty */
 #define MDB_TXN_SPILLS         0x08            /**< txn or a parent has spilled pages */
+#define MDB_TXN_NOSYNC         0x10            /**< don't sync this txn on commit */
 /** @} */
        unsigned int    mt_flags;               /**< @ref mdb_txn */
        /** #dirty_list room: Array size - \#dirty pages visible to this txn.
@@ -2755,6 +2756,8 @@ mdb_txn_begin(MDB_env *env, MDB_txn *parent, unsigned int flags, MDB_txn **ret)
                txn->mt_dbflags = (unsigned char *)(txn->mt_dbs + env->me_maxdbs);
                txn->mt_dbiseqs = env->me_dbiseqs;
        } else {
+               if (flags & MDB_NOSYNC)
+                       txn->mt_flags |= MDB_TXN_NOSYNC;
                txn->mt_cursors = (MDB_cursor **)(txn->mt_dbs + env->me_maxdbs);
                if (parent) {
                        txn->mt_dbiseqs = parent->mt_dbiseqs;
@@ -3486,9 +3489,12 @@ mdb_txn_commit(MDB_txn *txn)
        mdb_audit(txn);
 #endif
 
-       if ((rc = mdb_page_flush(txn, 0)) ||
-               (rc = mdb_env_sync(env, 0)) ||
-               (rc = mdb_env_write_meta(txn)))
+       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;
 
        /* Free P_LOOSE pages left behind in dirty_list */
@@ -3682,6 +3688,8 @@ mdb_env_write_meta(MDB_txn *txn)
                __sync_synchronize();
 #endif
                mp->mm_txnid = txn->mt_txnid;
+               if (F_ISSET(txn->mt_flags, MDB_TXN_NOSYNC))
+                       goto done;
                if (!(env->me_flags & (MDB_NOMETASYNC|MDB_NOSYNC))) {
                        unsigned meta_size = env->me_psize;
                        rc = (env->me_flags & MDB_MAPASYNC) ? MS_ASYNC : MS_SYNC;
@@ -3718,7 +3726,8 @@ mdb_env_write_meta(MDB_txn *txn)
        off += PAGEHDRSZ;
 
        /* Write to the SYNC fd */
-       mfd = env->me_flags & (MDB_NOSYNC|MDB_NOMETASYNC) ?
+       mfd = ((env->me_flags & (MDB_NOSYNC|MDB_NOMETASYNC)) ||
+               (txn->mt_flags & MDB_TXN_NOSYNC)) ?
                env->me_fd : env->me_mfd;
 #ifdef _WIN32
        {