mirror of
https://github.com/isar/libmdbx.git
synced 2025-12-17 17:32:24 +08:00
Compare commits
11 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
04a91adc70 | ||
|
|
d138a2a8e1 | ||
|
|
0eeb5f83c2 | ||
|
|
c2f9d088d5 | ||
|
|
179185985e | ||
|
|
efcb417838 | ||
|
|
aa7a55b480 | ||
|
|
e095282437 | ||
|
|
cbf96368b9 | ||
|
|
251f189428 | ||
|
|
2a5cbe6445 |
2
mdbx.h
2
mdbx.h
@@ -610,7 +610,7 @@ LIBMDBX_API int mdbx_env_create(MDBX_env **penv);
|
|||||||
* - MDBX_NOTLS
|
* - MDBX_NOTLS
|
||||||
* Don't use Thread-Local Storage. Tie reader locktable slots to
|
* Don't use Thread-Local Storage. Tie reader locktable slots to
|
||||||
* MDBX_txn objects instead of to threads. I.e. mdbx_txn_reset() keeps
|
* MDBX_txn objects instead of to threads. I.e. mdbx_txn_reset() keeps
|
||||||
* the slot reseved for the MDBX_txn object. A thread may use parallel
|
* the slot reserved for the MDBX_txn object. A thread may use parallel
|
||||||
* read-only transactions. A read-only transaction may span threads if
|
* read-only transactions. A read-only transaction may span threads if
|
||||||
* the user synchronizes its use. Applications that multiplex many
|
* the user synchronizes its use. Applications that multiplex many
|
||||||
* user threads over individual OS threads need this option. Such an
|
* user threads over individual OS threads need this option. Such an
|
||||||
|
|||||||
@@ -20,8 +20,8 @@
|
|||||||
#ifndef MDBX_USE_ROBUST
|
#ifndef MDBX_USE_ROBUST
|
||||||
/* Howard Chu: Android currently lacks Robust Mutex support */
|
/* Howard Chu: Android currently lacks Robust Mutex support */
|
||||||
#if defined(EOWNERDEAD) && \
|
#if defined(EOWNERDEAD) && \
|
||||||
!defined(ANDROID) /* LY: glibc before 2.10 has a troubles with Robust \
|
!defined(__ANDROID__) /* LY: glibc before 2.10 has a troubles \
|
||||||
Mutex too. */ \
|
with Robust Mutex too. */ \
|
||||||
&& __GLIBC_PREREQ(2, 10)
|
&& __GLIBC_PREREQ(2, 10)
|
||||||
#define MDBX_USE_ROBUST 1
|
#define MDBX_USE_ROBUST 1
|
||||||
#else
|
#else
|
||||||
|
|||||||
23
src/mdbx.c
23
src/mdbx.c
@@ -3755,6 +3755,7 @@ static int mdbx_prep_backlog(MDBX_txn *txn, MDBX_cursor *mc) {
|
|||||||
const int extra = mdbx_backlog_extragap(txn->mt_env);
|
const int extra = mdbx_backlog_extragap(txn->mt_env);
|
||||||
|
|
||||||
if (mdbx_backlog_size(txn) < mc->mc_db->md_depth + extra) {
|
if (mdbx_backlog_size(txn) < mc->mc_db->md_depth + extra) {
|
||||||
|
mc->mc_flags &= ~C_RECLAIMING;
|
||||||
int rc = mdbx_cursor_touch(mc);
|
int rc = mdbx_cursor_touch(mc);
|
||||||
if (unlikely(rc))
|
if (unlikely(rc))
|
||||||
return rc;
|
return rc;
|
||||||
@@ -3768,6 +3769,7 @@ static int mdbx_prep_backlog(MDBX_txn *txn, MDBX_cursor *mc) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
mc->mc_flags |= C_RECLAIMING;
|
||||||
}
|
}
|
||||||
|
|
||||||
return MDBX_SUCCESS;
|
return MDBX_SUCCESS;
|
||||||
@@ -3880,6 +3882,7 @@ static int mdbx_update_gc(MDBX_txn *txn) {
|
|||||||
if (unlikely(rc != MDBX_SUCCESS))
|
if (unlikely(rc != MDBX_SUCCESS))
|
||||||
goto bailout_notracking;
|
goto bailout_notracking;
|
||||||
|
|
||||||
|
mc.mc_flags |= C_RECLAIMING;
|
||||||
mc.mc_next = txn->mt_cursors[FREE_DBI];
|
mc.mc_next = txn->mt_cursors[FREE_DBI];
|
||||||
txn->mt_cursors[FREE_DBI] = &mc;
|
txn->mt_cursors[FREE_DBI] = &mc;
|
||||||
|
|
||||||
@@ -3925,9 +3928,7 @@ retry:
|
|||||||
mdbx_tassert(txn, cleaned_gc_id < *env->me_oldest);
|
mdbx_tassert(txn, cleaned_gc_id < *env->me_oldest);
|
||||||
mdbx_trace("%s.cleanup-reclaimed-id [%u]%" PRIaTXN, dbg_prefix_mode,
|
mdbx_trace("%s.cleanup-reclaimed-id [%u]%" PRIaTXN, dbg_prefix_mode,
|
||||||
cleaned_gc_slot, cleaned_gc_id);
|
cleaned_gc_slot, cleaned_gc_id);
|
||||||
mc.mc_flags |= C_RECLAIMING;
|
|
||||||
rc = mdbx_cursor_del(&mc, 0);
|
rc = mdbx_cursor_del(&mc, 0);
|
||||||
mc.mc_flags ^= C_RECLAIMING;
|
|
||||||
if (unlikely(rc != MDBX_SUCCESS))
|
if (unlikely(rc != MDBX_SUCCESS))
|
||||||
goto bailout;
|
goto bailout;
|
||||||
} while (cleaned_gc_slot < MDBX_PNL_SIZE(txn->mt_lifo_reclaimed));
|
} while (cleaned_gc_slot < MDBX_PNL_SIZE(txn->mt_lifo_reclaimed));
|
||||||
@@ -3949,9 +3950,7 @@ retry:
|
|||||||
mdbx_tassert(txn, cleaned_gc_id < *env->me_oldest);
|
mdbx_tassert(txn, cleaned_gc_id < *env->me_oldest);
|
||||||
mdbx_trace("%s.cleanup-reclaimed-id %" PRIaTXN, dbg_prefix_mode,
|
mdbx_trace("%s.cleanup-reclaimed-id %" PRIaTXN, dbg_prefix_mode,
|
||||||
cleaned_gc_id);
|
cleaned_gc_id);
|
||||||
mc.mc_flags |= C_RECLAIMING;
|
|
||||||
rc = mdbx_cursor_del(&mc, 0);
|
rc = mdbx_cursor_del(&mc, 0);
|
||||||
mc.mc_flags ^= C_RECLAIMING;
|
|
||||||
if (unlikely(rc != MDBX_SUCCESS))
|
if (unlikely(rc != MDBX_SUCCESS))
|
||||||
goto bailout;
|
goto bailout;
|
||||||
settled = 0;
|
settled = 0;
|
||||||
@@ -4104,7 +4103,9 @@ retry:
|
|||||||
if (befree_stored < MDBX_PNL_SIZE(txn->mt_befree_pages)) {
|
if (befree_stored < MDBX_PNL_SIZE(txn->mt_befree_pages)) {
|
||||||
if (unlikely(!befree_stored)) {
|
if (unlikely(!befree_stored)) {
|
||||||
/* Make sure last page of freeDB is touched and on befree-list */
|
/* Make sure last page of freeDB is touched and on befree-list */
|
||||||
|
mc.mc_flags &= ~C_RECLAIMING;
|
||||||
rc = mdbx_page_search(&mc, NULL, MDBX_PS_LAST | MDBX_PS_MODIFY);
|
rc = mdbx_page_search(&mc, NULL, MDBX_PS_LAST | MDBX_PS_MODIFY);
|
||||||
|
mc.mc_flags |= C_RECLAIMING;
|
||||||
if (unlikely(rc != MDBX_SUCCESS && rc != MDBX_NOTFOUND))
|
if (unlikely(rc != MDBX_SUCCESS && rc != MDBX_NOTFOUND))
|
||||||
goto bailout;
|
goto bailout;
|
||||||
}
|
}
|
||||||
@@ -4198,7 +4199,9 @@ retry:
|
|||||||
reused_gc_slot) *
|
reused_gc_slot) *
|
||||||
env->me_maxgc_ov1page) {
|
env->me_maxgc_ov1page) {
|
||||||
/* LY: need just a txn-id for save page list. */
|
/* LY: need just a txn-id for save page list. */
|
||||||
|
mc.mc_flags &= ~C_RECLAIMING;
|
||||||
rc = mdbx_page_alloc(&mc, 0, NULL, MDBX_ALLOC_GC | MDBX_ALLOC_KICK);
|
rc = mdbx_page_alloc(&mc, 0, NULL, MDBX_ALLOC_GC | MDBX_ALLOC_KICK);
|
||||||
|
mc.mc_flags |= C_RECLAIMING;
|
||||||
if (likely(rc == MDBX_SUCCESS)) {
|
if (likely(rc == MDBX_SUCCESS)) {
|
||||||
/* LY: ok, reclaimed from freedb. */
|
/* LY: ok, reclaimed from freedb. */
|
||||||
mdbx_trace("%s: took @%" PRIaTXN " from GC, continue",
|
mdbx_trace("%s: took @%" PRIaTXN " from GC, continue",
|
||||||
@@ -4412,7 +4415,7 @@ retry:
|
|||||||
key.iov_len = sizeof(fill_gc_id);
|
key.iov_len = sizeof(fill_gc_id);
|
||||||
|
|
||||||
mdbx_tassert(txn, data.iov_len >= sizeof(pgno_t) * 2);
|
mdbx_tassert(txn, data.iov_len >= sizeof(pgno_t) * 2);
|
||||||
mc.mc_flags |= C_RECLAIMING | C_GCFREEZE;
|
mc.mc_flags |= C_GCFREEZE;
|
||||||
unsigned chunk = (unsigned)(data.iov_len / sizeof(pgno_t)) - 1;
|
unsigned chunk = (unsigned)(data.iov_len / sizeof(pgno_t)) - 1;
|
||||||
if (unlikely(chunk > left)) {
|
if (unlikely(chunk > left)) {
|
||||||
mdbx_trace("%s: chunk %u > left %u, @%" PRIaTXN, dbg_prefix_mode, chunk,
|
mdbx_trace("%s: chunk %u > left %u, @%" PRIaTXN, dbg_prefix_mode, chunk,
|
||||||
@@ -4420,12 +4423,12 @@ retry:
|
|||||||
if (loop < 5 || chunk - left > env->me_maxgc_ov1page) {
|
if (loop < 5 || chunk - left > env->me_maxgc_ov1page) {
|
||||||
data.iov_len = (left + 1) * sizeof(pgno_t);
|
data.iov_len = (left + 1) * sizeof(pgno_t);
|
||||||
if (loop < 21)
|
if (loop < 21)
|
||||||
mc.mc_flags -= C_GCFREEZE;
|
mc.mc_flags &= ~C_GCFREEZE;
|
||||||
}
|
}
|
||||||
chunk = left;
|
chunk = left;
|
||||||
}
|
}
|
||||||
rc = mdbx_cursor_put(&mc, &key, &data, MDBX_CURRENT | MDBX_RESERVE);
|
rc = mdbx_cursor_put(&mc, &key, &data, MDBX_CURRENT | MDBX_RESERVE);
|
||||||
mc.mc_flags &= ~(C_RECLAIMING | C_GCFREEZE);
|
mc.mc_flags &= ~C_GCFREEZE;
|
||||||
if (unlikely(rc != MDBX_SUCCESS))
|
if (unlikely(rc != MDBX_SUCCESS))
|
||||||
goto bailout;
|
goto bailout;
|
||||||
|
|
||||||
@@ -5127,7 +5130,7 @@ static int __cold mdbx_read_header(MDBX_env *env, MDBX_meta *meta,
|
|||||||
|
|
||||||
/* LY: check and silently put mm_geo.now into [geo.lower...geo.upper].
|
/* LY: check and silently put mm_geo.now into [geo.lower...geo.upper].
|
||||||
*
|
*
|
||||||
* Copy-with-compaction by previous version of libmfbx could produce DB-file
|
* Copy-with-compaction by previous version of libmdbx could produce DB-file
|
||||||
* less than meta.geo.lower bound, in case actual filling is low or no data
|
* less than meta.geo.lower bound, in case actual filling is low or no data
|
||||||
* at all. This is not a problem as there is no damage or loss of data.
|
* at all. This is not a problem as there is no damage or loss of data.
|
||||||
* Therefore it is better not to consider such situation as an error, but
|
* Therefore it is better not to consider such situation as an error, but
|
||||||
@@ -8300,7 +8303,7 @@ int mdbx_cursor_put(MDBX_cursor *mc, MDBX_val *key, MDBX_val *data,
|
|||||||
if (rc > 0) {
|
if (rc > 0) {
|
||||||
rc = MDBX_NOTFOUND;
|
rc = MDBX_NOTFOUND;
|
||||||
mc->mc_ki[mc->mc_top]++;
|
mc->mc_ki[mc->mc_top]++;
|
||||||
} else {
|
} else if (unlikely(rc < 0 || (flags & MDBX_APPENDDUP) == 0)) {
|
||||||
/* new key is <= last key */
|
/* new key is <= last key */
|
||||||
rc = MDBX_EKEYMISMATCH;
|
rc = MDBX_EKEYMISMATCH;
|
||||||
}
|
}
|
||||||
@@ -10882,7 +10885,7 @@ static int mdbx_page_split(MDBX_cursor *mc, const MDBX_val *newkey,
|
|||||||
* This yields better packing during sequential inserts.
|
* This yields better packing during sequential inserts.
|
||||||
*/
|
*/
|
||||||
int dir;
|
int dir;
|
||||||
if (nkeys < 20 || nsize > pmax / 16 || newindx >= nkeys) {
|
if (nkeys < 32 || nsize > pmax / 16 || newindx >= nkeys) {
|
||||||
/* Find split point */
|
/* Find split point */
|
||||||
psize = 0;
|
psize = 0;
|
||||||
if (newindx <= split_indx || newindx >= nkeys) {
|
if (newindx <= split_indx || newindx >= nkeys) {
|
||||||
|
|||||||
22
src/osal.c
22
src/osal.c
@@ -581,17 +581,25 @@ int mdbx_pwrite(mdbx_filehandle_t fd, const void *buf, size_t bytes,
|
|||||||
return (bytes == written) ? MDBX_SUCCESS : MDBX_EIO /* ERROR_WRITE_FAULT */;
|
return (bytes == written) ? MDBX_SUCCESS : MDBX_EIO /* ERROR_WRITE_FAULT */;
|
||||||
return GetLastError();
|
return GetLastError();
|
||||||
#else
|
#else
|
||||||
int rc;
|
while (true) {
|
||||||
intptr_t written;
|
|
||||||
do {
|
|
||||||
STATIC_ASSERT_MSG(sizeof(off_t) >= sizeof(size_t),
|
STATIC_ASSERT_MSG(sizeof(off_t) >= sizeof(size_t),
|
||||||
"libmdbx requires 64-bit file I/O on 64-bit systems");
|
"libmdbx requires 64-bit file I/O on 64-bit systems");
|
||||||
written = pwrite(fd, buf, bytes, offset);
|
const intptr_t written =
|
||||||
|
pwrite(fd, buf, (bytes <= MAX_WRITE) ? bytes : MAX_WRITE, offset);
|
||||||
if (likely(bytes == (size_t)written))
|
if (likely(bytes == (size_t)written))
|
||||||
return MDBX_SUCCESS;
|
return MDBX_SUCCESS;
|
||||||
rc = errno;
|
if (written < 0) {
|
||||||
} while (rc == EINTR);
|
const int rc = errno;
|
||||||
return (written < 0) ? rc : MDBX_EIO /* Use which error code (ENOSPC)? */;
|
if (rc != EINTR)
|
||||||
|
return rc;
|
||||||
|
} else if (written > 0) {
|
||||||
|
bytes -= written;
|
||||||
|
offset += written;
|
||||||
|
buf = (char *)buf + written;
|
||||||
|
} else {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -18,8 +18,8 @@
|
|||||||
#error "API version mismatch!"
|
#error "API version mismatch!"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define MDBX_VERSION_RELEASE 0
|
#define MDBX_VERSION_RELEASE 2
|
||||||
#define MDBX_VERSION_REVISION 2
|
#define MDBX_VERSION_REVISION 0
|
||||||
|
|
||||||
/*LIBMDBX_EXPORTS*/ const mdbx_version_info mdbx_version = {
|
/*LIBMDBX_EXPORTS*/ const mdbx_version_info mdbx_version = {
|
||||||
MDBX_VERSION_MAJOR,
|
MDBX_VERSION_MAJOR,
|
||||||
@@ -30,5 +30,5 @@
|
|||||||
"@MDBX_GIT_DESCRIBE@"}};
|
"@MDBX_GIT_DESCRIBE@"}};
|
||||||
|
|
||||||
/*LIBMDBX_EXPORTS*/ const mdbx_build_info mdbx_build = {
|
/*LIBMDBX_EXPORTS*/ const mdbx_build_info mdbx_build = {
|
||||||
"@MDBX_BUILD_TIMESTAMP@", "@MDBX_BUILD_TAGRET@", "@MDBX_BUILD_OPTIONS@",
|
"@MDBX_BUILD_TIMESTAMP@", "@MDBX_BUILD_TARGET@", "@MDBX_BUILD_OPTIONS@",
|
||||||
"@MDBX_BUILD_COMPILER@", "@MDBX_BUILD_FLAGS@"};
|
"@MDBX_BUILD_COMPILER@", "@MDBX_BUILD_FLAGS@"};
|
||||||
|
|||||||
@@ -182,11 +182,11 @@ int main(int argc, char *const argv[]) {
|
|||||||
mdbx_limits_dbsize_min(params.pagesize),
|
mdbx_limits_dbsize_min(params.pagesize),
|
||||||
mdbx_limits_dbsize_max(params.pagesize)))
|
mdbx_limits_dbsize_max(params.pagesize)))
|
||||||
continue;
|
continue;
|
||||||
if (config::parse_option(argc, argv, narg, "size", params.size_now,
|
if (config::parse_option(argc, argv, narg, "size-upper", params.size_upper,
|
||||||
mdbx_limits_dbsize_min(params.pagesize),
|
mdbx_limits_dbsize_min(params.pagesize),
|
||||||
mdbx_limits_dbsize_max(params.pagesize)))
|
mdbx_limits_dbsize_max(params.pagesize)))
|
||||||
continue;
|
continue;
|
||||||
if (config::parse_option(argc, argv, narg, "size-upper", params.size_upper,
|
if (config::parse_option(argc, argv, narg, "size", params.size_now,
|
||||||
mdbx_limits_dbsize_min(params.pagesize),
|
mdbx_limits_dbsize_min(params.pagesize),
|
||||||
mdbx_limits_dbsize_max(params.pagesize)))
|
mdbx_limits_dbsize_max(params.pagesize)))
|
||||||
continue;
|
continue;
|
||||||
|
|||||||
Reference in New Issue
Block a user