]> git.sur5r.net Git - openldap/blobdiff - libraries/liblmdb/mdb.c
Wrap __func__ in mdb_func_
[openldap] / libraries / liblmdb / mdb.c
index cd3805a880fcbffebd4c66277f13b33a55cf0394..a61dba26a54ee808100c699c52909329d894ccba 100644 (file)
 /** @defgroup internal MDB Internals
  *     @{
  */
-/** @defgroup compat   Windows Compatibility Macros
+/** @defgroup compat   Compatibility Macros
  *     A bunch of macros to minimize the amount of platform-specific ifdefs
  *     needed throughout the rest of the code. When the features this library
  *     needs are similar enough to POSIX to be hidden in a one-or-two line
  *     replacement, this macro approach is used.
  *     @{
  */
+
+       /** Wrapper around __func__, which is a C99 feature */
+#if __STDC_VERSION__ >= 199901L
+# define mdb_func_     __func__
+#elif __GNUC__ >= 2 || _MSC_VER >= 1300
+# define mdb_func_     __FUNCTION__
+#else
+/* If a debug message says <mdb_unknown>(), update the #if statements above */
+# define mdb_func_     "<mdb_unknown>"
+#endif
+
 #ifdef _WIN32
 #define MDB_USE_HASH   1
 #define MDB_PIDLOCK    0
@@ -327,7 +338,7 @@ static txnid_t mdb_debug_start;
         */
 # define DPRINTF(args) ((void) ((mdb_debug) && DPRINTF0 args))
 # define DPRINTF0(fmt, ...) \
-       fprintf(stderr, "%s:%d " fmt "\n", __func__, __LINE__, __VA_ARGS__)
+       fprintf(stderr, "%s:%d " fmt "\n", mdb_func_, __LINE__, __VA_ARGS__)
 #else
 # define DPRINTF(args) ((void) 0)
 #endif
@@ -1205,6 +1216,15 @@ mdb_strerror(int err)
 }
 
 #if MDB_DEBUG
+/** Return the page number of \b mp which may be sub-page, for debug output */
+static pgno_t
+mdb_dbg_pgno(MDB_page *mp)
+{
+       pgno_t ret;
+       COPY_PGNO(ret, mp->mp_pgno);
+       return ret;
+}
+
 /** Display a key in hexadecimal and return the address of the result.
  * @param[in] key the key to display
  * @param[in] buf the buffer to write into. Should always be #DKBUF.
@@ -1245,7 +1265,7 @@ mdb_page_list(MDB_page *mp)
        DKBUF;
 
        nkeys = NUMKEYS(mp);
-       fprintf(stderr, "Page %"Z"u numkeys %d\n", mp->mp_pgno, nkeys);
+       fprintf(stderr, "Page %"Z"u numkeys %d\n", mdb_dbg_pgno(mp), nkeys);
        for (i=0; i<nkeys; i++) {
                node = NODEPTR(mp, i);
                key.mv_size = node->mn_ksize;
@@ -1380,11 +1400,11 @@ mdb_page_malloc(MDB_txn *txn, unsigned num)
                off = sz - psize;
        }
        if ((ret = malloc(sz)) != NULL) {
+               VGMEMP_ALLOC(env, ret, sz);
                if (!(env->me_flags & MDB_NOMEMINIT)) {
                        memset((char *)ret + off, 0, psize);
                        ret->mp_pad = 0;
                }
-               VGMEMP_ALLOC(env, ret, sz);
        }
        return ret;
 }
@@ -2825,8 +2845,8 @@ mdb_txn_commit(MDB_txn *txn)
        unsigned int i;
        MDB_env *env;
 
-       assert(txn != NULL);
-       assert(txn->mt_env != NULL);
+       if (txn == NULL || txn->mt_env == NULL)
+               return EINVAL;
 
        if (txn->mt_child) {
                rc = mdb_txn_commit(txn->mt_child);
@@ -3167,9 +3187,6 @@ mdb_env_write_meta(MDB_txn *txn)
        int r2;
 #endif
 
-       assert(txn != NULL);
-       assert(txn->mt_env != NULL);
-
        toggle = txn->mt_txnid & 1;
        DPRINTF(("writing meta page %d for root page %"Z"u",
                toggle, txn->mt_dbs[MAIN_DBI].md_root));
@@ -4499,15 +4516,9 @@ mdb_node_search(MDB_cursor *mc, MDB_val *key, int *exactp)
 
        nkeys = NUMKEYS(mp);
 
-#if MDB_DEBUG
-       {
-       pgno_t pgno;
-       COPY_PGNO(pgno, mp->mp_pgno);
        DPRINTF(("searching %u keys in %s %spage %"Z"u",
            nkeys, IS_LEAF(mp) ? "leaf" : "branch", IS_SUBP(mp) ? "sub-" : "",
-           pgno));
-       }
-#endif
+           mdb_dbg_pgno(mp)));
 
        low = IS_LEAF(mp) ? 0 : 1;
        high = nkeys - 1;
@@ -4621,7 +4632,7 @@ mdb_cursor_push(MDB_cursor *mc, MDB_page *mp)
                DDBI(mc), (void *) mc));
 
        if (mc->mc_snum >= CURSOR_STACK) {
-               assert(mc->mc_snum < CURSOR_STACK);
+               mc->mc_txn->mt_flags |= MDB_TXN_ERROR;
                return MDB_CURSOR_FULL;
        }
 
@@ -4681,7 +4692,7 @@ mdb_page_get(MDB_txn *txn, pgno_t pgno, MDB_page **ret, int *lvl)
                p = (MDB_page *)(env->me_map + env->me_psize * pgno);
        } else {
                DPRINTF(("page %"Z"u not found", pgno));
-               assert(p != NULL);
+               txn->mt_flags |= MDB_TXN_ERROR;
                return MDB_PAGE_NOTFOUND;
        }
 
@@ -4749,6 +4760,7 @@ mdb_page_search_root(MDB_cursor *mc, MDB_val *key, int flags)
        if (!IS_LEAF(mp)) {
                DPRINTF(("internal error, index points to a %02X page!?",
                    mp->mp_flags));
+               mc->mc_txn->mt_flags |= MDB_TXN_ERROR;
                return MDB_CORRUPTED;
        }
 
@@ -4981,8 +4993,9 @@ mdb_get(MDB_txn *txn, MDB_dbi dbi,
        int exact = 0;
        DKBUF;
 
-       assert(key);
-       assert(data);
+       if (key == NULL || data == NULL)
+               return EINVAL;
+
        DPRINTF(("===> get db %u key [%s]", dbi, DKEY(key)));
 
        if (txn == NULL || !dbi || dbi >= txn->mt_numdbs || !(txn->mt_dbflags[dbi] & DB_VALID))
@@ -5086,7 +5099,8 @@ mdb_cursor_next(MDB_cursor *mc, MDB_val *key, MDB_val *data, MDB_cursor_op op)
                }
        }
 
-       DPRINTF(("cursor_next: top page is %"Z"u in cursor %p", mp->mp_pgno, (void *) mc));
+       DPRINTF(("cursor_next: top page is %"Z"u in cursor %p",
+               mdb_dbg_pgno(mp), (void *) mc));
        if (mc->mc_flags & C_DEL)
                goto skip;
 
@@ -5103,7 +5117,7 @@ mdb_cursor_next(MDB_cursor *mc, MDB_val *key, MDB_val *data, MDB_cursor_op op)
 
 skip:
        DPRINTF(("==> cursor points to page %"Z"u with %u keys, key index %u",
-           mp->mp_pgno, NUMKEYS(mp), mc->mc_ki[mc->mc_top]));
+           mdb_dbg_pgno(mp), NUMKEYS(mp), mc->mc_ki[mc->mc_top]));
 
        if (IS_LEAF2(mp)) {
                key->mv_size = mc->mc_db->md_pad;
@@ -5162,7 +5176,8 @@ mdb_cursor_prev(MDB_cursor *mc, MDB_val *key, MDB_val *data, MDB_cursor_op op)
                }
        }
 
-       DPRINTF(("cursor_prev: top page is %"Z"u in cursor %p", mp->mp_pgno, (void *) mc));
+       DPRINTF(("cursor_prev: top page is %"Z"u in cursor %p",
+               mdb_dbg_pgno(mp), (void *) mc));
 
        if (mc->mc_ki[mc->mc_top] == 0)  {
                DPUTS("=====> move to prev sibling page");
@@ -5178,7 +5193,7 @@ mdb_cursor_prev(MDB_cursor *mc, MDB_val *key, MDB_val *data, MDB_cursor_op op)
        mc->mc_flags &= ~C_EOF;
 
        DPRINTF(("==> cursor points to page %"Z"u with %u keys, key index %u",
-           mp->mp_pgno, NUMKEYS(mp), mc->mc_ki[mc->mc_top]));
+           mdb_dbg_pgno(mp), NUMKEYS(mp), mc->mc_ki[mc->mc_top]));
 
        if (IS_LEAF2(mp)) {
                key->mv_size = mc->mc_db->md_pad;
@@ -5494,7 +5509,8 @@ mdb_cursor_get(MDB_cursor *mc, MDB_val *key, MDB_val *data,
        int              exact = 0;
        int              (*mfunc)(MDB_cursor *mc, MDB_val *key, MDB_val *data);
 
-       assert(mc);
+       if (mc == NULL)
+               return EINVAL;
 
        if (mc->mc_txn->mt_flags & MDB_TXN_ERROR)
                return MDB_BAD_TXN;
@@ -6351,7 +6367,7 @@ mdb_node_add(MDB_cursor *mc, indx_t indx,
        DPRINTF(("add to %s %spage %"Z"u index %i, data size %"Z"u key size %"Z"u [%s]",
            IS_LEAF(mp) ? "leaf" : "branch",
                IS_SUBP(mp) ? "sub-" : "",
-           mp->mp_pgno, indx, data ? data->mv_size : 0,
+               mdb_dbg_pgno(mp), indx, data ? data->mv_size : 0,
                key ? key->mv_size : 0, key ? DKEY(key) : "null"));
 
        if (IS_LEAF2(mp)) {
@@ -6449,9 +6465,10 @@ update:
 
 full:
        DPRINTF(("not enough room in page %"Z"u, got %u ptrs",
-               mp->mp_pgno, NUMKEYS(mp)));
+               mdb_dbg_pgno(mp), NUMKEYS(mp)));
        DPRINTF(("upper-lower = %u - %u = %"Z"d", mp->mp_upper,mp->mp_lower,room));
        DPRINTF(("node size = %"Z"u", node_size));
+       mc->mc_txn->mt_flags |= MDB_TXN_ERROR;
        return MDB_PAGE_FULL;
 }
 
@@ -6469,14 +6486,8 @@ mdb_node_del(MDB_page *mp, indx_t indx, int ksize)
        MDB_node        *node;
        char            *base;
 
-#if MDB_DEBUG
-       {
-       pgno_t pgno;
-       COPY_PGNO(pgno, mp->mp_pgno);
        DPRINTF(("delete node %u on %s page %"Z"u", indx,
-           IS_LEAF(mp) ? "leaf" : "branch", pgno));
-       }
-#endif
+           IS_LEAF(mp) ? "leaf" : "branch", mdb_dbg_pgno(mp)));
        assert(indx < NUMKEYS(mp));
 
        if (IS_LEAF2(mp)) {
@@ -7184,25 +7195,15 @@ mdb_rebalance(MDB_cursor *mc)
        MDB_cursor      mn;
 
        minkeys = 1 + (IS_BRANCH(mc->mc_pg[mc->mc_top]));
-#if MDB_DEBUG
-       {
-       pgno_t pgno;
-       COPY_PGNO(pgno, mc->mc_pg[mc->mc_top]->mp_pgno);
        DPRINTF(("rebalancing %s page %"Z"u (has %u keys, %.1f%% full)",
            IS_LEAF(mc->mc_pg[mc->mc_top]) ? "leaf" : "branch",
-           pgno, NUMKEYS(mc->mc_pg[mc->mc_top]),
+           mdb_dbg_pgno(mc->mc_pg[mc->mc_top]), NUMKEYS(mc->mc_pg[mc->mc_top]),
                (float)PAGEFILL(mc->mc_txn->mt_env, mc->mc_pg[mc->mc_top]) / 10));
-       }
-#endif
 
        if (PAGEFILL(mc->mc_txn->mt_env, mc->mc_pg[mc->mc_top]) >= FILL_THRESHOLD &&
                NUMKEYS(mc->mc_pg[mc->mc_top]) >= minkeys) {
-#if MDB_DEBUG
-               pgno_t pgno;
-               COPY_PGNO(pgno, mc->mc_pg[mc->mc_top]->mp_pgno);
                DPRINTF(("no need to rebalance page %"Z"u, above fill threshold",
-                   pgno));
-#endif
+                   mdb_dbg_pgno(mc->mc_pg[mc->mc_top])));
                return MDB_SUCCESS;
        }
 
@@ -7372,7 +7373,7 @@ mdb_cursor_del0(MDB_cursor *mc, MDB_node *leaf)
        if (rc != MDB_SUCCESS)
                mc->mc_txn->mt_flags |= MDB_TXN_ERROR;
        else {
-               MDB_cursor *m2;
+               MDB_cursor *m2, *m3;
                MDB_dbi dbi = mc->mc_dbi;
 
                mp = mc->mc_pg[mc->mc_top];
@@ -7384,18 +7385,19 @@ mdb_cursor_del0(MDB_cursor *mc, MDB_node *leaf)
 
                /* Adjust other cursors pointing to mp */
                for (m2 = mc->mc_txn->mt_cursors[dbi]; m2; m2=m2->mc_next) {
-                       if (m2 == mc || m2->mc_snum < mc->mc_snum)
+                       m3 = (mc->mc_flags & C_SUB) ? &m2->mc_xcursor->mx_cursor : m2;
+                       if (! (m2->mc_flags & m3->mc_flags & C_INITIALIZED))
                                continue;
-                       if (!(m2->mc_flags & C_INITIALIZED))
+                       if (m3 == mc || m3->mc_snum < mc->mc_snum)
                                continue;
-                       if (m2->mc_pg[mc->mc_top] == mp) {
-                               if (m2->mc_ki[mc->mc_top] >= ki) {
-                                       m2->mc_flags |= C_DEL;
-                                       if (m2->mc_ki[mc->mc_top] > ki)
-                                               m2->mc_ki[mc->mc_top]--;
+                       if (m3->mc_pg[mc->mc_top] == mp) {
+                               if (m3->mc_ki[mc->mc_top] >= ki) {
+                                       m3->mc_flags |= C_DEL;
+                                       if (m3->mc_ki[mc->mc_top] > ki)
+                                               m3->mc_ki[mc->mc_top]--;
                                }
-                               if (m2->mc_ki[mc->mc_top] >= nkeys)
-                                       mdb_cursor_sibling(m2, 1);
+                               if (m3->mc_ki[mc->mc_top] >= nkeys)
+                                       mdb_cursor_sibling(m3, 1);
                        }
                }
                mc->mc_flags |= C_DEL;
@@ -7415,7 +7417,8 @@ mdb_del(MDB_txn *txn, MDB_dbi dbi,
        int              rc, exact;
        DKBUF;
 
-       assert(key != NULL);
+       if (key == NULL)
+               return EINVAL;
 
        DPRINTF(("====> delete db %u key [%s]", dbi, DKEY(key)));
 
@@ -7860,8 +7863,8 @@ mdb_put(MDB_txn *txn, MDB_dbi dbi,
        MDB_cursor mc;
        MDB_xcursor mx;
 
-       assert(key != NULL);
-       assert(data != NULL);
+       if (key == NULL || data == NULL)
+               return EINVAL;
 
        if (txn == NULL || !dbi || dbi >= txn->mt_numdbs || !(txn->mt_dbflags[dbi] & DB_VALID))
                return EINVAL;
@@ -8314,13 +8317,10 @@ int mdb_reader_list(MDB_env *env, MDB_msg_func *func, void *ctx)
        mr = env->me_txns->mti_readers;
        for (i=0; i<rdrs; i++) {
                if (mr[i].mr_pid) {
-                       size_t tid;
-                       tid = mr[i].mr_tid;
-                       if (mr[i].mr_txnid == (txnid_t)-1) {
-                               sprintf(buf, "%10d %"Z"x -\n", mr[i].mr_pid, tid);
-                       } else {
-                               sprintf(buf, "%10d %"Z"x %"Z"u\n", mr[i].mr_pid, tid, mr[i].mr_txnid);
-                       }
+                       txnid_t txnid = mr[i].mr_txnid;
+                       sprintf(buf, txnid == (txnid_t)-1 ?
+                               "%10d %"Z"x -\n" : "%10d %"Z"x %"Z"u\n",
+                               (int)mr[i].mr_pid, (size_t)mr[i].mr_tid, txnid);
                        if (first) {
                                first = 0;
                                rc = func("    pid     thread     txnid\n", ctx);