/** @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
*/
# 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
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;
}
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);
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));
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;
}
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;
}
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;
}
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))
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;
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;
}
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];
/* 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;
int rc, exact;
DKBUF;
- assert(key != NULL);
+ if (key == NULL)
+ return EINVAL;
DPRINTF(("====> delete db %u key [%s]", dbi, DKEY(key)));
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;