mirror of
https://github.com/isar/libmdbx.git
synced 2024-12-30 02:04:12 +08:00
mdbx: packing the 16-bit representations of grow step
and shrink threshold
values.
Using float point (exponential quantized) representation for internal 16-bit values of grow step and shrink threshold when huge ones . To minimize the impact on compatibility, only the odd values inside the upper half of the range (i.e. 32769..65533) are used for the new representation. Resolve https://github.com/erthink/libmdbx/issues/166 Change-Id: I273127c1842deef0d7d8885b55a805b1463556eb
This commit is contained in:
parent
57af1d2310
commit
8e51a10908
@ -23,6 +23,10 @@ New features:
|
||||
The `MDBX_DISABLE_PAGECHECKS=1` provides a performance boost of about 10% in CRUD scenarios,
|
||||
and conjointly with the `MDBX_ENV_CHECKPID=0` and `MDBX_TXN_CHECKOWNER=0` options can yield
|
||||
up to 30% more performance compared to LMDB.
|
||||
- Using float point (exponential quantized) representation for internal 16-bit values
|
||||
of grow step and shrink threshold when huge ones (https://github.com/erthink/libmdbx/issues/166).
|
||||
To minimize the impact on compatibility, only the odd values inside the upper half
|
||||
of the range (i.e. 32769..65533) are used for the new representation.
|
||||
|
||||
Fixes:
|
||||
|
||||
|
238
src/core.c
238
src/core.c
@ -57,6 +57,59 @@ MDBX_NOTHROW_CONST_FUNCTION static unsigned log2n(size_t value) {
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Pack/Unpack 16-bit values for Grow step & Shrink threshold */
|
||||
MDBX_NOTHROW_CONST_FUNCTION static __inline pgno_t me2v(unsigned m,
|
||||
unsigned e) {
|
||||
assert(m < 2048 && e < 8);
|
||||
return (pgno_t)(32768 + ((m + 1) << (e + 5)));
|
||||
}
|
||||
|
||||
MDBX_NOTHROW_CONST_FUNCTION static __inline uint16_t v2me(size_t v,
|
||||
unsigned e) {
|
||||
assert(v > (e ? me2v(2047, e - 1) : 32768));
|
||||
assert(v <= me2v(2047, e));
|
||||
size_t m = (v - 32768 + (1 << (e + 5)) - 1) >> (e + 5);
|
||||
m -= m > 0;
|
||||
assert(m < 2048 && e < 8);
|
||||
// f e d c b a 9 8 7 6 5 4 3 2 1 0
|
||||
// 1 e e e m m m m m m m m m m m 1
|
||||
const uint16_t pv = (uint16_t)(0x8001 + (e << 12) + (m << 1));
|
||||
assert(pv != 65535);
|
||||
return pv;
|
||||
}
|
||||
|
||||
/* Convert 16-bit packed (exponential quantized) value to number of pages */
|
||||
MDBX_NOTHROW_CONST_FUNCTION static pgno_t pv2pages(uint16_t pv) {
|
||||
if ((pv & 0x8001) != 0x8001)
|
||||
return pv;
|
||||
if (pv == 65535)
|
||||
return 65536;
|
||||
// f e d c b a 9 8 7 6 5 4 3 2 1 0
|
||||
// 1 e e e m m m m m m m m m m m 1
|
||||
return me2v((pv >> 1) & 2047, (pv >> 12) & 7);
|
||||
}
|
||||
|
||||
/* Convert number of pages to 16-bit packed (exponential quantized) value */
|
||||
MDBX_NOTHROW_CONST_FUNCTION static uint16_t pages2pv(size_t pages) {
|
||||
if (pages < 32769 || (pages < 65536 && (pages & 1) == 0))
|
||||
return (uint16_t)pages;
|
||||
if (pages <= me2v(2047, 0))
|
||||
return v2me(pages, 0);
|
||||
if (pages <= me2v(2047, 1))
|
||||
return v2me(pages, 1);
|
||||
if (pages <= me2v(2047, 2))
|
||||
return v2me(pages, 2);
|
||||
if (pages <= me2v(2047, 3))
|
||||
return v2me(pages, 3);
|
||||
if (pages <= me2v(2047, 4))
|
||||
return v2me(pages, 4);
|
||||
if (pages <= me2v(2047, 5))
|
||||
return v2me(pages, 5);
|
||||
if (pages <= me2v(2047, 6))
|
||||
return v2me(pages, 6);
|
||||
return (pages < me2v(2046, 7)) ? v2me(pages, 7) : 65533;
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Unaligned access */
|
||||
|
||||
@ -1296,6 +1349,17 @@ __cold void mdbx_rthc_global_init(void) {
|
||||
}
|
||||
|
||||
bootid = mdbx_osal_bootid();
|
||||
#if 0 /* debug */
|
||||
for (unsigned i = 0; i < 65536; ++i) {
|
||||
size_t pages = pv2pages(i);
|
||||
unsigned x = pages2pv(pages);
|
||||
size_t xp = pv2pages(x);
|
||||
if (!(x == i || (x % 2 == 0 && x < 65536)) || pages != xp)
|
||||
printf("%u => %zu => %u => %zu\n", i, pages, x, xp);
|
||||
assert(pages == xp);
|
||||
}
|
||||
fflush(stdout);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* dtor called for thread, i.e. for all mdbx's environment objects */
|
||||
@ -6072,10 +6136,11 @@ no_loose:
|
||||
rc = MDBX_NOTFOUND;
|
||||
if (flags & MDBX_ALLOC_NEW) {
|
||||
rc = MDBX_MAP_FULL;
|
||||
if (next <= txn->mt_geo.upper && txn->mt_geo.grow) {
|
||||
if (next <= txn->mt_geo.upper && txn->mt_geo.grow_pv) {
|
||||
mdbx_assert(env, next > txn->mt_end_pgno);
|
||||
const pgno_t grow_step = pv2pages(txn->mt_geo.grow_pv);
|
||||
pgno_t aligned = pgno_align2os_pgno(
|
||||
env, pgno_add(next, txn->mt_geo.grow - next % txn->mt_geo.grow));
|
||||
env, pgno_add(next, grow_step - next % grow_step));
|
||||
|
||||
if (aligned > txn->mt_geo.upper)
|
||||
aligned = txn->mt_geo.upper;
|
||||
@ -9681,7 +9746,7 @@ mdbx_validate_meta(MDBX_env *env, MDBX_meta *const meta, uint64_t *filesize,
|
||||
page->mp_pgno, meta->mm_dbs[MAIN_DBI].md_root,
|
||||
meta->mm_dbs[FREE_DBI].md_root, meta->mm_geo.lower,
|
||||
meta->mm_geo.next, meta->mm_geo.now, meta->mm_geo.upper,
|
||||
meta->mm_geo.grow, meta->mm_geo.shrink,
|
||||
pv2pages(meta->mm_geo.grow_pv), pv2pages(meta->mm_geo.shrink_pv),
|
||||
unaligned_peek_u64(4, meta->mm_txnid_a), mdbx_durable_str(meta));
|
||||
|
||||
/* LY: check min-pages value */
|
||||
@ -9935,8 +10000,9 @@ static MDBX_page *__cold mdbx_meta_model(const MDBX_env *env, MDBX_page *model,
|
||||
|
||||
model_meta->mm_geo.lower = bytes2pgno(env, env->me_dbgeo.lower);
|
||||
model_meta->mm_geo.upper = bytes2pgno(env, env->me_dbgeo.upper);
|
||||
model_meta->mm_geo.grow = (uint16_t)bytes2pgno(env, env->me_dbgeo.grow);
|
||||
model_meta->mm_geo.shrink = (uint16_t)bytes2pgno(env, env->me_dbgeo.shrink);
|
||||
model_meta->mm_geo.grow_pv = pages2pv(bytes2pgno(env, env->me_dbgeo.grow));
|
||||
model_meta->mm_geo.shrink_pv =
|
||||
pages2pv(bytes2pgno(env, env->me_dbgeo.shrink));
|
||||
model_meta->mm_geo.now = bytes2pgno(env, env->me_dbgeo.now);
|
||||
model_meta->mm_geo.next = NUM_METAS;
|
||||
|
||||
@ -9946,10 +10012,10 @@ static MDBX_page *__cold mdbx_meta_model(const MDBX_env *env, MDBX_page *model,
|
||||
mdbx_ensure(env, model_meta->mm_geo.now <= model_meta->mm_geo.upper);
|
||||
mdbx_ensure(env, model_meta->mm_geo.next >= MIN_PAGENO);
|
||||
mdbx_ensure(env, model_meta->mm_geo.next <= model_meta->mm_geo.now);
|
||||
mdbx_ensure(env,
|
||||
model_meta->mm_geo.grow == bytes2pgno(env, env->me_dbgeo.grow));
|
||||
mdbx_ensure(env, model_meta->mm_geo.shrink ==
|
||||
bytes2pgno(env, env->me_dbgeo.shrink));
|
||||
mdbx_ensure(env, model_meta->mm_geo.grow_pv ==
|
||||
pages2pv(pv2pages(model_meta->mm_geo.grow_pv)));
|
||||
mdbx_ensure(env, model_meta->mm_geo.shrink_pv ==
|
||||
pages2pv(pv2pages(model_meta->mm_geo.shrink_pv)));
|
||||
|
||||
model_meta->mm_psize = env->me_psize;
|
||||
model_meta->mm_flags = (uint16_t)env->me_flags;
|
||||
@ -10074,13 +10140,17 @@ static int mdbx_sync_locked(MDBX_env *env, unsigned flags,
|
||||
|
||||
/* LY: check conditions to shrink datafile */
|
||||
const pgno_t backlog_gap = 3 + pending->mm_dbs[FREE_DBI].md_depth * 3;
|
||||
if (pending->mm_geo.shrink && pending->mm_geo.now - pending->mm_geo.next >
|
||||
pending->mm_geo.shrink + backlog_gap) {
|
||||
pgno_t shrink_step = 0;
|
||||
if (pending->mm_geo.shrink_pv &&
|
||||
pending->mm_geo.now - pending->mm_geo.next >
|
||||
(shrink_step = pv2pages(pending->mm_geo.shrink_pv)) + backlog_gap) {
|
||||
if (pending->mm_geo.now > largest_pgno &&
|
||||
pending->mm_geo.now - largest_pgno >
|
||||
pending->mm_geo.shrink + backlog_gap) {
|
||||
const pgno_t aligner = pending->mm_geo.grow ? pending->mm_geo.grow
|
||||
: pending->mm_geo.shrink;
|
||||
pending->mm_geo.now - largest_pgno > shrink_step + backlog_gap) {
|
||||
pgno_t grow_step = 0;
|
||||
const pgno_t aligner =
|
||||
pending->mm_geo.grow_pv
|
||||
? (grow_step = pv2pages(pending->mm_geo.grow_pv))
|
||||
: shrink_step;
|
||||
const pgno_t with_backlog_gap = largest_pgno + backlog_gap;
|
||||
const pgno_t aligned = pgno_align2os_pgno(
|
||||
env, with_backlog_gap + aligner - with_backlog_gap % aligner);
|
||||
@ -10168,15 +10238,15 @@ static int mdbx_sync_locked(MDBX_env *env, unsigned flags,
|
||||
}
|
||||
|
||||
/* LY: step#2 - update meta-page. */
|
||||
mdbx_debug("writing meta%" PRIaPGNO " = root %" PRIaPGNO "/%" PRIaPGNO
|
||||
", geo %" PRIaPGNO "/%" PRIaPGNO "-%" PRIaPGNO "/%" PRIaPGNO
|
||||
" +%u -%u, txn_id %" PRIaTXN ", %s",
|
||||
data_page(target)->mp_pgno, pending->mm_dbs[MAIN_DBI].md_root,
|
||||
pending->mm_dbs[FREE_DBI].md_root, pending->mm_geo.lower,
|
||||
pending->mm_geo.next, pending->mm_geo.now, pending->mm_geo.upper,
|
||||
pending->mm_geo.grow, pending->mm_geo.shrink,
|
||||
unaligned_peek_u64(4, pending->mm_txnid_a),
|
||||
mdbx_durable_str(pending));
|
||||
mdbx_debug(
|
||||
"writing meta%" PRIaPGNO " = root %" PRIaPGNO "/%" PRIaPGNO
|
||||
", geo %" PRIaPGNO "/%" PRIaPGNO "-%" PRIaPGNO "/%" PRIaPGNO
|
||||
" +%u -%u, txn_id %" PRIaTXN ", %s",
|
||||
data_page(target)->mp_pgno, pending->mm_dbs[MAIN_DBI].md_root,
|
||||
pending->mm_dbs[FREE_DBI].md_root, pending->mm_geo.lower,
|
||||
pending->mm_geo.next, pending->mm_geo.now, pending->mm_geo.upper,
|
||||
pv2pages(pending->mm_geo.grow_pv), pv2pages(pending->mm_geo.shrink_pv),
|
||||
unaligned_peek_u64(4, pending->mm_txnid_a), mdbx_durable_str(pending));
|
||||
|
||||
mdbx_debug("meta0: %s, %s, txn_id %" PRIaTXN ", root %" PRIaPGNO
|
||||
"/%" PRIaPGNO,
|
||||
@ -10458,9 +10528,9 @@ mdbx_env_set_geometry(MDBX_env *env, intptr_t size_lower, intptr_t size_now,
|
||||
if (size_upper < 0)
|
||||
size_upper = pgno2bytes(env, head->mm_geo.upper);
|
||||
if (growth_step < 0)
|
||||
growth_step = pgno2bytes(env, head->mm_geo.grow);
|
||||
growth_step = pgno2bytes(env, pv2pages(head->mm_geo.grow_pv));
|
||||
if (shrink_threshold < 0)
|
||||
shrink_threshold = pgno2bytes(env, head->mm_geo.shrink);
|
||||
shrink_threshold = pgno2bytes(env, pv2pages(head->mm_geo.shrink_pv));
|
||||
|
||||
if (pagesize != (intptr_t)env->me_psize) {
|
||||
rc = MDBX_EINVAL;
|
||||
@ -10603,21 +10673,18 @@ mdbx_env_set_geometry(MDBX_env *env, intptr_t size_lower, intptr_t size_now,
|
||||
if (growth_step == 0 && shrink_threshold > 0)
|
||||
growth_step = 1;
|
||||
growth_step = ceil_powerof2(growth_step, unit);
|
||||
if (bytes2pgno(env, growth_step) > UINT16_MAX)
|
||||
growth_step = pgno2bytes(env, UINT16_MAX);
|
||||
|
||||
if (shrink_threshold < 0)
|
||||
shrink_threshold = growth_step + growth_step;
|
||||
shrink_threshold = ceil_powerof2(shrink_threshold, unit);
|
||||
if (bytes2pgno(env, shrink_threshold) > UINT16_MAX)
|
||||
shrink_threshold = pgno2bytes(env, UINT16_MAX);
|
||||
|
||||
/* save user's geo-params for future open/create */
|
||||
env->me_dbgeo.lower = size_lower;
|
||||
env->me_dbgeo.now = size_now;
|
||||
env->me_dbgeo.upper = size_upper;
|
||||
env->me_dbgeo.grow = growth_step;
|
||||
env->me_dbgeo.shrink = shrink_threshold;
|
||||
env->me_dbgeo.grow = pv2pages(pages2pv(growth_step / pagesize)) * pagesize;
|
||||
env->me_dbgeo.shrink =
|
||||
pv2pages(pages2pv(shrink_threshold / pagesize)) * pagesize;
|
||||
rc = MDBX_SUCCESS;
|
||||
|
||||
mdbx_ensure(env, pagesize >= MIN_PAGESIZE);
|
||||
@ -10650,7 +10717,7 @@ mdbx_env_set_geometry(MDBX_env *env, intptr_t size_lower, intptr_t size_now,
|
||||
mdbx_ensure(env, pagesize == (intptr_t)env->me_psize);
|
||||
MDBX_meta meta;
|
||||
MDBX_meta *head = nullptr;
|
||||
const mdbx_geo_t *current_geo;
|
||||
const MDBX_geo *current_geo;
|
||||
if (inside_txn) {
|
||||
current_geo = &env->me_txn->mt_geo;
|
||||
} else {
|
||||
@ -10659,12 +10726,12 @@ mdbx_env_set_geometry(MDBX_env *env, intptr_t size_lower, intptr_t size_now,
|
||||
current_geo = &meta.mm_geo;
|
||||
}
|
||||
|
||||
mdbx_geo_t new_geo;
|
||||
MDBX_geo new_geo;
|
||||
new_geo.lower = bytes2pgno(env, env->me_dbgeo.lower);
|
||||
new_geo.now = bytes2pgno(env, env->me_dbgeo.now);
|
||||
new_geo.upper = bytes2pgno(env, env->me_dbgeo.upper);
|
||||
new_geo.grow = (uint16_t)bytes2pgno(env, env->me_dbgeo.grow);
|
||||
new_geo.shrink = (uint16_t)bytes2pgno(env, env->me_dbgeo.shrink);
|
||||
new_geo.grow_pv = pages2pv(bytes2pgno(env, env->me_dbgeo.grow));
|
||||
new_geo.shrink_pv = pages2pv(bytes2pgno(env, env->me_dbgeo.shrink));
|
||||
new_geo.next = current_geo->next;
|
||||
|
||||
mdbx_ensure(env,
|
||||
@ -10673,10 +10740,9 @@ mdbx_env_set_geometry(MDBX_env *env, intptr_t size_lower, intptr_t size_now,
|
||||
pgno_align2os_bytes(env, new_geo.upper) == env->me_dbgeo.upper);
|
||||
mdbx_ensure(env,
|
||||
pgno_align2os_bytes(env, new_geo.now) == env->me_dbgeo.now);
|
||||
mdbx_ensure(env, new_geo.grow_pv == pages2pv(pv2pages(new_geo.grow_pv)));
|
||||
mdbx_ensure(env,
|
||||
pgno_align2os_bytes(env, new_geo.grow) == env->me_dbgeo.grow);
|
||||
mdbx_ensure(env, pgno_align2os_bytes(env, new_geo.shrink) ==
|
||||
env->me_dbgeo.shrink);
|
||||
new_geo.shrink_pv == pages2pv(pv2pages(new_geo.shrink_pv)));
|
||||
|
||||
mdbx_ensure(env, env->me_dbgeo.lower >= MIN_MAPSIZE);
|
||||
mdbx_ensure(env, new_geo.lower >= MIN_PAGENO);
|
||||
@ -10686,11 +10752,12 @@ mdbx_env_set_geometry(MDBX_env *env, intptr_t size_lower, intptr_t size_now,
|
||||
mdbx_ensure(env, new_geo.upper >= new_geo.now);
|
||||
mdbx_ensure(env, new_geo.now >= new_geo.lower);
|
||||
|
||||
if (memcmp(current_geo, &new_geo, sizeof(mdbx_geo_t)) != 0) {
|
||||
if (memcmp(current_geo, &new_geo, sizeof(MDBX_geo)) != 0) {
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
/* Was DB shrinking disabled before and now it will be enabled? */
|
||||
if (new_geo.lower < new_geo.upper && new_geo.shrink &&
|
||||
!(current_geo->lower < current_geo->upper && current_geo->shrink)) {
|
||||
if (new_geo.lower < new_geo.upper && new_geo.shrink_pv &&
|
||||
!(current_geo->lower < current_geo->upper &&
|
||||
current_geo->shrink_pv)) {
|
||||
if (!env->me_lck) {
|
||||
rc = MDBX_EPERM;
|
||||
goto bailout;
|
||||
@ -10823,13 +10890,13 @@ static __cold int mdbx_setup_dxb(MDBX_env *env, const int lck_rc) {
|
||||
#endif
|
||||
}
|
||||
|
||||
mdbx_verbose("header: root %" PRIaPGNO "/%" PRIaPGNO ", geo %" PRIaPGNO
|
||||
"/%" PRIaPGNO "-%" PRIaPGNO "/%" PRIaPGNO
|
||||
" +%u -%u, txn_id %" PRIaTXN ", %s",
|
||||
meta.mm_dbs[MAIN_DBI].md_root, meta.mm_dbs[FREE_DBI].md_root,
|
||||
meta.mm_geo.lower, meta.mm_geo.next, meta.mm_geo.now,
|
||||
meta.mm_geo.upper, meta.mm_geo.grow, meta.mm_geo.shrink,
|
||||
unaligned_peek_u64(4, meta.mm_txnid_a), mdbx_durable_str(&meta));
|
||||
mdbx_verbose(
|
||||
"header: root %" PRIaPGNO "/%" PRIaPGNO ", geo %" PRIaPGNO "/%" PRIaPGNO
|
||||
"-%" PRIaPGNO "/%" PRIaPGNO " +%u -%u, txn_id %" PRIaTXN ", %s",
|
||||
meta.mm_dbs[MAIN_DBI].md_root, meta.mm_dbs[FREE_DBI].md_root,
|
||||
meta.mm_geo.lower, meta.mm_geo.next, meta.mm_geo.now, meta.mm_geo.upper,
|
||||
pv2pages(meta.mm_geo.grow_pv), pv2pages(meta.mm_geo.shrink_pv),
|
||||
unaligned_peek_u64(4, meta.mm_txnid_a), mdbx_durable_str(&meta));
|
||||
|
||||
mdbx_setup_pagesize(env, meta.mm_psize);
|
||||
const size_t used_bytes = pgno2bytes(env, meta.mm_geo.next);
|
||||
@ -10842,8 +10909,8 @@ static __cold int mdbx_setup_dxb(MDBX_env *env, const int lck_rc) {
|
||||
const size_t pagesize = meta.mm_psize;
|
||||
err = mdbx_env_set_geometry(
|
||||
env, meta.mm_geo.lower * pagesize, meta.mm_geo.now * pagesize,
|
||||
meta.mm_geo.upper * pagesize, meta.mm_geo.grow * pagesize,
|
||||
meta.mm_geo.shrink * pagesize, meta.mm_psize);
|
||||
meta.mm_geo.upper * pagesize, pv2pages(meta.mm_geo.grow_pv) * pagesize,
|
||||
pv2pages(meta.mm_geo.shrink_pv) * pagesize, meta.mm_psize);
|
||||
if (unlikely(err != MDBX_SUCCESS)) {
|
||||
mdbx_error("%s: err %d", "could not apply preconfigured geometry from db",
|
||||
err);
|
||||
@ -10865,9 +10932,9 @@ static __cold int mdbx_setup_dxb(MDBX_env *env, const int lck_rc) {
|
||||
bytes_align2os_bytes(env, env->me_dbgeo.lower) !=
|
||||
pgno2bytes(env, meta.mm_geo.lower) ||
|
||||
bytes_align2os_bytes(env, env->me_dbgeo.shrink) !=
|
||||
pgno2bytes(env, meta.mm_geo.shrink) ||
|
||||
pgno2bytes(env, pv2pages(meta.mm_geo.shrink_pv)) ||
|
||||
bytes_align2os_bytes(env, env->me_dbgeo.grow) !=
|
||||
pgno2bytes(env, meta.mm_geo.grow)) {
|
||||
pgno2bytes(env, pv2pages(meta.mm_geo.grow_pv))) {
|
||||
|
||||
if (env->me_dbgeo.shrink && env->me_dbgeo.now > used_bytes)
|
||||
/* pre-shrink if enabled */
|
||||
@ -10887,15 +10954,16 @@ static __cold int mdbx_setup_dxb(MDBX_env *env, const int lck_rc) {
|
||||
meta.mm_geo.now = bytes2pgno(env, env->me_dbgeo.now);
|
||||
meta.mm_geo.lower = bytes2pgno(env, env->me_dbgeo.lower);
|
||||
meta.mm_geo.upper = bytes2pgno(env, env->me_dbgeo.upper);
|
||||
meta.mm_geo.grow = (uint16_t)bytes2pgno(env, env->me_dbgeo.grow);
|
||||
meta.mm_geo.shrink = (uint16_t)bytes2pgno(env, env->me_dbgeo.shrink);
|
||||
meta.mm_geo.grow_pv = pages2pv(bytes2pgno(env, env->me_dbgeo.grow));
|
||||
meta.mm_geo.shrink_pv = pages2pv(bytes2pgno(env, env->me_dbgeo.shrink));
|
||||
|
||||
mdbx_verbose("amended: root %" PRIaPGNO "/%" PRIaPGNO ", geo %" PRIaPGNO
|
||||
"/%" PRIaPGNO "-%" PRIaPGNO "/%" PRIaPGNO
|
||||
" +%u -%u, txn_id %" PRIaTXN ", %s",
|
||||
meta.mm_dbs[MAIN_DBI].md_root, meta.mm_dbs[FREE_DBI].md_root,
|
||||
meta.mm_geo.lower, meta.mm_geo.next, meta.mm_geo.now,
|
||||
meta.mm_geo.upper, meta.mm_geo.grow, meta.mm_geo.shrink,
|
||||
meta.mm_geo.upper, pv2pages(meta.mm_geo.grow_pv),
|
||||
pv2pages(meta.mm_geo.shrink_pv),
|
||||
unaligned_peek_u64(4, meta.mm_txnid_a),
|
||||
mdbx_durable_str(&meta));
|
||||
} else {
|
||||
@ -10910,8 +10978,8 @@ static __cold int mdbx_setup_dxb(MDBX_env *env, const int lck_rc) {
|
||||
env->me_dbgeo.now = pgno2bytes(env, meta.mm_geo.now);
|
||||
env->me_dbgeo.lower = pgno2bytes(env, meta.mm_geo.lower);
|
||||
env->me_dbgeo.upper = pgno2bytes(env, meta.mm_geo.upper);
|
||||
env->me_dbgeo.grow = pgno2bytes(env, meta.mm_geo.grow);
|
||||
env->me_dbgeo.shrink = pgno2bytes(env, meta.mm_geo.shrink);
|
||||
env->me_dbgeo.grow = pgno2bytes(env, pv2pages(meta.mm_geo.grow_pv));
|
||||
env->me_dbgeo.shrink = pgno2bytes(env, pv2pages(meta.mm_geo.shrink_pv));
|
||||
}
|
||||
|
||||
mdbx_ensure(env,
|
||||
@ -11133,14 +11201,15 @@ static __cold int mdbx_setup_dxb(MDBX_env *env, const int lck_rc) {
|
||||
if (memcmp(&meta.mm_geo, &head->mm_geo, sizeof(meta.mm_geo))) {
|
||||
if ((env->me_flags & MDBX_RDONLY) != 0 ||
|
||||
/* recovery mode */ env->me_stuck_meta >= 0) {
|
||||
mdbx_warning("skipped update meta.geo in %s mode: from l%" PRIaPGNO
|
||||
"-n%" PRIaPGNO "-u%" PRIaPGNO "/s%u-g%u, to l%" PRIaPGNO
|
||||
"-n%" PRIaPGNO "-u%" PRIaPGNO "/s%u-g%u",
|
||||
(env->me_stuck_meta < 0) ? "read-only" : "recovery",
|
||||
head->mm_geo.lower, head->mm_geo.now, head->mm_geo.upper,
|
||||
head->mm_geo.shrink, head->mm_geo.grow, meta.mm_geo.lower,
|
||||
meta.mm_geo.now, meta.mm_geo.upper, meta.mm_geo.shrink,
|
||||
meta.mm_geo.grow);
|
||||
mdbx_warning(
|
||||
"skipped update meta.geo in %s mode: from l%" PRIaPGNO
|
||||
"-n%" PRIaPGNO "-u%" PRIaPGNO "/s%u-g%u, to l%" PRIaPGNO
|
||||
"-n%" PRIaPGNO "-u%" PRIaPGNO "/s%u-g%u",
|
||||
(env->me_stuck_meta < 0) ? "read-only" : "recovery",
|
||||
head->mm_geo.lower, head->mm_geo.now, head->mm_geo.upper,
|
||||
pv2pages(head->mm_geo.shrink_pv), pv2pages(head->mm_geo.grow_pv),
|
||||
meta.mm_geo.lower, meta.mm_geo.now, meta.mm_geo.upper,
|
||||
pv2pages(meta.mm_geo.shrink_pv), pv2pages(meta.mm_geo.grow_pv));
|
||||
} else {
|
||||
const txnid_t txnid = mdbx_meta_txnid_stable(env, head);
|
||||
const txnid_t next_txnid = safe64_txnid_next(txnid);
|
||||
@ -11154,9 +11223,11 @@ static __cold int mdbx_setup_dxb(MDBX_env *env, const int lck_rc) {
|
||||
"to l%" PRIaPGNO "-n%" PRIaPGNO "-u%" PRIaPGNO
|
||||
"/s%u-g%u (txn#%" PRIaTXN ")",
|
||||
head->mm_geo.lower, head->mm_geo.now, head->mm_geo.upper,
|
||||
head->mm_geo.shrink, head->mm_geo.grow, txnid,
|
||||
meta.mm_geo.lower, meta.mm_geo.now, meta.mm_geo.upper,
|
||||
meta.mm_geo.shrink, meta.mm_geo.grow, next_txnid);
|
||||
pv2pages(head->mm_geo.shrink_pv),
|
||||
pv2pages(head->mm_geo.grow_pv), txnid, meta.mm_geo.lower,
|
||||
meta.mm_geo.now, meta.mm_geo.upper,
|
||||
pv2pages(meta.mm_geo.shrink_pv),
|
||||
pv2pages(meta.mm_geo.grow_pv), next_txnid);
|
||||
|
||||
mdbx_ensure(env, mdbx_meta_eq(env, &meta, head));
|
||||
mdbx_meta_set_txnid(env, &meta, next_txnid);
|
||||
@ -11168,10 +11239,11 @@ static __cold int mdbx_setup_dxb(MDBX_env *env, const int lck_rc) {
|
||||
"to l%" PRIaPGNO "-n%" PRIaPGNO "-u%" PRIaPGNO
|
||||
"/s%u-g%u (txn#%" PRIaTXN ")",
|
||||
err, head->mm_geo.lower, head->mm_geo.now,
|
||||
head->mm_geo.upper, head->mm_geo.shrink, head->mm_geo.grow,
|
||||
txnid, meta.mm_geo.lower, meta.mm_geo.now,
|
||||
meta.mm_geo.upper, meta.mm_geo.shrink, meta.mm_geo.grow,
|
||||
next_txnid);
|
||||
head->mm_geo.upper, pv2pages(head->mm_geo.shrink_pv),
|
||||
pv2pages(head->mm_geo.grow_pv), txnid, meta.mm_geo.lower,
|
||||
meta.mm_geo.now, meta.mm_geo.upper,
|
||||
pv2pages(meta.mm_geo.shrink_pv),
|
||||
pv2pages(meta.mm_geo.grow_pv), next_txnid);
|
||||
return err;
|
||||
}
|
||||
}
|
||||
@ -17729,8 +17801,8 @@ static __cold void compact_fixup_meta(MDBX_env *env, MDBX_meta *meta) {
|
||||
/* Calculate filesize taking in account shrink/growing thresholds */
|
||||
if (meta->mm_geo.next != meta->mm_geo.now) {
|
||||
meta->mm_geo.now = meta->mm_geo.next;
|
||||
const pgno_t aligner =
|
||||
meta->mm_geo.grow ? meta->mm_geo.grow : meta->mm_geo.shrink;
|
||||
const pgno_t aligner = pv2pages(
|
||||
meta->mm_geo.grow_pv ? meta->mm_geo.grow_pv : meta->mm_geo.shrink_pv);
|
||||
if (aligner) {
|
||||
const pgno_t aligned = pgno_align2os_pgno(
|
||||
env, meta->mm_geo.next + aligner - meta->mm_geo.next % aligner);
|
||||
@ -17751,13 +17823,13 @@ static __cold void compact_fixup_meta(MDBX_env *env, MDBX_meta *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.grow_pv == 0) {
|
||||
const pgno_t step = 1 + (meta->mm_geo.upper - meta->mm_geo.lower) / 42;
|
||||
meta->mm_geo.grow_pv = pages2pv(step);
|
||||
}
|
||||
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;
|
||||
if (meta->mm_geo.shrink_pv == 0) {
|
||||
const pgno_t step = pv2pages(meta->mm_geo.grow_pv) << 1;
|
||||
meta->mm_geo.shrink_pv = pages2pv(step);
|
||||
}
|
||||
}
|
||||
|
||||
@ -18410,8 +18482,8 @@ __cold int mdbx_env_info_ex(const MDBX_env *env, const MDBX_txn *txn,
|
||||
}
|
||||
arg->mi_geo.lower = pgno2bytes(env, txn_meta->mm_geo.lower);
|
||||
arg->mi_geo.upper = pgno2bytes(env, txn_meta->mm_geo.upper);
|
||||
arg->mi_geo.shrink = pgno2bytes(env, txn_meta->mm_geo.shrink);
|
||||
arg->mi_geo.grow = pgno2bytes(env, txn_meta->mm_geo.grow);
|
||||
arg->mi_geo.shrink = pgno2bytes(env, pv2pages(txn_meta->mm_geo.shrink_pv));
|
||||
arg->mi_geo.grow = pgno2bytes(env, pv2pages(txn_meta->mm_geo.grow_pv));
|
||||
unsynced_pages = atomic_load32(env->me_unsynced_pages, mo_Relaxed) +
|
||||
(atomic_load32(env->me_meta_sync_txnid, mo_Relaxed) !=
|
||||
(uint32_t)arg->mi_last_pgno);
|
||||
|
@ -300,15 +300,17 @@ typedef struct MDBX_db {
|
||||
} MDBX_db;
|
||||
|
||||
/* database size-related parameters */
|
||||
typedef struct mdbx_geo_t {
|
||||
uint16_t grow; /* datafile growth step in pages */
|
||||
uint16_t shrink; /* datafile shrink threshold in pages */
|
||||
pgno_t lower; /* minimal size of datafile in pages */
|
||||
pgno_t upper; /* maximal size of datafile in pages */
|
||||
pgno_t now; /* current size of datafile in pages */
|
||||
pgno_t next; /* first unused page in the datafile,
|
||||
* but actually the file may be shorter. */
|
||||
} mdbx_geo_t;
|
||||
typedef struct MDBX_geo {
|
||||
uint16_t grow_pv; /* datafile growth step as a 16-bit packed (exponential
|
||||
quantized) value */
|
||||
uint16_t shrink_pv; /* datafile shrink threshold as a 16-bit packed
|
||||
(exponential quantized) value */
|
||||
pgno_t lower; /* minimal size of datafile in pages */
|
||||
pgno_t upper; /* maximal size of datafile in pages */
|
||||
pgno_t now; /* current size of datafile in pages */
|
||||
pgno_t next; /* first unused page in the datafile,
|
||||
but actually the file may be shorter. */
|
||||
} MDBX_geo;
|
||||
|
||||
/* Meta page content.
|
||||
* A meta page is the start point for accessing a database snapshot.
|
||||
@ -327,7 +329,7 @@ typedef struct MDBX_meta {
|
||||
uint8_t mm_extra_pagehdr; /* extra bytes in the page header,
|
||||
* zero (nothing) for now */
|
||||
|
||||
mdbx_geo_t mm_geo; /* database size-related parameters */
|
||||
MDBX_geo mm_geo; /* database size-related parameters */
|
||||
|
||||
MDBX_db mm_dbs[CORE_DBS]; /* first is free space, 2nd is main db */
|
||||
/* The size of pages used in this DB */
|
||||
@ -731,7 +733,7 @@ struct MDBX_txn {
|
||||
MDBX_txn *mt_parent; /* parent of a nested txn */
|
||||
/* Nested txn under this txn, set together with flag MDBX_TXN_HAS_CHILD */
|
||||
MDBX_txn *mt_child;
|
||||
mdbx_geo_t mt_geo;
|
||||
MDBX_geo mt_geo;
|
||||
/* next unallocated page */
|
||||
#define mt_next_pgno mt_geo.next
|
||||
/* corresponding to the current size of datafile */
|
||||
|
Loading…
x
Reference in New Issue
Block a user