diff options
Diffstat (limited to 'libs/libmdbx/src/mdbx_load.c')
-rw-r--r-- | libs/libmdbx/src/mdbx_load.c | 193 |
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; } |