mdbx: auto-shrink env's DBI table.

Change-Id: I9f423dab41863119a4491491e0ecd0a4aee42a82
This commit is contained in:
Leonid Yuriev 2020-12-16 18:04:08 +03:00
parent cda64ca663
commit 735da5fedd

View File

@ -6859,7 +6859,7 @@ static void dbi_update(MDBX_txn *txn, int keep) {
MDBX_dbi n = txn->mt_numdbs; MDBX_dbi n = txn->mt_numdbs;
if (n) { if (n) {
bool locked = false; bool locked = false;
MDBX_env *env = txn->mt_env; MDBX_env *const env = txn->mt_env;
for (unsigned i = n; --i >= CORE_DBS;) { for (unsigned i = n; --i >= CORE_DBS;) {
if (likely((txn->mt_dbistate[i] & DBI_CREAT) == 0)) if (likely((txn->mt_dbistate[i] & DBI_CREAT) == 0))
@ -6869,11 +6869,10 @@ static void dbi_update(MDBX_txn *txn, int keep) {
mdbx_fastmutex_acquire(&env->me_dbi_lock) == MDBX_SUCCESS); mdbx_fastmutex_acquire(&env->me_dbi_lock) == MDBX_SUCCESS);
locked = true; locked = true;
} }
if (env->me_numdbs <= i || txn->mt_dbiseqs[i] != env->me_dbiseqs[i])
continue /* dbi explicitly closed and/or then re-opened by other txn */;
if (keep) { if (keep) {
env->me_dbflags[i] = txn->mt_dbs[i].md_flags | DB_VALID; env->me_dbflags[i] = txn->mt_dbs[i].md_flags | DB_VALID;
mdbx_compiler_barrier();
if (env->me_numdbs <= i)
env->me_numdbs = i + 1;
} else { } else {
char *ptr = env->me_dbxs[i].md_name.iov_base; char *ptr = env->me_dbxs[i].md_name.iov_base;
if (ptr) { if (ptr) {
@ -6887,6 +6886,20 @@ static void dbi_update(MDBX_txn *txn, int keep) {
} }
} }
n = env->me_numdbs;
if (n > CORE_DBS && unlikely(!(env->me_dbflags[n - 1] & DB_VALID))) {
if (!locked) {
mdbx_ensure(env,
mdbx_fastmutex_acquire(&env->me_dbi_lock) == MDBX_SUCCESS);
locked = true;
}
n = env->me_numdbs;
while (n > CORE_DBS && !(env->me_dbflags[n - 1] & DB_VALID))
--n;
env->me_numdbs = n;
}
if (unlikely(locked)) if (unlikely(locked))
mdbx_ensure(env, mdbx_ensure(env,
mdbx_fastmutex_release(&env->me_dbi_lock) == MDBX_SUCCESS); mdbx_fastmutex_release(&env->me_dbi_lock) == MDBX_SUCCESS);
@ -17669,10 +17682,15 @@ static int mdbx_dbi_close_locked(MDBX_env *env, MDBX_dbi dbi) {
return MDBX_BAD_DBI; return MDBX_BAD_DBI;
env->me_dbflags[dbi] = 0; env->me_dbflags[dbi] = 0;
env->me_dbiseqs[dbi]++;
env->me_dbxs[dbi].md_name.iov_len = 0; env->me_dbxs[dbi].md_name.iov_len = 0;
mdbx_compiler_barrier(); mdbx_compiler_barrier();
env->me_dbxs[dbi].md_name.iov_base = NULL; env->me_dbxs[dbi].md_name.iov_base = NULL;
mdbx_free(ptr); mdbx_free(ptr);
if (env->me_numdbs == dbi + 1)
env->me_numdbs = dbi;
return MDBX_SUCCESS; return MDBX_SUCCESS;
} }
@ -17686,7 +17704,9 @@ int mdbx_dbi_close(MDBX_env *env, MDBX_dbi dbi) {
rc = mdbx_fastmutex_acquire(&env->me_dbi_lock); rc = mdbx_fastmutex_acquire(&env->me_dbi_lock);
if (likely(rc == MDBX_SUCCESS)) { if (likely(rc == MDBX_SUCCESS)) {
rc = mdbx_dbi_close_locked(env, dbi); rc = (dbi < env->me_maxdbs && (env->me_dbflags[dbi] & DB_VALID))
? mdbx_dbi_close_locked(env, dbi)
: MDBX_BAD_DBI;
mdbx_ensure(env, mdbx_fastmutex_release(&env->me_dbi_lock) == MDBX_SUCCESS); mdbx_ensure(env, mdbx_fastmutex_release(&env->me_dbi_lock) == MDBX_SUCCESS);
} }
return rc; return rc;
@ -17852,7 +17872,6 @@ int mdbx_drop(MDBX_txn *txn, MDBX_dbi dbi, bool del) {
txn->mt_flags |= MDBX_TXN_ERROR; txn->mt_flags |= MDBX_TXN_ERROR;
goto bailout; goto bailout;
} }
env->me_dbiseqs[dbi]++;
mdbx_dbi_close_locked(env, dbi); mdbx_dbi_close_locked(env, dbi);
mdbx_ensure(env, mdbx_ensure(env,
mdbx_fastmutex_release(&env->me_dbi_lock) == MDBX_SUCCESS); mdbx_fastmutex_release(&env->me_dbi_lock) == MDBX_SUCCESS);