lmdb: Add DB_USRVALID, to avoid 'dbi == FREE_DBI' tests.

Change-Id: Ic44ce41fd2fff1abb4cd24821ece07ef30254565
This commit is contained in:
Hallvard Furuseth 2015-07-04 13:49:12 +02:00 committed by Leo Yuriev
parent 4cb5d637d4
commit 57b263693c

42
mdb.c
View File

@ -912,6 +912,7 @@ struct MDB_txn {
#define DB_STALE 0x02 /**< Named-DB record is older than txnID */
#define DB_NEW 0x04 /**< Named-DB handle opened in this txn */
#define DB_VALID 0x08 /**< DB handle is valid, see also #MDB_VALID */
#define DB_USRVALID 0x10 /**< As #DB_VALID, but not set for #FREE_DBI */
/** @} */
/** In write txns, array of cursors for each DB */
MDB_cursor **mt_cursors;
@ -1098,8 +1099,8 @@ typedef struct MDB_ntxn {
#define MAX_WRITE (0x80000000U >> (sizeof(ssize_t) == 4))
/** Check \b txn and \b dbi arguments to a function */
#define TXN_DBI_EXIST(txn, dbi) \
((txn) && (dbi) < (txn)->mt_numdbs && ((txn)->mt_dbflags[dbi] & DB_VALID))
#define TXN_DBI_EXIST(txn, dbi, validity) \
((txn) && (dbi)<(txn)->mt_numdbs && ((txn)->mt_dbflags[dbi] & (validity)))
/** Check for misused \b dbi handles */
#define TXN_DBI_CHANGED(txn, dbi) \
@ -2825,9 +2826,10 @@ mdb_txn_renew0(MDB_txn *txn)
for (i=2; i<txn->mt_numdbs; i++) {
x = env->me_dbflags[i];
txn->mt_dbs[i].md_flags = x & PERSISTENT_FLAGS;
txn->mt_dbflags[i] = (x & MDB_VALID) ? DB_VALID|DB_STALE : 0;
txn->mt_dbflags[i] = (x & MDB_VALID) ? DB_VALID|DB_USRVALID|DB_STALE : 0;
}
txn->mt_dbflags[0] = txn->mt_dbflags[1] = DB_VALID;
txn->mt_dbflags[MAIN_DBI] = DB_VALID|DB_USRVALID;
txn->mt_dbflags[FREE_DBI] = DB_VALID;
if (env->me_maxpg < txn->mt_next_pgno) {
mdb_txn_reset0(txn, "renew0-mapfail");
@ -5394,7 +5396,7 @@ mdb_get(MDB_txn *txn, MDB_dbi dbi,
mdb_debug("===> get db %u key [%s]", dbi, DKEY(key));
if (!key || !data || dbi == FREE_DBI || !TXN_DBI_EXIST(txn, dbi))
if (!key || !data || !TXN_DBI_EXIST(txn, dbi, DB_USRVALID))
return EINVAL;
if (txn->mt_flags & MDB_TXN_ERROR)
@ -7117,7 +7119,11 @@ mdb_xcursor_init1(MDB_cursor *mc, MDB_node *node)
}
mdb_debug("Sub-db -%u root page %zu", mx->mx_cursor.mc_dbi,
mx->mx_db.md_root);
mx->mx_dbflag = DB_VALID|DB_DIRTY; /* DB_DIRTY guides mdb_cursor_touch */
mx->mx_dbflag = DB_VALID|DB_USRVALID|DB_DIRTY; /* DB_DIRTY guides mdb_cursor_touch */
/* #if UINT_MAX < SIZE_MAX
if (mx->mx_dbx.md_cmp == mdb_cmp_int && mx->mx_db.md_pad == sizeof(size_t))
mx->mx_dbx.md_cmp = mdb_cmp_clong;
#endif */
}
/** Initialize a cursor for a given transaction and database. */
@ -7154,7 +7160,7 @@ mdb_cursor_open(MDB_txn *txn, MDB_dbi dbi, MDB_cursor **ret)
MDB_cursor *mc;
size_t size = sizeof(MDB_cursor);
if (!ret || !TXN_DBI_EXIST(txn, dbi))
if (!ret || !TXN_DBI_EXIST(txn, dbi, DB_VALID))
return EINVAL;
if (txn->mt_flags & MDB_TXN_ERROR)
@ -7186,7 +7192,7 @@ mdb_cursor_open(MDB_txn *txn, MDB_dbi dbi, MDB_cursor **ret)
int
mdb_cursor_renew(MDB_txn *txn, MDB_cursor *mc)
{
if (!mc || !TXN_DBI_EXIST(txn, mc->mc_dbi))
if (!mc || !TXN_DBI_EXIST(txn, mc->mc_dbi, DB_VALID))
return EINVAL;
if ((mc->mc_flags & C_UNTRACK) || txn->mt_cursors)
@ -7933,7 +7939,7 @@ int
mdb_del(MDB_txn *txn, MDB_dbi dbi,
MDB_val *key, MDB_val *data)
{
if (!key || dbi == FREE_DBI || !TXN_DBI_EXIST(txn, dbi))
if (!key || !TXN_DBI_EXIST(txn, dbi, DB_USRVALID))
return EINVAL;
if (txn->mt_flags & (MDB_TXN_RDONLY|MDB_TXN_ERROR))
@ -8400,7 +8406,7 @@ mdb_put(MDB_txn *txn, MDB_dbi dbi,
MDB_cursor mc;
MDB_xcursor mx;
if (!key || !data || dbi == FREE_DBI || !TXN_DBI_EXIST(txn, dbi))
if (!key || !data || !TXN_DBI_EXIST(txn, dbi, DB_USRVALID))
return EINVAL;
if (flags & ~(MDB_NOOVERWRITE|MDB_NODUPDATA|MDB_RESERVE|MDB_APPEND|MDB_APPENDDUP))
@ -9155,7 +9161,7 @@ int mdb_dbi_open(MDB_txn *txn, const char *name, unsigned flags, MDB_dbi *dbi)
return (flags & MDB_CREATE) ? MDB_INCOMPATIBLE : MDB_NOTFOUND;
/* Find the DB info */
dbflag = DB_NEW|DB_VALID;
dbflag = DB_NEW|DB_VALID|DB_USRVALID;
exact = 0;
key.mv_size = len;
key.mv_data = (void *)name;
@ -9203,7 +9209,7 @@ int mdb_dbi_open(MDB_txn *txn, const char *name, unsigned flags, MDB_dbi *dbi)
int mdb_stat(MDB_txn *txn, MDB_dbi dbi, MDB_stat *arg)
{
if (!arg || !TXN_DBI_EXIST(txn, dbi))
if (!arg || !TXN_DBI_EXIST(txn, dbi, DB_VALID))
return EINVAL;
if (txn->mt_flags & MDB_TXN_ERROR)
@ -9236,7 +9242,7 @@ void mdb_dbi_close(MDB_env *env, MDB_dbi dbi)
int mdb_dbi_flags(MDB_txn *txn, MDB_dbi dbi, unsigned *flags)
{
if (!TXN_DBI_EXIST(txn, dbi))
if (!TXN_DBI_EXIST(txn, dbi, DB_VALID))
return EINVAL;
*flags = txn->mt_dbs[dbi].md_flags & PERSISTENT_FLAGS;
return MDB_SUCCESS;
@ -9336,7 +9342,7 @@ int mdb_drop(MDB_txn *txn, MDB_dbi dbi, int del)
MDB_cursor *mc, *m2;
int rc;
if ((unsigned)del > 1 || dbi == FREE_DBI || !TXN_DBI_EXIST(txn, dbi))
if ((unsigned)del > 1 || !TXN_DBI_EXIST(txn, dbi, DB_USRVALID))
return EINVAL;
if (F_ISSET(txn->mt_flags, MDB_TXN_RDONLY))
@ -9384,7 +9390,7 @@ leave:
int mdb_set_compare(MDB_txn *txn, MDB_dbi dbi, MDB_cmp_func *cmp)
{
if (dbi == FREE_DBI || !TXN_DBI_EXIST(txn, dbi))
if (!TXN_DBI_EXIST(txn, dbi, DB_USRVALID))
return EINVAL;
txn->mt_dbxs[dbi].md_cmp = cmp;
@ -9393,7 +9399,7 @@ int mdb_set_compare(MDB_txn *txn, MDB_dbi dbi, MDB_cmp_func *cmp)
int mdb_set_dupsort(MDB_txn *txn, MDB_dbi dbi, MDB_cmp_func *cmp)
{
if (dbi == FREE_DBI || !TXN_DBI_EXIST(txn, dbi))
if (!TXN_DBI_EXIST(txn, dbi, DB_USRVALID))
return EINVAL;
txn->mt_dbxs[dbi].md_dcmp = cmp;
@ -9402,7 +9408,7 @@ int mdb_set_dupsort(MDB_txn *txn, MDB_dbi dbi, MDB_cmp_func *cmp)
int mdb_set_relfunc(MDB_txn *txn, MDB_dbi dbi, MDB_rel_func *rel)
{
if (dbi == FREE_DBI || !TXN_DBI_EXIST(txn, dbi))
if (!TXN_DBI_EXIST(txn, dbi, DB_USRVALID))
return EINVAL;
txn->mt_dbxs[dbi].md_rel = rel;
@ -9411,7 +9417,7 @@ int mdb_set_relfunc(MDB_txn *txn, MDB_dbi dbi, MDB_rel_func *rel)
int mdb_set_relctx(MDB_txn *txn, MDB_dbi dbi, void *ctx)
{
if (dbi == FREE_DBI || !TXN_DBI_EXIST(txn, dbi))
if (!TXN_DBI_EXIST(txn, dbi, DB_USRVALID))
return EINVAL;
txn->mt_dbxs[dbi].md_relctx = ctx;