mirror of
https://github.com/isar/libmdbx.git
synced 2025-01-02 00:54:14 +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 **************************************************/
|
||||
/* Compacting: Omit free space from copy, and renumber all pages sequentially */
|
||||
#define MDBX_CP_COMPACT 1u
|
||||
#define MDBX_CP_FORCE_RESIZEABLE 2u
|
||||
|
||||
/**** 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);
|
||||
}
|
||||
|
||||
/* 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);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user