Commit fbc2e64b authored by Daniel Salzman's avatar Daniel Salzman

Merge branch 'require_lmdb_0.9.15' into 'master'

Require lmdb version at least 0.9.15

See merge request !442
parents 652cdf76 a3febbfb
......@@ -328,11 +328,16 @@ dt_DNSTAP([
AM_CONDITIONAL([HAVE_DNSTAP], test "$opt_dnstap" != "no")
dnl Check for LMDB
lmdb_MIN_VERSION_MAJOR=0
lmdb_MIN_VERSION_MINOR=9
lmdb_MIN_VERSION_PATCH=15
lmdb_MIN_VERSION_STRING="$lmdb_MIN_VERSION_MAJOR.$lmdb_MIN_VERSION_MINOR.$lmdb_MIN_VERSION_PATCH"
lmdb_MIN_VERSION_FULL="$((($lmdb_MIN_VERSION_MAJOR << 24) | ($lmdb_MIN_VERSION_MINOR << 16) | $lmdb_MIN_VERSION_PATCH))"
AC_ARG_WITH([lmdb],
AC_HELP_STRING([--with-lmdb=[DIR]], [Link with external LMDB]),[
AC_HELP_STRING([--with-lmdb=[DIR]], [Link with external LMDB (>= $lmdb_MIN_VERSION_STRING)]),[
with_lmdb=$withval
],[
with_lmdb=yes
with_lmdb=auto
])
have_lmdb=no
......@@ -340,6 +345,8 @@ have_lmdb=no
AS_IF([test "$with_lmdb" != "no"],[
save_CPPFLAGS=$CPPFLAGS
save_LIBS=$LIBS
# Look for lmdb in given path and common locations
for try_lmdb in "$with_lmdb" "" "/usr/local"; do
AS_IF([test -d "$try_lmdb"], [
......@@ -350,33 +357,44 @@ AS_IF([test "$with_lmdb" != "no"],[
lmdb_LIBS=""
])
CPPFLAGS="$CPPFLAGS $lmdb_CFLAGS"
LIBS="$LIBS $lmdb_LIBS"
CPPFLAGS="$save_CPPFLAGS $lmdb_CFLAGS"
LIBS="$save_LIBS $lmdb_LIBS"
AC_SEARCH_LIBS([mdb_env_open], [lmdb], [
AC_CHECK_HEADERS([lmdb.h], [], [
AC_ERROR([lmdb headers not found in `$try_lmdb', is your installation complete?])])
lmdb_LIBS="$lmdb_LIBS -llmdb"
have_lmdb=yes
break
],[
have_lmdb=no
# do not cache result of AC_SEARCH_LIBS test
unset ac_cv_search_mdb_env_open
])
CPPFLAGS="$save_CPPFLAGS"
LIBS="$save_LIBS"
AC_MSG_ERROR([lmdb headers not found in `$try_lmdb', is your installation complete?])])
AC_COMPUTE_INT(lmdb_VERSION_FULL, MDB_VERSION_FULL, [#include <lmdb.h>],
AC_MSG_ERROR([Unable to determine lmdb version from MDB_VERSION_FULL]))
AS_IF([test "$lmdb_VERSION_FULL" -ge "$lmdb_MIN_VERSION_FULL"],[
lmdb_LIBS="$lmdb_LIBS -llmdb"
have_lmdb=yes],[
AC_MSG_WARN([lmdb version 0.9.15 and higher not found, using embedded version])
])
break
])
unset lmdb_CFLAGS
unset lmdb_LIBS
# do not cache result of AC_SEARCH_LIBS test
unset ac_cv_search_mdb_env_open
done
CPPFLAGS="$save_CPPFLAGS"
LIBS="$save_LIBS"
# fail the configure if we haven't found lmdb library in the system
AS_IF([test "$with_lmdb" != "auto" -a "$have_lmdb" = "no"],[
AC_MSG_ERROR([shared lmdb library not found])
])
])
AS_IF([test "$have_lmdb" != "no"],[
AC_SUBST([lmdb_CFLAGS])
AC_SUBST([lmdb_LIBS])
enable_lmdb=shared
],[enable_lmdb=embedded])
],[
enable_lmdb=embedded
])
AM_CONDITIONAL([HAVE_LMDB], test "$have_lmdb" != "no")
AS_IF([test "$enable_daemon" = "yes"],[
......
......@@ -184,7 +184,7 @@ typedef int mdb_filehandle_t;
/** Library minor version */
#define MDB_VERSION_MINOR 9
/** Library patch version */
#define MDB_VERSION_PATCH 15
#define MDB_VERSION_PATCH 16
/** Combine args a,b,c into a single integer for easy version comparisons */
#define MDB_VERINT(a,b,c) (((a) << 24) | ((b) << 16) | (c))
......@@ -194,7 +194,7 @@ typedef int mdb_filehandle_t;
MDB_VERINT(MDB_VERSION_MAJOR,MDB_VERSION_MINOR,MDB_VERSION_PATCH)
/** The release date of this library version */
#define MDB_VERSION_DATE "June 19, 2015"
#define MDB_VERSION_DATE "August 14, 2015"
/** A stringifier for the version info */
#define MDB_VERSTR(a,b,c,d) "LMDB " #a "." #b "." #c ": (" d ")"
......@@ -413,7 +413,14 @@ typedef enum MDB_cursor_op {
#define MDB_PAGE_FULL (-30786)
/** Database contents grew beyond environment mapsize */
#define MDB_MAP_RESIZED (-30785)
/** MDB_INCOMPATIBLE: Operation and DB incompatible, or DB flags changed */
/** Operation and DB incompatible, or DB type changed. This can mean:
* <ul>
* <li>The operation expects an #MDB_DUPSORT / #MDB_DUPFIXED database.
* <li>Opening a named DB when the unnamed DB has #MDB_DUPSORT / #MDB_INTEGERKEY.
* <li>Accessing a data record as a database, or vice versa.
* <li>The database was dropped and recreated with different flags.
* </ul>
*/
#define MDB_INCOMPATIBLE (-30784)
/** Invalid reuse of reader locktable slot */
#define MDB_BAD_RSLOT (-30783)
......@@ -1034,8 +1041,9 @@ int mdb_txn_renew(MDB_txn *txn);
* any other transaction in the process may use this function.
*
* To use named databases (with name != NULL), #mdb_env_set_maxdbs()
* must be called before opening the environment. Database names
* are kept as keys in the unnamed database.
* must be called before opening the environment. Database names are
* keys in the unnamed database, and may be read but not written.
*
* @param[in] txn A transaction handle returned by #mdb_txn_begin()
* @param[in] name The name of the database to open. If only a single
* database is needed in the environment, this value may be NULL.
......
......@@ -332,7 +332,11 @@ mdb_sem_wait(sem_t *sem)
* Otherwise compile with the less efficient -DMDB_DSYNC=O_SYNC.
*/
#ifndef MDB_DSYNC
#ifdef O_DSYNC
# define MDB_DSYNC O_DSYNC
#else
# define MDB_DSYNC O_SYNC
#endif
#endif
#endif
......@@ -2822,8 +2826,8 @@ mdb_txn_reset0(MDB_txn *txn, const char *act)
}
if (!txn->mt_parent) {
if (mdb_midl_shrink(&txn->mt_free_pgs))
env->me_free_pgs = txn->mt_free_pgs;
mdb_midl_shrink(&txn->mt_free_pgs);
env->me_free_pgs = txn->mt_free_pgs;
/* me_pgstate: */
env->me_pghead = NULL;
env->me_pglast = 0;
......@@ -3395,7 +3399,8 @@ mdb_txn_commit(MDB_txn *txn)
goto fail;
}
data.mv_data = &txn->mt_dbs[i];
rc = mdb_cursor_put(&mc, &txn->mt_dbxs[i].md_name, &data, 0);
rc = mdb_cursor_put(&mc, &txn->mt_dbxs[i].md_name, &data,
F_SUBDATA);
if (rc)
goto fail;
}
......@@ -3408,8 +3413,8 @@ mdb_txn_commit(MDB_txn *txn)
mdb_midl_free(env->me_pghead);
env->me_pghead = NULL;
if (mdb_midl_shrink(&txn->mt_free_pgs))
env->me_free_pgs = txn->mt_free_pgs;
mdb_midl_shrink(&txn->mt_free_pgs);
env->me_free_pgs = txn->mt_free_pgs;
#if (MDB_DEBUG) > 2
mdb_audit(txn);
......@@ -3647,7 +3652,6 @@ mdb_env_write_meta(MDB_txn *txn)
/* Write to the SYNC fd */
mfd = env->me_flags & (MDB_NOSYNC|MDB_NOMETASYNC) ?
env->me_fd : env->me_mfd;
retry_write:
#ifdef _WIN32
{
memset(&ov, 0, sizeof(ov));
......@@ -3656,12 +3660,15 @@ retry_write:
rc = -1;
}
#else
retry_write:
rc = pwrite(mfd, ptr, len, off);
#endif
if (rc != len) {
rc = rc < 0 ? ErrCode() : EIO;
#ifndef _WIN32
if (rc == EINTR)
goto retry_write;
#endif
DPUTS("write failed, disk error?");
/* On a failure, the pagecache still contains the new data.
* Write some old data back, to prevent it from being used.
......@@ -5214,6 +5221,8 @@ mdb_page_search(MDB_cursor *mc, MDB_val *key, int flags)
&mc->mc_dbx->md_name, &exact);
if (!exact)
return MDB_NOTFOUND;
if ((leaf->mn_flags & (F_DUPDATA|F_SUBDATA)) != F_SUBDATA)
return MDB_INCOMPATIBLE; /* not a named DB */
rc = mdb_node_read(mc->mc_txn, leaf, &data);
if (rc)
return rc;
......@@ -5725,8 +5734,10 @@ set2:
if (leaf == NULL) {
DPUTS("===> inexact leaf not found, goto sibling");
if ((rc = mdb_cursor_sibling(mc, 1)) != MDB_SUCCESS)
if ((rc = mdb_cursor_sibling(mc, 1)) != MDB_SUCCESS) {
mc->mc_flags |= C_EOF;
return rc; /* no entries matched */
}
mp = mc->mc_pg[mc->mc_top];
mdb_cassert(mc, IS_LEAF(mp));
leaf = NODEPTR(mp, 0);
......@@ -6404,6 +6415,9 @@ prep_subDB:
goto new_sub;
}
current:
/* LMDB passes F_SUBDATA in 'flags' to write a DB record */
if ((leaf->mn_flags ^ flags) & F_SUBDATA)
return MDB_INCOMPATIBLE;
/* overflow page overwrites need special handling */
if (F_ISSET(leaf->mn_flags, F_BIGDATA)) {
MDB_page *omp;
......@@ -6674,6 +6688,11 @@ mdb_cursor_del(MDB_cursor *mc, unsigned int flags)
goto fail;
}
}
/* LMDB passes F_SUBDATA in 'flags' to delete a DB record */
else if ((leaf->mn_flags ^ flags) & F_SUBDATA) {
rc = MDB_INCOMPATIBLE;
goto fail;
}
/* add overflow pages to free list */
if (F_ISSET(leaf->mn_flags, F_BIGDATA)) {
......@@ -9169,7 +9188,7 @@ int mdb_dbi_open(MDB_txn *txn, const char *name, unsigned int flags, MDB_dbi *db
if (rc == MDB_SUCCESS) {
/* make sure this is actually a DB */
MDB_node *node = NODEPTR(mc.mc_pg[mc.mc_top], mc.mc_ki[mc.mc_top]);
if (!(node->mn_flags & F_SUBDATA))
if ((node->mn_flags & (F_DUPDATA|F_SUBDATA)) != F_SUBDATA)
return MDB_INCOMPATIBLE;
} else if (rc == MDB_NOTFOUND && (flags & MDB_CREATE)) {
/* Create if requested */
......@@ -9362,7 +9381,7 @@ int mdb_drop(MDB_txn *txn, MDB_dbi dbi, int del)
/* Can't delete the main DB */
if (del && dbi > MAIN_DBI) {
rc = mdb_del0(txn, MAIN_DBI, &mc->mc_dbx->md_name, NULL, 0);
rc = mdb_del0(txn, MAIN_DBI, &mc->mc_dbx->md_name, NULL, F_SUBDATA);
if (!rc) {
txn->mt_dbflags[dbi] = DB_STALE;
mdb_dbi_close(txn->mt_env, dbi);
......
......@@ -116,7 +116,7 @@ void mdb_midl_free(MDB_IDL ids)
free(ids-1);
}
int mdb_midl_shrink( MDB_IDL *idp )
void mdb_midl_shrink( MDB_IDL *idp )
{
MDB_IDL ids = *idp;
if (*(--ids) > MDB_IDL_UM_MAX &&
......@@ -124,9 +124,7 @@ int mdb_midl_shrink( MDB_IDL *idp )
{
*ids++ = MDB_IDL_UM_MAX;
*idp = ids;
return 1;
}
return 0;
}
static int mdb_midl_grow( MDB_IDL *idp, int num )
......
......@@ -98,9 +98,8 @@ void mdb_midl_free(MDB_IDL ids);
/** Shrink an IDL.
* Return the IDL to the default size if it has grown larger.
* @param[in,out] idp Address of the IDL to shrink.
* @return 0 on no change, non-zero if shrunk.
*/
int mdb_midl_shrink(MDB_IDL *idp);
void mdb_midl_shrink(MDB_IDL *idp);
/** Make room for num additional elements in an IDL.
* @param[in,out] idp Address of the IDL.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment