mdbx: add MDBX_CP_FORCE_RESIZEABLE option.

Change-Id: I5fcdae7933dbbfbf8629e8a0423545a4f6b9f6b6
This commit is contained in:
Leonid Yuriev 2020-04-27 19:51:12 +03:00
parent 37abc146b4
commit fac0d47913
2 changed files with 25 additions and 6 deletions

1
mdbx.h
View File

@ -1370,6 +1370,7 @@ LIBMDBX_API const char *mdbx_dump_val(const MDBX_val *key, char *const buf,
/**** ENVIRONMENT COPY FLAGS **************************************************/
/* Compacting: Omit free space from copy, and renumber all pages sequentially */
#define MDBX_CP_COMPACT 1u
#define MDBX_CP_FORCE_RESIZEABLE 2u
/**** CURSOR OPERATIONS ********************************************************
*

View File

@ -15258,16 +15258,32 @@ static __cold void compact_fixup_meta(MDBX_env *env, MDBX_meta *meta) {
meta->mm_datasync_sign = mdbx_meta_sign(meta);
}
/* Make resizeable */
static __cold void make_sizeable(MDBX_meta *meta) {
meta->mm_geo.lower = MIN_PAGENO;
if (meta->mm_geo.grow == 0) {
const size_t step = 1 + (meta->mm_geo.upper - meta->mm_geo.lower) / 42;
meta->mm_geo.grow = (step < UINT16_MAX) ? (uint16_t)step : UINT16_MAX;
}
if (meta->mm_geo.shrink == 0) {
const size_t step = meta->mm_geo.grow + meta->mm_geo.grow;
meta->mm_geo.shrink = (step < UINT16_MAX) ? (uint16_t)step : UINT16_MAX;
}
}
/* Copy environment with compaction. */
static int __cold mdbx_env_compact(MDBX_env *env, MDBX_txn *read_txn,
mdbx_filehandle_t fd, uint8_t *buffer,
const bool dest_is_pipe) {
const bool dest_is_pipe, const int flags) {
const size_t meta_bytes = pgno2bytes(env, NUM_METAS);
uint8_t *const data_buffer =
buffer + ceil_powerof2(meta_bytes, env->me_os_psize);
MDBX_meta *const meta = mdbx_init_metas(env, buffer);
mdbx_meta_set_txnid(env, meta, read_txn->mt_txnid);
if (flags & MDBX_CP_FORCE_RESIZEABLE)
make_sizeable(meta);
/* copy canary sequenses if present */
if (read_txn->mt_canary.v) {
meta->mm_canary = read_txn->mt_canary;
@ -15395,7 +15411,7 @@ static int __cold mdbx_env_compact(MDBX_env *env, MDBX_txn *read_txn,
/* Copy environment as-is. */
static int __cold mdbx_env_copy_asis(MDBX_env *env, MDBX_txn *read_txn,
mdbx_filehandle_t fd, uint8_t *buffer,
const bool dest_is_pipe) {
const bool dest_is_pipe, const int flags) {
/* We must start the actual read txn after blocking writers */
int rc = mdbx_txn_end(read_txn, MDBX_END_RESET_TMP);
if (unlikely(rc != MDBX_SUCCESS))
@ -15419,9 +15435,12 @@ static int __cold mdbx_env_copy_asis(MDBX_env *env, MDBX_txn *read_txn,
memcpy(buffer, env->me_map, meta_bytes);
MDBX_meta *const headcopy = /* LY: get pointer to the spanshot copy */
(MDBX_meta *)(buffer + ((uint8_t *)mdbx_meta_head(env) - env->me_map));
mdbx_txn_unlock(env);
if (flags & MDBX_CP_FORCE_RESIZEABLE)
make_sizeable(headcopy);
/* Update signature to steady */
headcopy->mm_datasync_sign = mdbx_meta_sign(headcopy);
mdbx_txn_unlock(env);
/* Copy the data */
const size_t whole_size = pgno_align2os_bytes(env, read_txn->mt_end_pgno);
@ -15537,9 +15556,8 @@ int __cold mdbx_env_copy2fd(MDBX_env *env, mdbx_filehandle_t fd,
if (likely(rc == MDBX_SUCCESS)) {
memset(buffer, 0, pgno2bytes(env, NUM_METAS));
rc = (flags & MDBX_CP_COMPACT)
? mdbx_env_compact(env, read_txn, fd, buffer, dest_is_pipe)
: mdbx_env_copy_asis(env, read_txn, fd, buffer, dest_is_pipe);
rc = ((flags & MDBX_CP_COMPACT) ? mdbx_env_compact : mdbx_env_copy_asis)(
env, read_txn, fd, buffer, dest_is_pipe, flags);
}
mdbx_txn_abort(read_txn);