]> git.sur5r.net Git - openldap/commitdiff
Add txn_reset / txn_renew
authorHoward Chu <hyc@symas.com>
Wed, 24 Aug 2011 08:45:42 +0000 (01:45 -0700)
committerHoward Chu <hyc@symas.com>
Thu, 1 Sep 2011 23:31:10 +0000 (16:31 -0700)
libraries/libmdb/mdb.c
libraries/libmdb/mdb.h

index bd39a203f2b9fc8dec91b0a96ad125dc61ddf1e5..291bd22bfc1214bb338dad6442a00a2496129d3d 100644 (file)
@@ -703,24 +703,22 @@ mdb_env_sync(MDB_env *env, int force)
        return rc;
 }
 
-int
-mdb_txn_begin(MDB_env *env, int rdonly, MDB_txn **ret)
+static inline void
+mdb_txn_reset0(MDB_txn *txn);
+
+static inline int
+mdb_txn_renew0(MDB_txn *txn)
 {
-       MDB_txn *txn;
+       MDB_env *env = txn->mt_env;
+
        int rc, toggle;
 
        if (env->me_flags & MDB_FATAL_ERROR) {
                DPUTS("mdb_txn_begin: environment had fatal error, must shutdown!");
                return MDB_PANIC;
        }
-       if ((txn = calloc(1, sizeof(MDB_txn))) == NULL) {
-               DPRINTF("calloc: %s", strerror(errno));
-               return ENOMEM;
-       }
 
-       if (rdonly) {
-               txn->mt_flags |= MDB_TXN_RDONLY;
-       } else {
+       if (!(txn->mt_flags & MDB_TXN_RDONLY)) {
                txn->mt_u.dirty_list = env->me_dirty_list;
                txn->mt_u.dirty_list[0].mid = 0;
                txn->mt_free_pgs = env->me_free_pgs;
@@ -731,7 +729,8 @@ mdb_txn_begin(MDB_env *env, int rdonly, MDB_txn **ret)
        }
 
        txn->mt_txnid = env->me_txns->mti_txnid;
-       if (rdonly) {
+
+       if (txn->mt_flags & MDB_TXN_RDONLY) {
                MDB_reader *r = pthread_getspecific(env->me_txkey);
                if (!r) {
                        unsigned int i;
@@ -757,24 +756,21 @@ mdb_txn_begin(MDB_env *env, int rdonly, MDB_txn **ret)
                env->me_txn = txn;
        }
 
-       txn->mt_env = env;
-
        toggle = env->me_txns->mti_me_toggle;
        if ((rc = mdb_env_read_meta(env, &toggle)) != MDB_SUCCESS) {
-               mdb_txn_abort(txn);
+               mdb_txn_reset0(txn);
                return rc;
        }
 
        /* Copy the DB arrays */
        txn->mt_numdbs = env->me_numdbs;
        txn->mt_dbxs = env->me_dbxs;    /* mostly static anyway */
-       txn->mt_dbs = malloc(env->me_maxdbs * sizeof(MDB_db));
        memcpy(txn->mt_dbs, env->me_meta->mm_dbs, 2 * sizeof(MDB_db));
        if (txn->mt_numdbs > 2)
                memcpy(txn->mt_dbs+2, env->me_dbs[env->me_db_toggle]+2,
                        (txn->mt_numdbs - 2) * sizeof(MDB_db));
 
-       if (!rdonly) {
+       if (!(txn->mt_flags & MDB_TXN_RDONLY)) {
                if (toggle)
                        txn->mt_flags |= MDB_TXN_METOGGLE;
                txn->mt_next_pgno = env->me_meta->mm_last_pg+1;
@@ -783,23 +779,63 @@ mdb_txn_begin(MDB_env *env, int rdonly, MDB_txn **ret)
        DPRINTF("begin transaction %lu on mdbenv %p, root page %lu",
                txn->mt_txnid, (void *) env, txn->mt_dbs[MAIN_DBI].md_root);
 
-       *ret = txn;
        return MDB_SUCCESS;
 }
 
-void
-mdb_txn_abort(MDB_txn *txn)
+int
+mdb_txn_renew(MDB_txn *txn)
 {
-       MDB_env *env;
+       int rc;
 
-       if (txn == NULL)
-               return;
+       if (!txn)
+               return EINVAL;
 
-       env = txn->mt_env;
-       DPRINTF("abort transaction %lu on mdbenv %p, root page %lu",
-               txn->mt_txnid, (void *) env, txn->mt_dbs[MAIN_DBI].md_root);
+       rc = mdb_txn_renew0(txn);
+       if (rc == MDB_SUCCESS) {
+               DPRINTF("reset txn %p %lu%c on mdbenv %p, root page %lu", txn,
+                       txn->mt_txnid, (txn->mt_flags & MDB_TXN_RDONLY) ? 'r' : 'w',
+                       (void *)txn->mt_env, txn->mt_dbs[MAIN_DBI].md_root);
+       }
+       return rc;
+}
 
-       free(txn->mt_dbs);
+int
+mdb_txn_begin(MDB_env *env, int rdonly, MDB_txn **ret)
+{
+       MDB_txn *txn;
+       int rc;
+
+       if (env->me_flags & MDB_FATAL_ERROR) {
+               DPUTS("mdb_txn_begin: environment had fatal error, must shutdown!");
+               return MDB_PANIC;
+       }
+       if ((txn = calloc(1, sizeof(MDB_txn) + env->me_maxdbs * sizeof(MDB_db))) == NULL) {
+               DPRINTF("calloc: %s", strerror(errno));
+               return ENOMEM;
+       }
+       txn->mt_dbs = (MDB_db *)(txn+1);
+       if (rdonly) {
+               txn->mt_flags |= MDB_TXN_RDONLY;
+       }
+       txn->mt_env = env;
+
+       rc = mdb_txn_renew0(txn);
+       if (rc)
+               free(txn);
+       else {
+               *ret = txn;
+               DPRINTF("begin txn %p %lu%c on mdbenv %p, root page %lu", txn,
+                       txn->mt_txnid, (txn->mt_flags & MDB_TXN_RDONLY) ? 'r' : 'w',
+                       (void *) env, txn->mt_dbs[MAIN_DBI].md_root);
+       }
+
+       return rc;
+}
+
+static inline void
+mdb_txn_reset0(MDB_txn *txn)
+{
+       MDB_env *env = txn->mt_env;
 
        if (F_ISSET(txn->mt_flags, MDB_TXN_RDONLY)) {
                txn->mt_u.reader->mr_txnid = 0;
@@ -831,7 +867,32 @@ mdb_txn_abort(MDB_txn *txn)
                        env->me_dbxs[i].md_dirty = 0;
                pthread_mutex_unlock(&env->me_txns->mti_wmutex);
        }
+}
+
+void
+mdb_txn_reset(MDB_txn *txn)
+{
+       if (txn == NULL)
+               return;
+
+       DPRINTF("reset txn %p %lu%c on mdbenv %p, root page %lu", txn,
+               txn->mt_txnid, (txn->mt_flags & MDB_TXN_RDONLY) ? 'r' : 'w',
+               (void *)txn->mt_env, txn->mt_dbs[MAIN_DBI].md_root);
+
+       mdb_txn_reset0(txn);
+}
 
+void
+mdb_txn_abort(MDB_txn *txn)
+{
+       if (txn == NULL)
+               return;
+
+       DPRINTF("abort txn %p %lu%c on mdbenv %p, root page %lu", txn,
+               txn->mt_txnid, (txn->mt_flags & MDB_TXN_RDONLY) ? 'r' : 'w',
+               (void *)txn->mt_env, txn->mt_dbs[MAIN_DBI].md_root);
+
+       mdb_txn_reset0(txn);
        free(txn);
 }
 
@@ -1032,8 +1093,6 @@ done:
                }
                env->me_db_toggle = toggle;
                env->me_numdbs = txn->mt_numdbs;
-
-               free(txn->mt_dbs);
        }
 
        pthread_mutex_unlock(&env->me_txns->mti_wmutex);
index 5e679c55cee8212526d88a8c359becbaae44a73e..bb52dbecf6de225c351b753df6b946a9ba134ebd 100644 (file)
@@ -135,6 +135,8 @@ int  mdb_env_set_maxdbs(MDB_env *env, int dbs);
 int  mdb_txn_begin(MDB_env *env, int rdonly, MDB_txn **txn);
 int  mdb_txn_commit(MDB_txn *txn);
 void mdb_txn_abort(MDB_txn *txn);
+void mdb_txn_reset(MDB_txn *txn);      /* like abort, but doesn't free TXN */
+int  mdb_txn_renew(MDB_txn *txn);      /* like begin, but doesn't alloc TXN */
 
 int  mdb_open(MDB_txn *txn, const char *name, unsigned int flags, MDB_dbi *dbi);
 int  mdb_stat(MDB_txn *txn, MDB_dbi dbi, MDB_stat *stat);