mirror of
https://github.com/isar/libmdbx.git
synced 2025-01-04 18:04:13 +08:00
mdbx: add MDBX_CP_FORCE_RESIZEABLE option.
Change-Id: I5fcdae7933dbbfbf8629e8a0423545a4f6b9f6b6
This commit is contained in:
parent
37abc146b4
commit
fac0d47913
1
mdbx.h
1
mdbx.h
@ -1370,6 +1370,7 @@ LIBMDBX_API const char *mdbx_dump_val(const MDBX_val *key, char *const buf,
|
|||||||
/**** ENVIRONMENT COPY FLAGS **************************************************/
|
/**** ENVIRONMENT COPY FLAGS **************************************************/
|
||||||
/* Compacting: Omit free space from copy, and renumber all pages sequentially */
|
/* Compacting: Omit free space from copy, and renumber all pages sequentially */
|
||||||
#define MDBX_CP_COMPACT 1u
|
#define MDBX_CP_COMPACT 1u
|
||||||
|
#define MDBX_CP_FORCE_RESIZEABLE 2u
|
||||||
|
|
||||||
/**** CURSOR OPERATIONS ********************************************************
|
/**** CURSOR OPERATIONS ********************************************************
|
||||||
*
|
*
|
||||||
|
30
src/core.c
30
src/core.c
@ -15258,16 +15258,32 @@ static __cold void compact_fixup_meta(MDBX_env *env, MDBX_meta *meta) {
|
|||||||
meta->mm_datasync_sign = mdbx_meta_sign(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. */
|
/* Copy environment with compaction. */
|
||||||
static int __cold mdbx_env_compact(MDBX_env *env, MDBX_txn *read_txn,
|
static int __cold mdbx_env_compact(MDBX_env *env, MDBX_txn *read_txn,
|
||||||
mdbx_filehandle_t fd, uint8_t *buffer,
|
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);
|
const size_t meta_bytes = pgno2bytes(env, NUM_METAS);
|
||||||
uint8_t *const data_buffer =
|
uint8_t *const data_buffer =
|
||||||
buffer + ceil_powerof2(meta_bytes, env->me_os_psize);
|
buffer + ceil_powerof2(meta_bytes, env->me_os_psize);
|
||||||
MDBX_meta *const meta = mdbx_init_metas(env, buffer);
|
MDBX_meta *const meta = mdbx_init_metas(env, buffer);
|
||||||
mdbx_meta_set_txnid(env, meta, read_txn->mt_txnid);
|
mdbx_meta_set_txnid(env, meta, read_txn->mt_txnid);
|
||||||
|
|
||||||
|
if (flags & MDBX_CP_FORCE_RESIZEABLE)
|
||||||
|
make_sizeable(meta);
|
||||||
|
|
||||||
/* copy canary sequenses if present */
|
/* copy canary sequenses if present */
|
||||||
if (read_txn->mt_canary.v) {
|
if (read_txn->mt_canary.v) {
|
||||||
meta->mm_canary = read_txn->mt_canary;
|
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. */
|
/* Copy environment as-is. */
|
||||||
static int __cold mdbx_env_copy_asis(MDBX_env *env, MDBX_txn *read_txn,
|
static int __cold mdbx_env_copy_asis(MDBX_env *env, MDBX_txn *read_txn,
|
||||||
mdbx_filehandle_t fd, uint8_t *buffer,
|
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 */
|
/* We must start the actual read txn after blocking writers */
|
||||||
int rc = mdbx_txn_end(read_txn, MDBX_END_RESET_TMP);
|
int rc = mdbx_txn_end(read_txn, MDBX_END_RESET_TMP);
|
||||||
if (unlikely(rc != MDBX_SUCCESS))
|
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);
|
memcpy(buffer, env->me_map, meta_bytes);
|
||||||
MDBX_meta *const headcopy = /* LY: get pointer to the spanshot copy */
|
MDBX_meta *const headcopy = /* LY: get pointer to the spanshot copy */
|
||||||
(MDBX_meta *)(buffer + ((uint8_t *)mdbx_meta_head(env) - env->me_map));
|
(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 */
|
/* Update signature to steady */
|
||||||
headcopy->mm_datasync_sign = mdbx_meta_sign(headcopy);
|
headcopy->mm_datasync_sign = mdbx_meta_sign(headcopy);
|
||||||
mdbx_txn_unlock(env);
|
|
||||||
|
|
||||||
/* Copy the data */
|
/* Copy the data */
|
||||||
const size_t whole_size = pgno_align2os_bytes(env, read_txn->mt_end_pgno);
|
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)) {
|
if (likely(rc == MDBX_SUCCESS)) {
|
||||||
memset(buffer, 0, pgno2bytes(env, NUM_METAS));
|
memset(buffer, 0, pgno2bytes(env, NUM_METAS));
|
||||||
rc = (flags & MDBX_CP_COMPACT)
|
rc = ((flags & MDBX_CP_COMPACT) ? mdbx_env_compact : mdbx_env_copy_asis)(
|
||||||
? mdbx_env_compact(env, read_txn, fd, buffer, dest_is_pipe)
|
env, read_txn, fd, buffer, dest_is_pipe, flags);
|
||||||
: mdbx_env_copy_asis(env, read_txn, fd, buffer, dest_is_pipe);
|
|
||||||
}
|
}
|
||||||
mdbx_txn_abort(read_txn);
|
mdbx_txn_abort(read_txn);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user