summaryrefslogtreecommitdiff
path: root/libs/libmdbx/src/mdbx_dump.c
diff options
context:
space:
mode:
Diffstat (limited to 'libs/libmdbx/src/mdbx_dump.c')
-rw-r--r--libs/libmdbx/src/mdbx_dump.c141
1 files changed, 80 insertions, 61 deletions
diff --git a/libs/libmdbx/src/mdbx_dump.c b/libs/libmdbx/src/mdbx_dump.c
index c51247a121..6b7a5aaa40 100644
--- a/libs/libmdbx/src/mdbx_dump.c
+++ b/libs/libmdbx/src/mdbx_dump.c
@@ -34,7 +34,7 @@
* top-level directory of the distribution or, alternatively, at
* <http://www.OpenLDAP.org/license.html>. */
-#define MDBX_BUILD_SOURCERY b30bc0044d83cd1275fa00662c8265e39091a931353b79a46d21c9536795acb2_v0_9_2_12_g3e7459b4
+#define MDBX_BUILD_SOURCERY 69c11536d7625297e4095e26adca038aaec4105753b20848ae5dfd8bc130d747_v0_9_2_110_g4e13d12
#ifdef MDBX_CONFIG_H
#include MDBX_CONFIG_H
#endif
@@ -361,7 +361,7 @@
# if (defined(__GNUC__) || __has_builtin(__builtin_expect)) && !defined(__COVERITY__)
# define likely(cond) __builtin_expect(!!(cond), 1)
# else
-# define likely(x) (x)
+# define likely(x) (!!(x))
# endif
#endif /* likely */
@@ -369,7 +369,7 @@
# if (defined(__GNUC__) || __has_builtin(__builtin_expect)) && !defined(__COVERITY__)
# define unlikely(cond) __builtin_expect(!!(cond), 0)
# else
-# define unlikely(x) (x)
+# define unlikely(x) (!!(x))
# endif
#endif /* unlikely */
@@ -1564,11 +1564,6 @@ extern LIBMDBX_API const char *const mdbx_sourcery_anchor;
#endif /* DOXYGEN */
-/** Enables support for huge write-transactions */
-#ifndef MDBX_HUGE_TRANSACTIONS
-#define MDBX_HUGE_TRANSACTIONS 0
-#endif /* MDBX_HUGE_TRANSACTIONS */
-
/** Using fcntl(F_FULLFSYNC) with 5-10 times slowdown */
#define MDBX_OSX_WANNA_DURABILITY 0
/** Using fsync() with chance of data lost on power failure */
@@ -1618,6 +1613,24 @@ extern LIBMDBX_API const char *const mdbx_sourcery_anchor;
#define MDBX_TRUST_RTC_CONFIG STRINGIFY(MDBX_TRUST_RTC)
#endif /* MDBX_TRUST_RTC */
+/** Controls online database auto-compactification during write-transactions. */
+#ifndef MDBX_ENABLE_REFUND
+#define MDBX_ENABLE_REFUND 1
+#endif
+#if !(MDBX_ENABLE_REFUND == 0 || MDBX_ENABLE_REFUND == 1)
+#error MDBX_ENABLE_REFUND must be defined as 0 or 1
+#endif /* MDBX_ENABLE_REFUND */
+
+/** Controls sort order of internal page number lists.
+ * The database format depend on this option and libmdbx builded with different
+ * option value are incompatible. */
+#ifndef MDBX_PNL_ASCENDING
+#define MDBX_PNL_ASCENDING 0
+#endif
+#if !(MDBX_PNL_ASCENDING == 0 || MDBX_PNL_ASCENDING == 1)
+#error MDBX_PNL_ASCENDING must be defined as 0 or 1
+#endif /* MDBX_PNL_ASCENDING */
+
//------------------------------------------------------------------------------
/** Win32 File Locking API for \ref MDBX_LOCKING */
@@ -1939,10 +1952,10 @@ typedef struct mdbx_geo_t {
typedef struct MDBX_meta {
/* Stamp identifying this as an MDBX file.
* It must be set to MDBX_MAGIC with MDBX_DATA_VERSION. */
- uint64_t mm_magic_and_version;
+ uint32_t mm_magic_and_version[2];
/* txnid that committed this page, the first of a two-phase-update pair */
- mdbx_safe64_t mm_txnid_a;
+ uint32_t mm_txnid_a[2];
uint16_t mm_extra_flags; /* extra DB flags, zero (nothing) for now */
uint8_t mm_validator_id; /* ID of checksum and page validation method,
@@ -1962,17 +1975,18 @@ typedef struct MDBX_meta {
#define MDBX_DATASIGN_NONE 0u
#define MDBX_DATASIGN_WEAK 1u
#define SIGN_IS_STEADY(sign) ((sign) > MDBX_DATASIGN_WEAK)
-#define META_IS_STEADY(meta) SIGN_IS_STEADY((meta)->mm_datasync_sign)
- volatile uint64_t mm_datasync_sign;
+#define META_IS_STEADY(meta) \
+ SIGN_IS_STEADY(unaligned_peek_u64(4, (meta)->mm_datasync_sign))
+ uint32_t mm_datasync_sign[2];
/* txnid that committed this page, the second of a two-phase-update pair */
- mdbx_safe64_t mm_txnid_b;
+ uint32_t mm_txnid_b[2];
/* Number of non-meta pages which were put in GC after COW. May be 0 in case
* DB was previously handled by libmdbx without corresponding feature.
* This value in couple with mr_snapshot_pages_retired allows fast estimation
* of "how much reader is restraining GC recycling". */
- uint64_t mm_pages_retired;
+ uint32_t mm_pages_retired[2];
/* The analogue /proc/sys/kernel/random/boot_id or similar to determine
* whether the system was rebooted after the last use of the database files.
@@ -2221,7 +2235,8 @@ typedef struct MDBX_lockinfo {
(unsigned)offsetof(MDBX_lockinfo, mti_numreaders) * 37 + \
(unsigned)offsetof(MDBX_lockinfo, mti_readers) * 29)
-#define MDBX_DATA_MAGIC ((MDBX_MAGIC << 8) + MDBX_DATA_VERSION)
+#define MDBX_DATA_MAGIC \
+ ((MDBX_MAGIC << 8) + MDBX_PNL_ASCENDING * 64 + MDBX_DATA_VERSION)
#define MDBX_DATA_MAGIC_DEVEL ((MDBX_MAGIC << 8) + 255)
#define MDBX_LOCK_MAGIC ((MDBX_MAGIC << 8) + MDBX_LOCK_VERSION)
@@ -2259,19 +2274,20 @@ typedef struct MDBX_lockinfo {
#define MAX_MAPSIZE MAX_MAPSIZE64
#define MDBX_READERS_LIMIT \
((65536 - sizeof(MDBX_lockinfo)) / sizeof(MDBX_reader))
+#define MDBX_PGL_LIMIT MAX_PAGENO
#else
#define MDBX_READERS_LIMIT 1024
#define MAX_MAPSIZE MAX_MAPSIZE32
+#define MDBX_PGL_LIMIT (MAX_MAPSIZE32 / MIN_PAGESIZE)
#endif /* MDBX_WORDBITS */
/*----------------------------------------------------------------------------*/
-/* Two kind lists of pages (aka PNL) */
-/* An PNL is an Page Number List, a sorted array of IDs. The first element of
- * the array is a counter for how many actual page-numbers are in the list.
- * PNLs are sorted in descending order, this allow cut off a page with lowest
- * pgno (at the tail) just truncating the list */
-#define MDBX_PNL_ASCENDING 0
+/* An PNL is an Page Number List, a sorted array of IDs.
+ * The first element of the array is a counter for how many actual page-numbers
+ * are in the list. By default PNLs are sorted in descending order, this allow
+ * cut off a page with lowest pgno (at the tail) just truncating the list. The
+ * sort order of PNLs is controlled by the MDBX_PNL_ASCENDING build option. */
typedef pgno_t *MDBX_PNL;
#if MDBX_PNL_ASCENDING
@@ -2286,37 +2302,27 @@ typedef pgno_t *MDBX_PNL;
typedef txnid_t *MDBX_TXL;
/* An Dirty-Page list item is an pgno/pointer pair. */
-typedef union MDBX_DP {
- __anonymous_struct_extension__ struct {
- pgno_t pgno;
- MDBX_page *ptr;
- };
- __anonymous_struct_extension__ struct {
- unsigned sorted;
- unsigned length;
- };
-} MDBX_DP;
-
-/* An DPL (dirty-page list) is a sorted array of MDBX_DPs.
- * The first element's length member is a count of how many actual
- * elements are in the array. */
-typedef MDBX_DP *MDBX_DPL;
+typedef struct MDBX_dp {
+ pgno_t pgno;
+ MDBX_page *ptr;
+} MDBX_dp;
+
+/* An DPL (dirty-page list) is a sorted array of MDBX_DPs. */
+typedef struct MDBX_dpl {
+ unsigned sorted;
+ unsigned length;
+ unsigned allocated;
+#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || \
+ (!defined(__cplusplus) && defined(_MSC_VER))
+ MDBX_dp items[] /* dynamic size with holes at zero and after the last */;
+#endif
+} MDBX_dpl;
/* PNL sizes */
#define MDBX_PNL_GRANULATE 1024
#define MDBX_PNL_INITIAL \
(MDBX_PNL_GRANULATE - 2 - MDBX_ASSUME_MALLOC_OVERHEAD / sizeof(pgno_t))
-#if MDBX_HUGE_TRANSACTIONS
-#define MDBX_PNL_MAX \
- ((1u << 26) - 2 - MDBX_ASSUME_MALLOC_OVERHEAD / sizeof(pgno_t))
-#define MDBX_DPL_TXNFULL (MDBX_PNL_MAX / 2)
-#else
-#define MDBX_PNL_MAX \
- ((1u << 24) - 2 - MDBX_ASSUME_MALLOC_OVERHEAD / sizeof(pgno_t))
-#define MDBX_DPL_TXNFULL (MDBX_PNL_MAX / 4)
-#endif /* MDBX_HUGE_TRANSACTIONS */
-
#define MDBX_TXL_GRANULATE 32
#define MDBX_TXL_INITIAL \
(MDBX_TXL_GRANULATE - 2 - MDBX_ASSUME_MALLOC_OVERHEAD / sizeof(txnid_t))
@@ -2440,14 +2446,16 @@ struct MDBX_txn {
MDBX_cursor **cursors;
pgno_t *reclaimed_pglist; /* Reclaimed GC pages */
txnid_t last_reclaimed; /* ID of last used record */
+#if MDBX_ENABLE_REFUND
pgno_t loose_refund_wl /* FIXME: describe */;
+#endif /* MDBX_ENABLE_REFUND */
/* dirtylist room: Dirty array size - dirty pages visible to this txn.
* Includes ancestor txns' dirty pages not hidden by other txns'
* dirty/spilled pages. Thus commit(nested txn) has room to merge
* dirtylist into mt_parent after freeing hidden mt_parent pages. */
unsigned dirtyroom;
/* For write txns: Modified pages. Sorted when not MDBX_WRITEMAP. */
- MDBX_DPL dirtylist;
+ MDBX_dpl *dirtylist;
/* The list of reclaimed txns from GC */
MDBX_TXL lifo_reclaimed;
/* The list of pages that became unused during this transaction. */
@@ -2457,26 +2465,19 @@ struct MDBX_txn {
MDBX_page *loose_pages;
/* Number of loose pages (tw.loose_pages) */
unsigned loose_count;
- /* Number of retired to parent pages (tw.retired2parent_pages) */
- unsigned retired2parent_count;
- /* The list of parent's txn dirty pages that retired (became unused)
- * in this transaction, linked through `mp_next`. */
- MDBX_page *retired2parent_pages;
/* The sorted list of dirty pages we temporarily wrote to disk
* because the dirty list was full. page numbers in here are
* shifted left by 1, deleted slots have the LSB set. */
MDBX_PNL spill_pages;
+ unsigned spill_least_removed;
} tw;
};
};
-/* Enough space for 2^32 nodes with minimum of 2 keys per node. I.e., plenty.
- * At 4 keys per node, enough for 2^64 nodes, so there's probably no need to
- * raise this on a 64 bit machine. */
#if MDBX_WORDBITS >= 64
-#define CURSOR_STACK 28
+#define CURSOR_STACK 32
#else
-#define CURSOR_STACK 20
+#define CURSOR_STACK 24
#endif
struct MDBX_xcursor;
@@ -2606,11 +2607,9 @@ struct MDBX_env {
uint16_t *me_dbflags; /* array of flags from MDBX_db.md_flags */
unsigned *me_dbiseqs; /* array of dbi sequence numbers */
volatile txnid_t *me_oldest; /* ID of oldest reader last time we looked */
- MDBX_page *me_dpages; /* list of malloc'd blocks for re-use */
+ MDBX_page *me_dp_reserve; /* list of malloc'd blocks for re-use */
/* PNL of pages that became unused in a write txn */
MDBX_PNL me_retired_pages;
- /* MDBX_DP of pages written during a write txn. */
- MDBX_DPL me_dirtylist;
/* Number of freelist items that can fit in a single overflow page */
unsigned me_maxgc_ov1page;
unsigned me_branch_nodemax; /* max size of a branch-node */
@@ -2623,6 +2622,17 @@ struct MDBX_env {
volatile pgno_t *me_discarded_tail;
volatile uint32_t *me_meta_sync_txnid;
MDBX_hsr_func *me_hsr_callback; /* Callback for kicking laggard readers */
+ unsigned me_dp_reserve_len;
+ struct {
+ unsigned dp_reserve_limit;
+ unsigned rp_augment_limit;
+ unsigned dp_limit;
+ unsigned dp_initial;
+ uint8_t dp_loose_limit;
+ uint8_t spill_max_denominator;
+ uint8_t spill_min_denominator;
+ uint8_t spill_parent4child_denominator;
+ } me_options;
struct {
#if MDBX_LOCKING > 0
mdbx_ipclock_t wlock;
@@ -3370,7 +3380,16 @@ int main(int argc, char *argv[]) {
if (argc < 2)
usage();
- while ((i = getopt(argc, argv, "af:lnps:Vrq")) != EOF) {
+ while ((i = getopt(argc, argv,
+ "a"
+ "f:"
+ "l"
+ "n"
+ "p"
+ "s:"
+ "V"
+ "r"
+ "q")) != EOF) {
switch (i) {
case 'V':
printf("mdbx_dump version %d.%d.%d.%d\n"