Add DB_USRVALID, to avoid 'dbi == FREE_DBI' tests

mdb.RE/0.9
Hallvard Furuseth 10 years ago
parent b6f0179683
commit 110fba2ef1
  1. 38
      libraries/liblmdb/mdb.c

@ -1037,6 +1037,7 @@ struct MDB_txn {
#define DB_STALE 0x02 /**< Named-DB record is older than txnID */ #define DB_STALE 0x02 /**< Named-DB record is older than txnID */
#define DB_NEW 0x04 /**< Named-DB handle opened in this txn */ #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_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 */ /** In write txns, array of cursors for each DB */
MDB_cursor **mt_cursors; MDB_cursor **mt_cursors;
@ -1227,8 +1228,8 @@ typedef struct MDB_ntxn {
#define MAX_WRITE (0x80000000U >> (sizeof(ssize_t) == 4)) #define MAX_WRITE (0x80000000U >> (sizeof(ssize_t) == 4))
/** Check \b txn and \b dbi arguments to a function */ /** Check \b txn and \b dbi arguments to a function */
#define TXN_DBI_EXIST(txn, dbi) \ #define TXN_DBI_EXIST(txn, dbi, validity) \
((txn) && (dbi) < (txn)->mt_numdbs && ((txn)->mt_dbflags[dbi] & DB_VALID)) ((txn) && (dbi)<(txn)->mt_numdbs && ((txn)->mt_dbflags[dbi] & (validity)))
/** Check for misused \b dbi handles */ /** Check for misused \b dbi handles */
#define TXN_DBI_CHANGED(txn, dbi) \ #define TXN_DBI_CHANGED(txn, dbi) \
@ -2662,9 +2663,10 @@ mdb_txn_renew0(MDB_txn *txn)
for (i=2; i<txn->mt_numdbs; i++) { for (i=2; i<txn->mt_numdbs; i++) {
x = env->me_dbflags[i]; x = env->me_dbflags[i];
txn->mt_dbs[i].md_flags = x & PERSISTENT_FLAGS; 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) { if (env->me_maxpg < txn->mt_next_pgno) {
mdb_txn_reset0(txn, "renew0-mapfail"); mdb_txn_reset0(txn, "renew0-mapfail");
@ -5466,7 +5468,7 @@ mdb_get(MDB_txn *txn, MDB_dbi dbi,
DPRINTF(("===> get db %u key [%s]", dbi, DKEY(key))); DPRINTF(("===> 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; return EINVAL;
if (txn->mt_flags & MDB_TXN_ERROR) if (txn->mt_flags & MDB_TXN_ERROR)
@ -7207,7 +7209,7 @@ mdb_xcursor_init1(MDB_cursor *mc, MDB_node *node)
} }
DPRINTF(("Sub-db -%u root page %"Z"u", mx->mx_cursor.mc_dbi, DPRINTF(("Sub-db -%u root page %"Z"u", mx->mx_cursor.mc_dbi,
mx->mx_db.md_root)); 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 UINT_MAX < SIZE_MAX
if (mx->mx_dbx.md_cmp == mdb_cmp_int && mx->mx_db.md_pad == sizeof(size_t)) 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; mx->mx_dbx.md_cmp = mdb_cmp_clong;
@ -7280,7 +7282,7 @@ mdb_cursor_open(MDB_txn *txn, MDB_dbi dbi, MDB_cursor **ret)
MDB_cursor *mc; MDB_cursor *mc;
size_t size = sizeof(MDB_cursor); size_t size = sizeof(MDB_cursor);
if (!ret || !TXN_DBI_EXIST(txn, dbi)) if (!ret || !TXN_DBI_EXIST(txn, dbi, DB_VALID))
return EINVAL; return EINVAL;
if (txn->mt_flags & MDB_TXN_ERROR) if (txn->mt_flags & MDB_TXN_ERROR)
@ -7312,7 +7314,7 @@ mdb_cursor_open(MDB_txn *txn, MDB_dbi dbi, MDB_cursor **ret)
int int
mdb_cursor_renew(MDB_txn *txn, MDB_cursor *mc) 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; return EINVAL;
if ((mc->mc_flags & C_UNTRACK) || txn->mt_cursors) if ((mc->mc_flags & C_UNTRACK) || txn->mt_cursors)
@ -8084,7 +8086,7 @@ int
mdb_del(MDB_txn *txn, MDB_dbi dbi, mdb_del(MDB_txn *txn, MDB_dbi dbi,
MDB_val *key, MDB_val *data) 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; return EINVAL;
if (txn->mt_flags & (MDB_TXN_RDONLY|MDB_TXN_ERROR)) if (txn->mt_flags & (MDB_TXN_RDONLY|MDB_TXN_ERROR))
@ -8550,7 +8552,7 @@ mdb_put(MDB_txn *txn, MDB_dbi dbi,
MDB_cursor mc; MDB_cursor mc;
MDB_xcursor mx; 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; return EINVAL;
if (flags & ~(MDB_NOOVERWRITE|MDB_NODUPDATA|MDB_RESERVE|MDB_APPEND|MDB_APPENDDUP)) if (flags & ~(MDB_NOOVERWRITE|MDB_NODUPDATA|MDB_RESERVE|MDB_APPEND|MDB_APPENDDUP))
@ -9320,7 +9322,7 @@ int mdb_dbi_open(MDB_txn *txn, const char *name, unsigned int flags, MDB_dbi *db
return (flags & MDB_CREATE) ? MDB_INCOMPATIBLE : MDB_NOTFOUND; return (flags & MDB_CREATE) ? MDB_INCOMPATIBLE : MDB_NOTFOUND;
/* Find the DB info */ /* Find the DB info */
dbflag = DB_NEW|DB_VALID; dbflag = DB_NEW|DB_VALID|DB_USRVALID;
exact = 0; exact = 0;
key.mv_size = len; key.mv_size = len;
key.mv_data = (void *)name; key.mv_data = (void *)name;
@ -9368,7 +9370,7 @@ int mdb_dbi_open(MDB_txn *txn, const char *name, unsigned int flags, MDB_dbi *db
int mdb_stat(MDB_txn *txn, MDB_dbi dbi, MDB_stat *arg) 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; return EINVAL;
if (txn->mt_flags & MDB_TXN_ERROR) if (txn->mt_flags & MDB_TXN_ERROR)
@ -9402,7 +9404,7 @@ void mdb_dbi_close(MDB_env *env, MDB_dbi dbi)
int mdb_dbi_flags(MDB_txn *txn, MDB_dbi dbi, unsigned int *flags) int mdb_dbi_flags(MDB_txn *txn, MDB_dbi dbi, unsigned int *flags)
{ {
/* We could return the flags for the FREE_DBI too but what's the point? */ /* We could return the flags for the FREE_DBI too but what's the point? */
if (dbi == FREE_DBI || !TXN_DBI_EXIST(txn, dbi)) if (!TXN_DBI_EXIST(txn, dbi, DB_USRVALID))
return EINVAL; return EINVAL;
*flags = txn->mt_dbs[dbi].md_flags & PERSISTENT_FLAGS; *flags = txn->mt_dbs[dbi].md_flags & PERSISTENT_FLAGS;
return MDB_SUCCESS; return MDB_SUCCESS;
@ -9502,7 +9504,7 @@ int mdb_drop(MDB_txn *txn, MDB_dbi dbi, int del)
MDB_cursor *mc, *m2; MDB_cursor *mc, *m2;
int rc; 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; return EINVAL;
if (F_ISSET(txn->mt_flags, MDB_TXN_RDONLY)) if (F_ISSET(txn->mt_flags, MDB_TXN_RDONLY))
@ -9550,7 +9552,7 @@ leave:
int mdb_set_compare(MDB_txn *txn, MDB_dbi dbi, MDB_cmp_func *cmp) 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; return EINVAL;
txn->mt_dbxs[dbi].md_cmp = cmp; txn->mt_dbxs[dbi].md_cmp = cmp;
@ -9559,7 +9561,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) 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; return EINVAL;
txn->mt_dbxs[dbi].md_dcmp = cmp; txn->mt_dbxs[dbi].md_dcmp = cmp;
@ -9568,7 +9570,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) 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; return EINVAL;
txn->mt_dbxs[dbi].md_rel = rel; txn->mt_dbxs[dbi].md_rel = rel;
@ -9577,7 +9579,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) 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; return EINVAL;
txn->mt_dbxs[dbi].md_relctx = ctx; txn->mt_dbxs[dbi].md_relctx = ctx;

Loading…
Cancel
Save