mirror of
https://github.com/isar/libmdbx.git
synced 2025-01-06 23:04:13 +08:00
mdbx: rework PNL, DPL and TXN lists.
Change-Id: I79c7399912516b17cc255fc8e24b5941338e5eb1
This commit is contained in:
parent
8f51b6bac2
commit
e00dce3543
59
src/bits.h
59
src/bits.h
@ -479,6 +479,10 @@ typedef struct MDBX_lockinfo {
|
|||||||
|
|
||||||
#define MDBX_LOCK_MAGIC ((MDBX_MAGIC << 8) + MDBX_LOCK_VERSION)
|
#define MDBX_LOCK_MAGIC ((MDBX_MAGIC << 8) + MDBX_LOCK_VERSION)
|
||||||
|
|
||||||
|
#ifndef MDBX_ASSUME_MALLOC_OVERHEAD
|
||||||
|
#define MDBX_ASSUME_MALLOC_OVERHEAD (sizeof(void *) * 2u)
|
||||||
|
#endif /* MDBX_ASSUME_MALLOC_OVERHEAD */
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------*/
|
/*----------------------------------------------------------------------------*/
|
||||||
/* Two kind lists of pages (aka PNL) */
|
/* Two kind lists of pages (aka PNL) */
|
||||||
|
|
||||||
@ -500,33 +504,46 @@ typedef pgno_t *MDBX_PNL;
|
|||||||
/* List of txnid, only for MDBX_env.mt_lifo_reclaimed */
|
/* List of txnid, only for MDBX_env.mt_lifo_reclaimed */
|
||||||
typedef txnid_t *MDBX_TXL;
|
typedef txnid_t *MDBX_TXL;
|
||||||
|
|
||||||
/* An ID2 is an ID/pointer pair. */
|
/* An Dirty-Page list item is an pgno/pointer pair. */
|
||||||
typedef union MDBX_ID2 {
|
typedef union MDBX_DP {
|
||||||
struct {
|
struct {
|
||||||
pgno_t pgno;
|
pgno_t pgno;
|
||||||
void *ptr;
|
void *ptr;
|
||||||
};
|
};
|
||||||
unsigned limit, length;
|
struct {
|
||||||
} MDBX_ID2;
|
pgno_t unused;
|
||||||
|
unsigned length;
|
||||||
|
};
|
||||||
|
} MDBX_DP;
|
||||||
|
|
||||||
/* An ID2L is an ID2 List, a sorted array of ID2s.
|
/* An DPL (dirty-page list) is a sorted array of MDBX_DPs.
|
||||||
* The first element's mid member is a count of how many actual
|
* The first element's length member is a count of how many actual
|
||||||
* elements are in the array. The mptr member of the first element is
|
* elements are in the array. */
|
||||||
* unused. The array is sorted in ascending order by mid. */
|
typedef MDBX_DP *MDBX_DPL;
|
||||||
typedef MDBX_ID2 *MDBX_ID2L;
|
|
||||||
|
|
||||||
/* PNL sizes - likely should be even bigger
|
/* PNL sizes - likely should be even bigger */
|
||||||
* limiting factors: sizeof(pgno_t), thread stack size */
|
#define MDBX_PNL_GRANULATE 1024
|
||||||
#define MDBX_LIST_MAX ((1 << 24) - 1)
|
#define MDBX_PNL_INITIAL \
|
||||||
|
(MDBX_PNL_GRANULATE - 2 - MDBX_ASSUME_MALLOC_OVERHEAD / sizeof(pgno_t))
|
||||||
|
#define MDBX_PNL_MAX \
|
||||||
|
((1u << 24) - 2 - MDBX_ASSUME_MALLOC_OVERHEAD / sizeof(pgno_t))
|
||||||
|
#define MDBX_DPL_TXNFULL (MDBX_PNL_MAX / 4)
|
||||||
|
|
||||||
#define MDBX_PNL_SIZEOF(pl) (((pl)[0] + 1) * sizeof(pgno_t))
|
#define MDBX_TXL_GRANULATE 32
|
||||||
#define MDBX_PNL_IS_ZERO(pl) ((pl)[0] == 0)
|
#define MDBX_TXL_INITIAL \
|
||||||
#define MDBX_PNL_CPY(dst, src) (memcpy(dst, src, MDBX_PNL_SIZEOF(src)))
|
(MDBX_TXL_GRANULATE - 2 - MDBX_ASSUME_MALLOC_OVERHEAD / sizeof(txnid_t))
|
||||||
#define MDBX_PNL_FIRST(pl) ((pl)[1])
|
#define MDBX_TXL_MAX \
|
||||||
#define MDBX_PNL_LAST(pl) ((pl)[(pl)[0]])
|
((1u << 17) - 2 - MDBX_ASSUME_MALLOC_OVERHEAD / sizeof(txnid_t))
|
||||||
|
|
||||||
/* Current max length of an mdbx_pnl_alloc()ed PNL */
|
|
||||||
#define MDBX_PNL_ALLOCLEN(pl) ((pl)[-1])
|
#define MDBX_PNL_ALLOCLEN(pl) ((pl)[-1])
|
||||||
|
#define MDBX_PNL_SIZE(pl) ((pl)[0])
|
||||||
|
#define MDBX_PNL_FIRST(pl) ((pl)[1])
|
||||||
|
#define MDBX_PNL_LAST(pl) ((pl)[MDBX_PNL_SIZE(pl)])
|
||||||
|
#define MDBX_PNL_BEGIN(pl) (&(pl)[1])
|
||||||
|
#define MDBX_PNL_END(pl) (&(pl)[MDBX_PNL_SIZE(pl) + 1])
|
||||||
|
|
||||||
|
#define MDBX_PNL_SIZEOF(pl) ((MDBX_PNL_SIZE(pl) + 1) * sizeof(pgno_t))
|
||||||
|
#define MDBX_PNL_IS_EMPTY(pl) (MDBX_PNL_SIZE(pl) == 0)
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------*/
|
/*----------------------------------------------------------------------------*/
|
||||||
/* Internal structures */
|
/* Internal structures */
|
||||||
@ -570,7 +587,7 @@ struct MDBX_txn {
|
|||||||
MDBX_PNL mt_spill_pages;
|
MDBX_PNL mt_spill_pages;
|
||||||
union {
|
union {
|
||||||
/* For write txns: Modified pages. Sorted when not MDBX_WRITEMAP. */
|
/* For write txns: Modified pages. Sorted when not MDBX_WRITEMAP. */
|
||||||
MDBX_ID2L mt_rw_dirtylist;
|
MDBX_DPL mt_rw_dirtylist;
|
||||||
/* For read txns: This thread/txn's reader table slot, or NULL. */
|
/* For read txns: This thread/txn's reader table slot, or NULL. */
|
||||||
MDBX_reader *mt_ro_reader;
|
MDBX_reader *mt_ro_reader;
|
||||||
};
|
};
|
||||||
@ -767,8 +784,8 @@ struct MDBX_env {
|
|||||||
MDBX_page *me_dpages; /* list of malloc'd blocks for re-use */
|
MDBX_page *me_dpages; /* list of malloc'd blocks for re-use */
|
||||||
/* PNL of pages that became unused in a write txn */
|
/* PNL of pages that became unused in a write txn */
|
||||||
MDBX_PNL me_free_pgs;
|
MDBX_PNL me_free_pgs;
|
||||||
/* ID2L of pages written during a write txn. Length MDBX_LIST_MAX. */
|
/* MDBX_DP of pages written during a write txn. Length MDBX_DPL_TXNFULL. */
|
||||||
MDBX_ID2L me_dirtylist;
|
MDBX_DPL me_dirtylist;
|
||||||
/* Number of freelist items that can fit in a single overflow page */
|
/* Number of freelist items that can fit in a single overflow page */
|
||||||
unsigned me_maxgc_ov1page;
|
unsigned me_maxgc_ov1page;
|
||||||
/* Max size of a node on a page */
|
/* Max size of a node on a page */
|
||||||
|
758
src/mdbx.c
758
src/mdbx.c
File diff suppressed because it is too large
Load Diff
@ -412,7 +412,7 @@ static int handle_freedb(const uint64_t record_number, const MDBX_val *key,
|
|||||||
problem_add("entry", record_number, "wrong idl size", "%" PRIuPTR,
|
problem_add("entry", record_number, "wrong idl size", "%" PRIuPTR,
|
||||||
data->iov_len);
|
data->iov_len);
|
||||||
size_t number = (data->iov_len >= sizeof(pgno_t)) ? *iptr++ : 0;
|
size_t number = (data->iov_len >= sizeof(pgno_t)) ? *iptr++ : 0;
|
||||||
if (number < 1 || number > MDBX_LIST_MAX)
|
if (number < 1 || number > MDBX_PNL_MAX)
|
||||||
problem_add("entry", record_number, "wrong idl length", "%" PRIuPTR,
|
problem_add("entry", record_number, "wrong idl length", "%" PRIuPTR,
|
||||||
number);
|
number);
|
||||||
else if ((number + 1) * sizeof(pgno_t) > data->iov_len) {
|
else if ((number + 1) * sizeof(pgno_t) > data->iov_len) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user