diff options
Diffstat (limited to 'libs/libmdbx/src/mdbx_dump.c')
-rw-r--r-- | libs/libmdbx/src/mdbx_dump.c | 141 |
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" |