mirror of
https://git.openldap.org/openldap/openldap.git
synced 2026-01-22 14:53:33 -05:00
Merge remote-tracking branch 'origin/mdb.master'
This commit is contained in:
commit
011eb3a27c
2 changed files with 47 additions and 69 deletions
|
|
@ -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 "July 8, 2014"
|
||||
#define MDB_VERSION_DATE "July 24, 2014"
|
||||
|
||||
/** A stringifier for the version info */
|
||||
#define MDB_VERSTR(a,b,c,d) "LMDB " #a "." #b "." #c ": (" d ")"
|
||||
|
|
@ -411,7 +411,7 @@ typedef enum MDB_cursor_op {
|
|||
#define MDB_CURSOR_FULL (-30787)
|
||||
/** Page has not enough space - internal error */
|
||||
#define MDB_PAGE_FULL (-30786)
|
||||
/** Environment mapsize was changed by another process */
|
||||
/** Database contents grew beyond environment mapsize */
|
||||
#define MDB_MAP_RESIZED (-30785)
|
||||
/** MDB_INCOMPATIBLE: Operation and DB incompatible, or DB flags changed */
|
||||
#define MDB_INCOMPATIBLE (-30784)
|
||||
|
|
@ -785,12 +785,15 @@ int mdb_env_get_fd(MDB_env *env, mdb_filehandle_t *fd);
|
|||
* This function should be called after #mdb_env_create() and before #mdb_env_open().
|
||||
* It may be called at later times if no transactions are active in
|
||||
* this process. Note that the library does not check for this condition,
|
||||
* the caller must ensure it explicitly. The new size takes effect
|
||||
* immediately for the current process but will not be persisted to
|
||||
* any others until a write transaction has been committed by the
|
||||
* current process.
|
||||
* the caller must ensure it explicitly.
|
||||
*
|
||||
* If the mapsize is changed by another process, #mdb_txn_begin() will
|
||||
* The new size takes effect immediately for the current process but
|
||||
* will not be persisted to any others until a write transaction has been
|
||||
* committed by the current process. Also, only mapsize increases are
|
||||
* persisted into the environment.
|
||||
*
|
||||
* If the mapsize is increased by another process, and data has grown
|
||||
* beyond the range of the current mapsize, #mdb_txn_begin() will
|
||||
* return #MDB_MAP_RESIZED. This function may be called with a size
|
||||
* of zero to adopt the new size.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -1074,8 +1074,6 @@ struct MDB_env {
|
|||
HANDLE me_mfd; /**< just for writing the meta pages */
|
||||
/** Failed to update the meta page. Probably an I/O error. */
|
||||
#define MDB_FATAL_ERROR 0x80000000U
|
||||
/** We're explicitly changing the mapsize. */
|
||||
#define MDB_RESIZING 0x40000000U
|
||||
/** Some fields are initialized. */
|
||||
#define MDB_ENV_ACTIVE 0x20000000U
|
||||
/** me_txkey is set */
|
||||
|
|
@ -2537,9 +2535,7 @@ mdb_txn_renew0(MDB_txn *txn)
|
|||
}
|
||||
txn->mt_dbflags[0] = txn->mt_dbflags[1] = DB_VALID;
|
||||
|
||||
/* If we didn't ask for a resize, but the size grew, fail */
|
||||
if (!(env->me_flags & MDB_RESIZING)
|
||||
&& env->me_mapsize < meta->mm_mapsize) {
|
||||
if (env->me_maxpg < txn->mt_next_pgno) {
|
||||
mdb_txn_reset0(txn, "renew0-mapfail");
|
||||
if (new_notls) {
|
||||
txn->mt_u.reader->mr_pid = 0;
|
||||
|
|
@ -3277,13 +3273,8 @@ mdb_txn_commit(MDB_txn *txn)
|
|||
mdb_cursors_close(txn, 0);
|
||||
|
||||
if (!txn->mt_u.dirty_list[0].mid &&
|
||||
!(txn->mt_flags & (MDB_TXN_DIRTY|MDB_TXN_SPILLS))) {
|
||||
if ((env->me_flags & MDB_RESIZING)
|
||||
&& (rc = mdb_env_write_meta(txn))) {
|
||||
goto fail;
|
||||
}
|
||||
!(txn->mt_flags & (MDB_TXN_DIRTY|MDB_TXN_SPILLS)))
|
||||
goto done;
|
||||
}
|
||||
|
||||
DPRINTF(("committing txn %"Z"u %p on mdbenv %p, root page %"Z"u",
|
||||
txn->mt_txnid, (void*)txn, (void*)env, txn->mt_dbs[MAIN_DBI].md_root));
|
||||
|
|
@ -3324,6 +3315,7 @@ mdb_txn_commit(MDB_txn *txn)
|
|||
#endif
|
||||
|
||||
if ((rc = mdb_page_flush(txn, 0)) ||
|
||||
(rc = mdb_env_sync(env, 0)) ||
|
||||
(rc = mdb_env_write_meta(txn)))
|
||||
goto fail;
|
||||
|
||||
|
|
@ -3480,8 +3472,9 @@ mdb_env_init_meta(MDB_env *env, MDB_meta *meta)
|
|||
static int
|
||||
mdb_env_write_meta(MDB_txn *txn)
|
||||
{
|
||||
MDB_env *env = txn->mt_env;
|
||||
MDB_env *env;
|
||||
MDB_meta meta, metab, *mp;
|
||||
size_t mapsize;
|
||||
off_t off;
|
||||
int rc, len, toggle;
|
||||
char *ptr;
|
||||
|
|
@ -3492,22 +3485,19 @@ mdb_env_write_meta(MDB_txn *txn)
|
|||
int r2;
|
||||
#endif
|
||||
|
||||
/* Sync data and previous metapage before writing a new metapage */
|
||||
if ((rc = mdb_env_sync(env, 0)) != MDB_SUCCESS)
|
||||
return rc;
|
||||
|
||||
toggle = txn->mt_txnid & 1;
|
||||
DPRINTF(("writing meta page %d for root page %"Z"u",
|
||||
toggle, txn->mt_dbs[MAIN_DBI].md_root));
|
||||
|
||||
env = txn->mt_env;
|
||||
mp = env->me_metas[toggle];
|
||||
mapsize = env->me_metas[toggle ^ 1]->mm_mapsize;
|
||||
/* Persist any increases of mapsize config */
|
||||
if (mapsize < env->me_mapsize)
|
||||
mapsize = env->me_mapsize;
|
||||
|
||||
if (env->me_flags & MDB_WRITEMAP) {
|
||||
/* Persist any changes of mapsize config */
|
||||
if (env->me_flags & MDB_RESIZING) {
|
||||
mp->mm_mapsize = env->me_mapsize;
|
||||
env->me_flags ^= MDB_RESIZING;
|
||||
}
|
||||
mp->mm_mapsize = mapsize;
|
||||
mp->mm_dbs[0] = txn->mt_dbs[0];
|
||||
mp->mm_dbs[1] = txn->mt_dbs[1];
|
||||
mp->mm_last_pg = txn->mt_next_pgno - 1;
|
||||
|
|
@ -3534,23 +3524,15 @@ mdb_env_write_meta(MDB_txn *txn)
|
|||
metab.mm_txnid = env->me_metas[toggle]->mm_txnid;
|
||||
metab.mm_last_pg = env->me_metas[toggle]->mm_last_pg;
|
||||
|
||||
ptr = (char *)&meta;
|
||||
if (env->me_flags & MDB_RESIZING) {
|
||||
/* Persist any changes of mapsize config */
|
||||
meta.mm_mapsize = env->me_mapsize;
|
||||
off = offsetof(MDB_meta, mm_mapsize);
|
||||
env->me_flags ^= MDB_RESIZING;
|
||||
} else {
|
||||
off = offsetof(MDB_meta, mm_dbs[0].md_depth);
|
||||
}
|
||||
len = sizeof(MDB_meta) - off;
|
||||
|
||||
ptr += off;
|
||||
meta.mm_mapsize = mapsize;
|
||||
meta.mm_dbs[0] = txn->mt_dbs[0];
|
||||
meta.mm_dbs[1] = txn->mt_dbs[1];
|
||||
meta.mm_last_pg = txn->mt_next_pgno - 1;
|
||||
meta.mm_txnid = txn->mt_txnid;
|
||||
|
||||
off = offsetof(MDB_meta, mm_mapsize);
|
||||
ptr = (char *)&meta + off;
|
||||
len = sizeof(MDB_meta) - off;
|
||||
if (toggle)
|
||||
off += env->me_psize;
|
||||
off += PAGEHDRSZ;
|
||||
|
|
@ -3728,25 +3710,19 @@ mdb_env_set_mapsize(MDB_env *env, size_t size)
|
|||
* sure there are no active txns.
|
||||
*/
|
||||
if (env->me_map) {
|
||||
int rc, change = 0;
|
||||
int rc;
|
||||
void *old;
|
||||
if (env->me_txn)
|
||||
return EINVAL;
|
||||
if (!size)
|
||||
size = env->me_metas[mdb_env_pick_meta(env)]->mm_mapsize;
|
||||
else {
|
||||
if (size < env->me_mapsize) {
|
||||
/* If the configured size is smaller, make sure it's
|
||||
* still big enough. Silently round up to minimum if not.
|
||||
*/
|
||||
size_t minsize = (env->me_metas[mdb_env_pick_meta(env)]->mm_last_pg + 1) * env->me_psize;
|
||||
if (size < minsize)
|
||||
size = minsize;
|
||||
}
|
||||
/* nothing actually changed */
|
||||
if (size == env->me_mapsize)
|
||||
return MDB_SUCCESS;
|
||||
change = 1;
|
||||
else if (size < env->me_mapsize) {
|
||||
/* If the configured size is smaller, make sure it's
|
||||
* still big enough. Silently round up to minimum if not.
|
||||
*/
|
||||
size_t minsize = (env->me_metas[mdb_env_pick_meta(env)]->mm_last_pg + 1) * env->me_psize;
|
||||
if (size < minsize)
|
||||
size = minsize;
|
||||
}
|
||||
munmap(env->me_map, env->me_mapsize);
|
||||
env->me_mapsize = size;
|
||||
|
|
@ -3754,8 +3730,6 @@ mdb_env_set_mapsize(MDB_env *env, size_t size)
|
|||
rc = mdb_env_map(env, old);
|
||||
if (rc)
|
||||
return rc;
|
||||
if (change)
|
||||
env->me_flags |= MDB_RESIZING;
|
||||
}
|
||||
env->me_mapsize = size;
|
||||
if (env->me_psize)
|
||||
|
|
@ -3828,17 +3802,13 @@ mdb_env_open2(MDB_env *env)
|
|||
* else use the size recorded in the existing env.
|
||||
*/
|
||||
env->me_mapsize = newenv ? DEFAULT_MAPSIZE : meta.mm_mapsize;
|
||||
} else {
|
||||
if (env->me_mapsize < meta.mm_mapsize) {
|
||||
/* If the configured size is smaller, make sure it's
|
||||
* still big enough. Silently round up to minimum if not.
|
||||
*/
|
||||
size_t minsize = (meta.mm_last_pg + 1) * meta.mm_psize;
|
||||
if (env->me_mapsize < minsize)
|
||||
env->me_mapsize = minsize;
|
||||
}
|
||||
if (env->me_mapsize != meta.mm_mapsize)
|
||||
env->me_flags |= MDB_RESIZING;
|
||||
} else if (env->me_mapsize < meta.mm_mapsize) {
|
||||
/* If the configured size is smaller, make sure it's
|
||||
* still big enough. Silently round up to minimum if not.
|
||||
*/
|
||||
size_t minsize = (meta.mm_last_pg + 1) * meta.mm_psize;
|
||||
if (env->me_mapsize < minsize)
|
||||
env->me_mapsize = minsize;
|
||||
}
|
||||
|
||||
rc = mdb_env_map(env, (flags & MDB_FIXEDMAP) ? meta.mm_address : NULL);
|
||||
|
|
@ -6992,6 +6962,9 @@ mdb_cursor_count(MDB_cursor *mc, size_t *countp)
|
|||
if (!(mc->mc_flags & C_INITIALIZED))
|
||||
return EINVAL;
|
||||
|
||||
if (!mc->mc_snum || (mc->mc_flags & C_EOF))
|
||||
return MDB_NOTFOUND;
|
||||
|
||||
leaf = NODEPTR(mc->mc_pg[mc->mc_top], mc->mc_ki[mc->mc_top]);
|
||||
if (!F_ISSET(leaf->mn_flags, F_DUPDATA)) {
|
||||
*countp = 1;
|
||||
|
|
@ -8440,13 +8413,13 @@ mdb_env_copyfd1(MDB_env *env, HANDLE fd)
|
|||
#ifdef _WIN32
|
||||
my.mc_mutex = CreateMutex(NULL, FALSE, NULL);
|
||||
my.mc_cond = CreateEvent(NULL, FALSE, FALSE, NULL);
|
||||
my.mc_wbuf[0] = _aligned_malloc(MDB_WBUF*2, env->me_psize);
|
||||
my.mc_wbuf[0] = _aligned_malloc(MDB_WBUF*2, env->me_os_psize);
|
||||
if (my.mc_wbuf[0] == NULL)
|
||||
return errno;
|
||||
#else
|
||||
pthread_mutex_init(&my.mc_mutex, NULL);
|
||||
pthread_cond_init(&my.mc_cond, NULL);
|
||||
rc = posix_memalign((void **)&my.mc_wbuf[0], env->me_psize, MDB_WBUF*2);
|
||||
rc = posix_memalign((void **)&my.mc_wbuf[0], env->me_os_psize, MDB_WBUF*2);
|
||||
if (rc)
|
||||
return rc;
|
||||
#endif
|
||||
|
|
@ -8684,6 +8657,7 @@ mdb_env_copy2(MDB_env *env, const char *path, unsigned int flags)
|
|||
goto leave;
|
||||
}
|
||||
|
||||
if (env->me_psize >= env->me_os_psize) {
|
||||
#ifdef O_DIRECT
|
||||
/* Set O_DIRECT if the file system supports it */
|
||||
if ((rc = fcntl(newfd, F_GETFL)) != -1)
|
||||
|
|
@ -8696,6 +8670,7 @@ mdb_env_copy2(MDB_env *env, const char *path, unsigned int flags)
|
|||
goto leave;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
rc = mdb_env_copyfd2(env, newfd, flags);
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue