summaryrefslogtreecommitdiff
path: root/libs/libmdbx/src/mdbx_load.c
diff options
context:
space:
mode:
Diffstat (limited to 'libs/libmdbx/src/mdbx_load.c')
-rw-r--r--libs/libmdbx/src/mdbx_load.c193
1 files changed, 96 insertions, 97 deletions
diff --git a/libs/libmdbx/src/mdbx_load.c b/libs/libmdbx/src/mdbx_load.c
index 6832e0f73a..3a49a60ec7 100644
--- a/libs/libmdbx/src/mdbx_load.c
+++ b/libs/libmdbx/src/mdbx_load.c
@@ -34,11 +34,16 @@
* top-level directory of the distribution or, alternatively, at
* <http://www.OpenLDAP.org/license.html>. */
-#define MDBX_BUILD_SOURCERY 3b5677a6062b714f1e138b0066c5590ee3c9ebf3bf8cfa3bb9503515ea0d1f02_v0_9_1_18_g1d31ebdc1c
+#define MDBX_BUILD_SOURCERY 47492323531afee427a3de6ddaeae26eed45bfd1b52d92fd121a5a13a9747dbb_v0_9_2_0_g092ab09
#ifdef MDBX_CONFIG_H
#include MDBX_CONFIG_H
#endif
+#define LIBMDBX_INTERNALS
+#ifdef MDBX_TOOLS
+#define MDBX_DEPRECATED
+#endif /* MDBX_TOOLS */
+
/* *INDENT-OFF* */
/* clang-format off */
@@ -119,11 +124,6 @@
#pragma warning(disable : 4505) /* unreferenced local function has been removed */
#endif /* _MSC_VER (warnings) */
-#if defined(MDBX_TOOLS)
-#undef MDBX_DEPRECATED
-#define MDBX_DEPRECATED
-#endif /* MDBX_TOOLS */
-
#include "mdbx.h"
/*
* Copyright 2015-2020 Leonid Yuriev <leo@yuriev.ru>
@@ -839,7 +839,7 @@ typedef pthread_mutex_t mdbx_fastmutex_t;
defined(__amd64__) || defined(__amd64) || defined(_M_X64) || \
defined(_M_AMD64) || defined(__IA32__) || defined(__INTEL__)
#ifndef __ia32__
-/* LY: define neutral __ia32__ for x86 and x86-64 archs */
+/* LY: define neutral __ia32__ for x86 and x86-64 */
#define __ia32__ 1
#endif /* __ia32__ */
#if !defined(__amd64__) && (defined(__x86_64) || defined(__x86_64__) || \
@@ -1015,6 +1015,35 @@ typedef union MDBX_srwlock {
#ifdef __cplusplus
extern void mdbx_osal_jitter(bool tiny);
#else
+
+/*----------------------------------------------------------------------------*/
+/* Atomics */
+
+#if defined(__cplusplus) && !defined(__STDC_NO_ATOMICS__) && __has_include(<cstdatomic>)
+#include <cstdatomic>
+#elif !defined(__cplusplus) && (__STDC_VERSION__ >= 201112L) && \
+ !defined(__STDC_NO_ATOMICS__) && \
+ (__GNUC_PREREQ(4, 9) || __CLANG_PREREQ(3, 8) || \
+ !(defined(__GNUC__) || defined(__clang__)))
+#include <stdatomic.h>
+#elif defined(__GNUC__) || defined(__clang__)
+/* LY: nothing required */
+#elif defined(_MSC_VER)
+#pragma warning(disable : 4163) /* 'xyz': not available as an intrinsic */
+#pragma warning(disable : 4133) /* 'function': incompatible types - from \
+ 'size_t' to 'LONGLONG' */
+#pragma warning(disable : 4244) /* 'return': conversion from 'LONGLONG' to \
+ 'std::size_t', possible loss of data */
+#pragma warning(disable : 4267) /* 'function': conversion from 'size_t' to \
+ 'long', possible loss of data */
+#pragma intrinsic(_InterlockedExchangeAdd, _InterlockedCompareExchange)
+#pragma intrinsic(_InterlockedExchangeAdd64, _InterlockedCompareExchange64)
+#elif defined(__APPLE__)
+#include <libkern/OSAtomic.h>
+#else
+#error FIXME atomic-ops
+#endif
+
/*----------------------------------------------------------------------------*/
/* Memory/Compiler barriers, cache coherence */
@@ -1056,8 +1085,8 @@ static __maybe_unused __inline void mdbx_compiler_barrier(void) {
}
static __maybe_unused __inline void mdbx_memory_barrier(void) {
-#if __has_extension(c_atomic) || __has_extension(cxx_atomic)
- __c11_atomic_thread_fence(__ATOMIC_SEQ_CST);
+#if __has_extension(c_atomic) && !defined(__STDC_NO_ATOMICS__)
+ atomic_thread_fence(__ATOMIC_SEQ_CST);
#elif defined(__ATOMIC_SEQ_CST)
__atomic_thread_fence(__ATOMIC_SEQ_CST);
#elif defined(__clang__) || defined(__GNUC__)
@@ -1110,8 +1139,7 @@ MDBX_INTERNAL_FUNC int mdbx_vasprintf(char **strp, const char *fmt, va_list ap);
#if defined(__linux__) || defined(__gnu_linux__)
MDBX_INTERNAL_VAR uint32_t mdbx_linux_kernel_version;
-MDBX_INTERNAL_VAR bool
- mdbx_RunningOnWSL /* Windows Subsystem for Linux is mad and trouble-full */;
+MDBX_INTERNAL_VAR bool mdbx_RunningOnWSL1 /* Windows Subsystem 1 for Linux */;
#endif /* Linux */
#ifndef mdbx_strdup
@@ -1182,7 +1210,8 @@ enum mdbx_openfile_purpose {
MDBX_OPEN_DXB_LAZY = 1,
MDBX_OPEN_DXB_DSYNC = 2,
MDBX_OPEN_LCK = 3,
- MDBX_OPEN_COPY = 4
+ MDBX_OPEN_COPY = 4,
+ MDBX_OPEN_DELETE = 5
};
MDBX_INTERNAL_FUNC int mdbx_openfile(const enum mdbx_openfile_purpose purpose,
@@ -1191,7 +1220,9 @@ MDBX_INTERNAL_FUNC int mdbx_openfile(const enum mdbx_openfile_purpose purpose,
mdbx_mode_t unix_mode_bits);
MDBX_INTERNAL_FUNC int mdbx_closefile(mdbx_filehandle_t fd);
MDBX_INTERNAL_FUNC int mdbx_removefile(const char *pathname);
+MDBX_INTERNAL_FUNC int mdbx_removedirectory(const char *pathname);
MDBX_INTERNAL_FUNC int mdbx_is_pipe(mdbx_filehandle_t fd);
+MDBX_INTERNAL_FUNC int mdbx_lockfile(mdbx_filehandle_t fd, bool wait);
#define MMAP_OPTION_TRUNCATE 1
#define MMAP_OPTION_SEMAPHORE 2
@@ -1451,32 +1482,6 @@ MDBX_INTERNAL_VAR MDBX_RegGetValueA mdbx_RegGetValueA;
#endif /* Windows */
-/*----------------------------------------------------------------------------*/
-/* Atomics */
-
-#if !defined(__cplusplus) && (__STDC_VERSION__ >= 201112L) && \
- !defined(__STDC_NO_ATOMICS__) && \
- (__GNUC_PREREQ(4, 9) || __CLANG_PREREQ(3, 8) || \
- !(defined(__GNUC__) || defined(__clang__)))
-#include <stdatomic.h>
-#elif defined(__GNUC__) || defined(__clang__)
-/* LY: nothing required */
-#elif defined(_MSC_VER)
-#pragma warning(disable : 4163) /* 'xyz': not available as an intrinsic */
-#pragma warning(disable : 4133) /* 'function': incompatible types - from \
- 'size_t' to 'LONGLONG' */
-#pragma warning(disable : 4244) /* 'return': conversion from 'LONGLONG' to \
- 'std::size_t', possible loss of data */
-#pragma warning(disable : 4267) /* 'function': conversion from 'size_t' to \
- 'long', possible loss of data */
-#pragma intrinsic(_InterlockedExchangeAdd, _InterlockedCompareExchange)
-#pragma intrinsic(_InterlockedExchangeAdd64, _InterlockedCompareExchange64)
-#elif defined(__APPLE__)
-#include <libkern/OSAtomic.h>
-#else
-#error FIXME atomic-ops
-#endif
-
#endif /* !__cplusplus */
/*----------------------------------------------------------------------------*/
@@ -1912,7 +1917,7 @@ typedef struct MDBX_db {
pgno_t md_overflow_pages; /* number of overflow pages */
uint64_t md_seq; /* table sequence counter */
uint64_t md_entries; /* number of data items */
- uint64_t md_mod_txnid; /* txnid of last commited modification */
+ uint64_t md_mod_txnid; /* txnid of last committed modification */
} MDBX_db;
/* database size-related parameters */
@@ -1996,7 +2001,7 @@ typedef struct MDBX_meta {
typedef struct MDBX_page {
union {
struct MDBX_page *mp_next; /* for in-memory list of freed pages */
- uint64_t mp_txnid; /* txnid during which the page has been COW-ed */
+ uint64_t mp_txnid; /* txnid that committed this page */
};
uint16_t mp_leaf2_ksize; /* key size if this is a LEAF2 page */
#define P_BRANCH 0x01 /* branch page */
@@ -2244,7 +2249,7 @@ typedef struct MDBX_lockinfo {
#if defined(_WIN32) || defined(_WIN64)
#define MAX_MAPSIZE32 UINT32_C(0x38000000)
#else
-#define MAX_MAPSIZE32 UINT32_C(0x7ff80000)
+#define MAX_MAPSIZE32 UINT32_C(0x7f000000)
#endif
#define MAX_MAPSIZE64 (MAX_PAGENO * (uint64_t)MAX_PAGESIZE)
@@ -2403,8 +2408,6 @@ struct MDBX_txn {
MDBX_db *mt_dbs;
/* Array of sequence numbers for each DB handle */
unsigned *mt_dbiseqs;
- /* In write txns, array of cursors for each DB */
- MDBX_cursor **mt_cursors;
/* Transaction DBI Flags */
#define DBI_DIRTY MDBX_DBI_DIRTY /* DB was written in this txn */
@@ -2431,6 +2434,8 @@ struct MDBX_txn {
MDBX_reader *reader;
} to;
struct {
+ /* In write txns, array of cursors for each DB */
+ MDBX_cursor **cursors;
pgno_t *reclaimed_pglist; /* Reclaimed GC pages */
txnid_t last_reclaimed; /* ID of last used record */
pgno_t loose_refund_wl /* FIXME: describe */;
@@ -2568,7 +2573,7 @@ struct MDBX_env {
#define me_lfd me_lck_mmap.fd
#define me_lck me_lck_mmap.lck
- unsigned me_psize; /* DB page size, inited from me_os_psize */
+ unsigned me_psize; /* DB page size, initialized from me_os_psize */
uint8_t me_psize2log; /* log2 of DB page size */
int8_t me_stuck_meta; /* recovery-only: target meta page or less that zero */
unsigned me_os_psize; /* OS page size, from mdbx_syspagesize() */
@@ -2578,7 +2583,7 @@ struct MDBX_env {
MDBX_dbi me_maxdbs; /* size of the DB table */
uint32_t me_pid; /* process ID of this env */
mdbx_thread_key_t me_txkey; /* thread-key for readers */
- char *me_path; /* path to the DB files */
+ char *me_pathname; /* path to the DB files */
void *me_pbuf; /* scratch area for DUPSORT put() */
MDBX_txn *me_txn; /* current write transaction */
MDBX_txn *me_txn0; /* prealloc'd write transaction */
@@ -2854,7 +2859,7 @@ static __maybe_unused __inline void mdbx_jitter4testing(bool tiny) {
((rc) != MDBX_RESULT_TRUE && (rc) != MDBX_RESULT_FALSE)
/* Internal error codes, not exposed outside libmdbx */
-#define MDBX_NO_ROOT (MDBX_LAST_LMDB_ERRCODE + 10)
+#define MDBX_NO_ROOT (MDBX_LAST_ADDED_ERRCODE + 10)
/* Debugging output value of a cursor DBI: Negative in a sub-cursor. */
#define DDBI(mc) \
@@ -3229,7 +3234,6 @@ static MDBX_envinfo envinfo;
static int mode = GLOBAL;
static MDBX_val kbuf, dbuf;
-static MDBX_val k0buf;
#define STRLENOF(s) (sizeof(s) - 1)
@@ -3561,7 +3565,7 @@ static int readline(MDBX_val *out, MDBX_val *buf) {
static void usage(void) {
fprintf(stderr,
"usage: %s [-V] [-q] [-a] [-f file] [-s name] [-N] [-T] [-r] [-n]"
- "dbpath\n"
+ " dbpath\n"
" -V\t\tprint version and exit\n"
" -q\t\tbe quiet\n"
" -a\t\tappend records in input order (required for custom "
@@ -3592,11 +3596,9 @@ int main(int argc, char *argv[]) {
MDBX_cursor *mc = nullptr;
MDBX_dbi dbi;
char *envname = nullptr;
- int envflags = MDBX_UTTERLY_NOSYNC, putflags = 0;
- bool append = false;
+ int envflags = MDBX_UTTERLY_NOSYNC, putflags = MDBX_UPSERT;
bool quiet = false;
bool rescue = false;
- MDBX_val prevk;
prog = argv[0];
if (argc < 2)
@@ -3619,7 +3621,7 @@ int main(int argc, char *argv[]) {
mdbx_build.options);
return EXIT_SUCCESS;
case 'a':
- append = true;
+ putflags |= MDBX_APPEND;
break;
case 'f':
if (freopen(optarg, "r", stdin) == nullptr) {
@@ -3635,7 +3637,7 @@ int main(int argc, char *argv[]) {
subname = mdbx_strdup(optarg);
break;
case 'N':
- putflags = MDBX_NOOVERWRITE | MDBX_NODUPDATA;
+ putflags |= MDBX_NOOVERWRITE | MDBX_NODUPDATA;
break;
case 'T':
mode |= NOHDR | PRINT;
@@ -3676,6 +3678,11 @@ int main(int argc, char *argv[]) {
dbuf.iov_len = 4096;
dbuf.iov_base = mdbx_malloc(dbuf.iov_len);
+ if (!dbuf.iov_base) {
+ rc = MDBX_ENOMEM;
+ error("value-buffer", rc);
+ goto env_close;
+ }
/* read first header for mapsize= */
if (!(mode & NOHDR)) {
@@ -3703,7 +3710,7 @@ int main(int argc, char *argv[]) {
}
}
- if (envinfo.mi_mapsize) {
+ if (envinfo.mi_geo.current | envinfo.mi_mapsize) {
if (envinfo.mi_geo.current) {
rc = mdbx_env_set_geometry(
env, (intptr_t)envinfo.mi_geo.lower, (intptr_t)envinfo.mi_geo.current,
@@ -3736,17 +3743,19 @@ int main(int argc, char *argv[]) {
goto env_close;
}
- kbuf.iov_len = mdbx_env_get_maxvalsize_ex(env, MDBX_DUPSORT);
- if (kbuf.iov_len >= INTPTR_MAX / 4) {
+ kbuf.iov_len = mdbx_env_get_maxvalsize_ex(env, 0) + 1;
+ if (kbuf.iov_len >= INTPTR_MAX / 2) {
fprintf(stderr, "mdbx_env_get_maxkeysize() failed, returns %zu\n",
kbuf.iov_len);
goto env_close;
}
- kbuf.iov_len = (kbuf.iov_len + 1) * 2;
- kbuf.iov_base = malloc(kbuf.iov_len * 2);
- k0buf.iov_len = kbuf.iov_len;
- k0buf.iov_base = (char *)kbuf.iov_base + kbuf.iov_len;
- prevk.iov_base = k0buf.iov_base;
+
+ kbuf.iov_base = malloc(kbuf.iov_len);
+ if (!kbuf.iov_base) {
+ rc = MDBX_ENOMEM;
+ error("key-buffer", rc);
+ goto env_close;
+ }
while (rc == MDBX_SUCCESS) {
if (user_break) {
@@ -3772,9 +3781,10 @@ int main(int argc, char *argv[]) {
}
const char *const dbi_name = subname ? subname : "@MAIN";
- rc = mdbx_dbi_open_ex(txn, subname, dbi_flags | MDBX_CREATE, &dbi,
- append ? equal_or_greater : nullptr,
- append ? equal_or_greater : nullptr);
+ rc =
+ mdbx_dbi_open_ex(txn, subname, dbi_flags | MDBX_CREATE, &dbi,
+ (putflags & MDBX_APPEND) ? equal_or_greater : nullptr,
+ (putflags & MDBX_APPEND) ? equal_or_greater : nullptr);
if (unlikely(rc != MDBX_SUCCESS)) {
error("mdbx_dbi_open_ex", rc);
goto txn_abort;
@@ -3789,7 +3799,7 @@ int main(int argc, char *argv[]) {
if (present_sequence > sequence) {
fprintf(stderr,
"present sequence for '%s' value (%" PRIu64
- ") is greated than loaded (%" PRIu64 ")\n",
+ ") is greater than loaded (%" PRIu64 ")\n",
dbi_name, present_sequence, sequence);
rc = MDBX_RESULT_TRUE;
goto txn_abort;
@@ -3802,19 +3812,17 @@ int main(int argc, char *argv[]) {
}
}
+ if (putflags & MDBX_APPEND)
+ putflags = (dbi_flags & MDBX_DUPSORT) ? putflags | MDBX_APPENDDUP
+ : putflags & ~MDBX_APPENDDUP;
+
rc = mdbx_cursor_open(txn, dbi, &mc);
if (unlikely(rc != MDBX_SUCCESS)) {
error("mdbx_cursor_open", rc);
goto txn_abort;
}
- /* if (append) {
- mc->mc_flags |= C_SKIPORD;
- if (mc->mc_xcursor)
- mc->mc_xcursor->mx_cursor.mc_flags |= C_SKIPORD;
- } */
int batch = 0;
- prevk.iov_len = 0;
while (rc == MDBX_SUCCESS) {
MDBX_val key, data;
rc = readline(&key, &kbuf);
@@ -3829,18 +3837,7 @@ int main(int argc, char *argv[]) {
goto txn_abort;
}
- int appflag = 0;
- if (append) {
- appflag = MDBX_APPEND;
- if (dbi_flags & MDBX_DUPSORT) {
- if (prevk.iov_len == key.iov_len &&
- memcmp(prevk.iov_base, key.iov_base, key.iov_len) == 0)
- appflag = MDBX_APPEND | MDBX_APPENDDUP;
- else
- memcpy(prevk.iov_base, key.iov_base, prevk.iov_len = key.iov_len);
- }
- }
- rc = mdbx_cursor_put(mc, &key, &data, putflags | appflag);
+ rc = mdbx_cursor_put(mc, &key, &data, putflags);
if (rc == MDBX_KEYEXIST && putflags)
continue;
if (rc == MDBX_BAD_VALSIZE && rescue) {
@@ -3861,9 +3858,7 @@ int main(int argc, char *argv[]) {
goto txn_abort;
}
- if (batch == 10000 || txn_info.txn_space_dirty > MEGABYTE * 16) {
- mdbx_cursor_close(mc);
- mc = nullptr;
+ if (batch == 10000 || txn_info.txn_space_dirty > MEGABYTE * 256) {
rc = mdbx_txn_commit(txn);
if (unlikely(rc != MDBX_SUCCESS)) {
error("mdbx_txn_commit", rc);
@@ -3876,16 +3871,11 @@ int main(int argc, char *argv[]) {
error("mdbx_txn_begin", rc);
goto env_close;
}
- rc = mdbx_cursor_open(txn, dbi, &mc);
+ rc = mdbx_cursor_bind(txn, mc, dbi);
if (unlikely(rc != MDBX_SUCCESS)) {
- error("mdbx_cursor_open", rc);
+ error("mdbx_cursor_bind", rc);
goto txn_abort;
}
- /* if (append) {
- mc->mc_flags |= C_SKIPORD;
- if (mc->mc_xcursor)
- mc->mc_xcursor->mx_cursor.mc_flags |= C_SKIPORD;
- } */
}
}
@@ -3897,15 +3887,22 @@ int main(int argc, char *argv[]) {
error("mdbx_txn_commit", rc);
goto env_close;
}
- rc = mdbx_dbi_close(env, dbi);
- if (unlikely(rc != MDBX_SUCCESS)) {
- error("mdbx_dbi_close", rc);
- goto env_close;
+ if (subname) {
+ assert(dbi != MAIN_DBI);
+ rc = mdbx_dbi_close(env, dbi);
+ if (unlikely(rc != MDBX_SUCCESS)) {
+ error("mdbx_dbi_close", rc);
+ goto env_close;
+ }
+ } else {
+ assert(dbi == MAIN_DBI);
}
/* try read next header */
if (!(mode & NOHDR))
rc = readhdr();
+ else if (ferror(stdin) || feof(stdin))
+ break;
}
switch (rc) {
@@ -3926,6 +3923,8 @@ txn_abort:
mdbx_txn_abort(txn);
env_close:
mdbx_env_close(env);
+ free(kbuf.iov_base);
+ free(dbuf.iov_base);
return rc ? EXIT_FAILURE : EXIT_SUCCESS;
}