mirror of
https://github.com/isar/libmdbx.git
synced 2025-01-04 17:04:13 +08:00
mdbx: rework MDBX_page, drop COPY_PGNO.
This commit is contained in:
parent
8f2c21e2ba
commit
a3ed42b999
61
src/bits.h
61
src/bits.h
@ -283,13 +283,11 @@ typedef struct MDB_meta {
|
||||
*
|
||||
* Each non-metapage up to MDB_meta.mm_last_pg is reachable exactly once
|
||||
* in the snapshot: Either used by a database or listed in a freeDB record. */
|
||||
typedef struct MDB_page {
|
||||
#define mp_pgno mp_p.p_pgno
|
||||
#define mp_next mp_p.p_next
|
||||
typedef struct MDBX_page {
|
||||
union {
|
||||
pgno_t p_pgno; /* page number */
|
||||
struct MDB_page *p_next; /* for in-memory list of freed pages */
|
||||
} mp_p;
|
||||
pgno_t mp_pgno; /* page number */
|
||||
struct MDBX_page *mp_next; /* for in-memory list of freed pages */
|
||||
};
|
||||
uint16_t mp_leaf2_ksize; /* key size if this is a LEAF2 page */
|
||||
#define P_BRANCH 0x01 /* branch page */
|
||||
#define P_LEAF 0x02 /* leaf page */
|
||||
@ -301,28 +299,25 @@ typedef struct MDB_page {
|
||||
#define P_LOOSE 0x4000 /* page was dirtied then freed, can be reused */
|
||||
#define P_KEEP 0x8000 /* leave this page alone during spill */
|
||||
uint16_t mp_flags;
|
||||
#define mp_lower mp_pb.pb.pb_lower
|
||||
#define mp_upper mp_pb.pb.pb_upper
|
||||
#define mp_pages mp_pb.pb_pages
|
||||
union {
|
||||
struct {
|
||||
indx_t pb_lower; /* lower bound of free space */
|
||||
indx_t pb_upper; /* upper bound of free space */
|
||||
} pb;
|
||||
uint32_t pb_pages; /* number of overflow pages */
|
||||
} mp_pb;
|
||||
indx_t mp_lower; /* lower bound of free space */
|
||||
indx_t mp_upper; /* upper bound of free space */
|
||||
};
|
||||
uint32_t mp_pages; /* number of overflow pages */
|
||||
};
|
||||
indx_t mp_ptrs[1]; /* dynamic size */
|
||||
} MDB_page;
|
||||
} MDBX_page;
|
||||
|
||||
/* Size of the page header, excluding dynamic data at the end */
|
||||
#define PAGEHDRSZ ((unsigned)offsetof(MDB_page, mp_ptrs))
|
||||
#define PAGEHDRSZ ((unsigned)offsetof(MDBX_page, mp_ptrs))
|
||||
|
||||
/* Buffer for a stack-allocated meta page.
|
||||
* The members define size and alignment, and silence type
|
||||
* aliasing warnings. They are not used directly; that could
|
||||
* mean incorrectly using several union members in parallel. */
|
||||
typedef union MDB_metabuf {
|
||||
MDB_page mb_page;
|
||||
MDBX_page mb_page;
|
||||
struct {
|
||||
char mm_pad[PAGEHDRSZ];
|
||||
MDB_meta mm_meta;
|
||||
@ -384,7 +379,7 @@ struct MDB_txn {
|
||||
MDB_IDL mt_free_pgs;
|
||||
/* The list of loose pages that became unused and may be reused
|
||||
* in this transaction, linked through NEXT_LOOSE_PAGE(page). */
|
||||
MDB_page *mt_loose_pgs;
|
||||
MDBX_page *mt_loose_pgs;
|
||||
/* Number of loose pages (mt_loose_pgs) */
|
||||
unsigned mt_loose_count;
|
||||
/* The sorted list of dirty pages we temporarily wrote to disk
|
||||
@ -480,18 +475,18 @@ struct MDB_cursor {
|
||||
MDB_dbx *mc_dbx;
|
||||
/* The mt_dbflag for this database */
|
||||
uint8_t *mc_dbflag;
|
||||
uint16_t mc_snum; /* number of pushed pages */
|
||||
uint16_t mc_top; /* index of top page, normally mc_snum-1 */
|
||||
/* Cursor state flags. */
|
||||
#define C_INITIALIZED 0x01 /* cursor has been initialized and is valid */
|
||||
#define C_EOF 0x02 /* No more data */
|
||||
#define C_SUB 0x04 /* Cursor is a sub-cursor */
|
||||
#define C_DEL 0x08 /* last op was a cursor_del */
|
||||
#define C_UNTRACK 0x40 /* Un-track cursor when closing */
|
||||
#define C_RECLAIMING 0x80 /* FreeDB lookup is prohibited */
|
||||
unsigned mc_flags; /* see mdbx_cursor */
|
||||
MDB_page *mc_pg[CURSOR_STACK]; /* stack of pushed pages */
|
||||
indx_t mc_ki[CURSOR_STACK]; /* stack of page indices */
|
||||
uint16_t mc_snum; /* number of pushed pages */
|
||||
uint16_t mc_top; /* index of top page, normally mc_snum-1 */
|
||||
/* Cursor state flags. */
|
||||
#define C_INITIALIZED 0x01 /* cursor has been initialized and is valid */
|
||||
#define C_EOF 0x02 /* No more data */
|
||||
#define C_SUB 0x04 /* Cursor is a sub-cursor */
|
||||
#define C_DEL 0x08 /* last op was a cursor_del */
|
||||
#define C_UNTRACK 0x40 /* Un-track cursor when closing */
|
||||
#define C_RECLAIMING 0x80 /* FreeDB lookup is prohibited */
|
||||
unsigned mc_flags; /* see mdbx_cursor */
|
||||
MDBX_page *mc_pg[CURSOR_STACK]; /* stack of pushed pages */
|
||||
indx_t mc_ki[CURSOR_STACK]; /* stack of page indices */
|
||||
};
|
||||
|
||||
/* Context for sorted-dup records.
|
||||
@ -518,7 +513,7 @@ typedef struct MDB_xcursor {
|
||||
* Called with mp = mc->mc_pg[mc->mc_top], ki = mc->mc_ki[mc->mc_top]. */
|
||||
#define XCURSOR_REFRESH(mc, mp, ki) \
|
||||
do { \
|
||||
MDB_page *xr_pg = (mp); \
|
||||
MDBX_page *xr_pg = (mp); \
|
||||
MDBX_node *xr_node = NODEPTR(xr_pg, ki); \
|
||||
if ((xr_node->mn_flags & (F_DUPDATA | F_SUBDATA)) == F_DUPDATA) \
|
||||
(mc)->mc_xcursor->mx_cursor.mc_pg[0] = NODEDATA(xr_node); \
|
||||
@ -577,8 +572,8 @@ struct MDB_env {
|
||||
MDB_pgstate me_pgstate; /* state of old pages from freeDB */
|
||||
#define me_pglast me_pgstate.mf_pglast
|
||||
#define me_pghead me_pgstate.mf_pghead
|
||||
MDB_page *me_dpages; /* list of malloc'd blocks for re-use */
|
||||
/* IDL of pages that became unused in a write txn */
|
||||
MDBX_page *me_dpages; /* list of malloc'd blocks for re-use */
|
||||
/* IDL of pages that became unused in a write txn */
|
||||
MDB_IDL me_free_pgs;
|
||||
/* ID2L of pages written during a write txn. Length MDB_IDL_UM_SIZE. */
|
||||
MDB_ID2L me_dirty_list;
|
||||
|
269
src/mdbx.c
269
src/mdbx.c
@ -270,7 +270,7 @@ txnid_t mdbx_debug_edge;
|
||||
/* The maximum size of a database page.
|
||||
*
|
||||
* It is 32k or 64k, since value-PAGEBASE must fit in
|
||||
* MDB_page.mp_upper.
|
||||
* MDBX_page.mp_upper.
|
||||
*
|
||||
* LMDB will use database pages < OS pages if needed.
|
||||
* That causes more I/O in write transactions: The OS must
|
||||
@ -416,7 +416,7 @@ txnid_t mdbx_debug_edge;
|
||||
|
||||
/* Link in MDB_txn.mt_loose_pgs list.
|
||||
* Kept outside the page header, which is needed when reusing the page. */
|
||||
#define NEXT_LOOSE_PAGE(p) (*(MDB_page **)((p) + 2))
|
||||
#define NEXT_LOOSE_PAGE(p) (*(MDBX_page **)((p) + 2))
|
||||
|
||||
/* Header for a single key/data pair within a page.
|
||||
* Used in pages of type P_BRANCH and P_LEAF without P_LEAF2.
|
||||
@ -482,7 +482,7 @@ typedef struct MDBX_node {
|
||||
#define LEAFSIZE(k, d) (NODESIZE + (k)->mv_size + (d)->mv_size)
|
||||
|
||||
/* Address of node i in page p */
|
||||
static __inline MDBX_node *NODEPTR(MDB_page *p, unsigned i) {
|
||||
static __inline MDBX_node *NODEPTR(MDBX_page *p, unsigned i) {
|
||||
assert(NUMKEYS(p) > (unsigned)(i));
|
||||
return (MDBX_node *)((char *)(p) + (p)->mp_ptrs[i] + PAGEBASE);
|
||||
}
|
||||
@ -549,27 +549,6 @@ static __inline void SETDSZ(MDBX_node *node, unsigned size) {
|
||||
/* The size of a key in a node */
|
||||
#define NODEKSZ(node) ((node)->mn_ksize)
|
||||
|
||||
/* Copy a page number from src to dst */
|
||||
#if UNALIGNED_OK
|
||||
#define COPY_PGNO(dst, src) (dst) = (src)
|
||||
#elif defined(__GNUC__) || __has_builtin(__built_memcmp)
|
||||
#define COPY_PGNO(dst, src) __built_memcmp(&(dst), &(src), sizeof(pgno_t));
|
||||
#else
|
||||
#define COPY_PGNO(dst, src) \
|
||||
do { \
|
||||
uint16_t *s, *d; \
|
||||
s = (uint16_t *)&(src); \
|
||||
d = (uint16_t *)&(dst); \
|
||||
if (sizeof(pgno_t) > 6) \
|
||||
*d++ = *s++; \
|
||||
if (sizeof(pgno_t) > 4) \
|
||||
*d++ = *s++; \
|
||||
if (sizeof(pgno_t) > 2) \
|
||||
*d++ = *s++; \
|
||||
*d = *s; \
|
||||
} while (0)
|
||||
#endif /* UNALIGNED_OK */
|
||||
|
||||
/* The address of a key in a LEAF2 page.
|
||||
* LEAF2 pages are used for MDB_DUPFIXED sorted-duplicate sub-DBs.
|
||||
* There are no node headers, keys are stored contiguously. */
|
||||
@ -613,9 +592,9 @@ static __inline void SETDSZ(MDBX_node *node, unsigned size) {
|
||||
#define TXN_DBI_CHANGED(txn, dbi) \
|
||||
((txn)->mt_dbiseqs[dbi] != (txn)->mt_env->me_dbiseqs[dbi])
|
||||
|
||||
static int mdbx_page_alloc(MDB_cursor *mc, int num, MDB_page **mp, int flags);
|
||||
static int mdbx_page_alloc(MDB_cursor *mc, int num, MDBX_page **mp, int flags);
|
||||
static int mdbx_page_new(MDB_cursor *mc, uint32_t flags, int num,
|
||||
MDB_page **mp);
|
||||
MDBX_page **mp);
|
||||
static int mdbx_page_touch(MDB_cursor *mc);
|
||||
static int mdbx_cursor_touch(MDB_cursor *mc);
|
||||
|
||||
@ -641,7 +620,7 @@ enum {
|
||||
#define MDB_END_SLOT 0x80 /* release any reader slot if MDB_NOTLS */
|
||||
static int mdbx_txn_end(MDB_txn *txn, unsigned mode);
|
||||
|
||||
static int mdbx_page_get(MDB_cursor *mc, pgno_t pgno, MDB_page **mp, int *lvl);
|
||||
static int mdbx_page_get(MDB_cursor *mc, pgno_t pgno, MDBX_page **mp, int *lvl);
|
||||
static int mdbx_page_search_root(MDB_cursor *mc, MDB_val *key, int modify);
|
||||
#define MDB_PS_MODIFY 1
|
||||
#define MDB_PS_ROOTONLY 2
|
||||
@ -663,7 +642,7 @@ static MDBX_node *mdbx_node_search(MDB_cursor *mc, MDB_val *key, int *exactp);
|
||||
static int mdbx_node_add(MDB_cursor *mc, indx_t indx, MDB_val *key,
|
||||
MDB_val *data, pgno_t pgno, unsigned flags);
|
||||
static void mdbx_node_del(MDB_cursor *mc, int ksize);
|
||||
static void mdbx_node_shrink(MDB_page *mp, indx_t indx);
|
||||
static void mdbx_node_shrink(MDBX_page *mp, indx_t indx);
|
||||
static int mdbx_node_move(MDB_cursor *csrc, MDB_cursor *cdst, int fromleft);
|
||||
static int mdbx_node_read(MDB_cursor *mc, MDBX_node *leaf, MDB_val *data);
|
||||
static size_t mdbx_leaf_size(MDB_env *env, MDB_val *key, MDB_val *data);
|
||||
@ -673,7 +652,7 @@ static int mdbx_rebalance(MDB_cursor *mc);
|
||||
static int mdbx_update_key(MDB_cursor *mc, MDB_val *key);
|
||||
|
||||
static void mdbx_cursor_pop(MDB_cursor *mc);
|
||||
static int mdbx_cursor_push(MDB_cursor *mc, MDB_page *mp);
|
||||
static int mdbx_cursor_push(MDB_cursor *mc, MDBX_page *mp);
|
||||
|
||||
static int mdbx_cursor_del0(MDB_cursor *mc);
|
||||
static int mdbx_del0(MDB_txn *txn, MDB_dbi dbi, MDB_val *key, MDB_val *data,
|
||||
@ -830,13 +809,6 @@ void __cold mdbx_debug_log(int type, const char *function, int line,
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
/* Return the page number of mp which may be sub-page, for debug output */
|
||||
static __inline pgno_t mdbx_dbg_pgno(MDB_page *mp) {
|
||||
pgno_t ret;
|
||||
COPY_PGNO(ret, mp->mp_pgno);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Dump a key in ascii or hexadecimal. */
|
||||
char *mdbx_dkey(const MDB_val *key, char *const buf, const size_t bufsize) {
|
||||
if (!key)
|
||||
@ -888,8 +860,8 @@ static const char *mdbx_leafnode_type(MDBX_node *n) {
|
||||
}
|
||||
|
||||
/* Display all the keys in the page. */
|
||||
static void mdbx_page_list(MDB_page *mp) {
|
||||
pgno_t pgno = mdbx_dbg_pgno(mp);
|
||||
static void mdbx_page_list(MDBX_page *mp) {
|
||||
pgno_t pgno = mp->mp_pgno;
|
||||
const char *type, *state = (mp->mp_flags & P_DIRTY) ? ", dirty" : "";
|
||||
MDBX_node *node;
|
||||
unsigned i, nkeys, nsize, total = 0;
|
||||
@ -965,7 +937,7 @@ static void mdbx_page_list(MDB_page *mp) {
|
||||
static void mdbx_cursor_chk(MDB_cursor *mc) {
|
||||
unsigned i;
|
||||
MDBX_node *node;
|
||||
MDB_page *mp;
|
||||
MDBX_page *mp;
|
||||
|
||||
if (!mc->mc_snum || !(mc->mc_flags & C_INITIALIZED))
|
||||
return;
|
||||
@ -1017,7 +989,7 @@ static void mdbx_audit(MDB_txn *txn) {
|
||||
rc = mdbx_page_search(&mc, NULL, MDB_PS_FIRST);
|
||||
for (; rc == MDB_SUCCESS; rc = mdbx_cursor_sibling(&mc, 1)) {
|
||||
unsigned j;
|
||||
MDB_page *mp;
|
||||
MDBX_page *mp;
|
||||
mp = mc.mc_pg[mc.mc_top];
|
||||
for (j = 0; j < NUMKEYS(mp); j++) {
|
||||
MDBX_node *leaf = NODEPTR(mp, j);
|
||||
@ -1053,10 +1025,10 @@ int mdbx_dcmp(MDB_txn *txn, MDB_dbi dbi, const MDB_val *a, const MDB_val *b) {
|
||||
/* Allocate memory for a page.
|
||||
* Re-use old malloc'd pages first for singletons, otherwise just malloc.
|
||||
* Set MDB_TXN_ERROR on failure. */
|
||||
static MDB_page *mdbx_page_malloc(MDB_txn *txn, unsigned num) {
|
||||
static MDBX_page *mdbx_page_malloc(MDB_txn *txn, unsigned num) {
|
||||
MDB_env *env = txn->mt_env;
|
||||
size_t size = env->me_psize;
|
||||
MDB_page *np = env->me_dpages;
|
||||
MDBX_page *np = env->me_dpages;
|
||||
if (likely(num == 1 && np)) {
|
||||
ASAN_UNPOISON_MEMORY_REGION(np, size);
|
||||
VALGRIND_MEMPOOL_ALLOC(env, np, size);
|
||||
@ -1090,14 +1062,14 @@ static MDB_page *mdbx_page_malloc(MDB_txn *txn, unsigned num) {
|
||||
/* Free a single page.
|
||||
* Saves single pages to a list, for future reuse.
|
||||
* (This is not used for multi-page overflow pages.) */
|
||||
static __inline void mdbx_page_free(MDB_env *env, MDB_page *mp) {
|
||||
static __inline void mdbx_page_free(MDB_env *env, MDBX_page *mp) {
|
||||
mp->mp_next = env->me_dpages;
|
||||
VALGRIND_MEMPOOL_FREE(env, mp);
|
||||
env->me_dpages = mp;
|
||||
}
|
||||
|
||||
/* Free a dirty page */
|
||||
static void mdbx_dpage_free(MDB_env *env, MDB_page *dp) {
|
||||
static void mdbx_dpage_free(MDB_env *env, MDBX_page *dp) {
|
||||
if (!IS_OVERFLOW(dp) || dp->mp_pages == 1) {
|
||||
mdbx_page_free(env, dp);
|
||||
} else {
|
||||
@ -1121,13 +1093,13 @@ static void mdbx_dlist_free(MDB_txn *txn) {
|
||||
|
||||
static void __cold mdbx_kill_page(MDB_env *env, pgno_t pgno) {
|
||||
const size_t offs = env->me_psize * pgno;
|
||||
const size_t shift = offsetof(MDB_page, mp_pb);
|
||||
const size_t shift = offsetof(MDBX_page, mp_pages);
|
||||
|
||||
if (env->me_flags & MDB_WRITEMAP) {
|
||||
MDB_page *mp = (MDB_page *)(env->me_map + offs);
|
||||
memset(&mp->mp_pb, 0x6F /* 'o', 111 */, env->me_psize - shift);
|
||||
VALGRIND_MAKE_MEM_NOACCESS(&mp->mp_pb, env->me_psize - shift);
|
||||
ASAN_POISON_MEMORY_REGION(&mp->mp_pb, env->me_psize - shift);
|
||||
MDBX_page *mp = (MDBX_page *)(env->me_map + offs);
|
||||
memset(&mp->mp_pages, 0x6F /* 'o', 111 */, env->me_psize - shift);
|
||||
VALGRIND_MAKE_MEM_NOACCESS(&mp->mp_pages, env->me_psize - shift);
|
||||
ASAN_POISON_MEMORY_REGION(&mp->mp_pages, env->me_psize - shift);
|
||||
} else {
|
||||
ssize_t len = env->me_psize - shift;
|
||||
void *buf = alloca(len);
|
||||
@ -1146,7 +1118,7 @@ static void __cold mdbx_kill_page(MDB_env *env, pgno_t pgno) {
|
||||
*
|
||||
* If the page wasn't dirtied in this txn, just add it
|
||||
* to this txn's free list. */
|
||||
static int mdbx_page_loose(MDB_cursor *mc, MDB_page *mp) {
|
||||
static int mdbx_page_loose(MDB_cursor *mc, MDBX_page *mp) {
|
||||
int loose = 0;
|
||||
pgno_t pgno = mp->mp_pgno;
|
||||
MDB_txn *txn = mc->mc_txn;
|
||||
@ -1175,11 +1147,11 @@ static int mdbx_page_loose(MDB_cursor *mc, MDB_page *mp) {
|
||||
}
|
||||
if (loose) {
|
||||
mdbx_debug("loosen db %d page %" PRIaPGNO, DDBI(mc), mp->mp_pgno);
|
||||
MDB_page **link = &NEXT_LOOSE_PAGE(mp);
|
||||
MDBX_page **link = &NEXT_LOOSE_PAGE(mp);
|
||||
if (unlikely(txn->mt_env->me_flags & MDBX_PAGEPERTURB)) {
|
||||
mdbx_kill_page(txn->mt_env, pgno);
|
||||
VALGRIND_MAKE_MEM_UNDEFINED(link, sizeof(MDB_page *));
|
||||
ASAN_UNPOISON_MEMORY_REGION(link, sizeof(MDB_page *));
|
||||
VALGRIND_MAKE_MEM_UNDEFINED(link, sizeof(MDBX_page *));
|
||||
ASAN_UNPOISON_MEMORY_REGION(link, sizeof(MDBX_page *));
|
||||
}
|
||||
*link = txn->mt_loose_pgs;
|
||||
txn->mt_loose_pgs = mp;
|
||||
@ -1208,7 +1180,7 @@ static int mdbx_pages_xkeep(MDB_cursor *mc, unsigned pflags, int all) {
|
||||
MDB_txn *txn = mc->mc_txn;
|
||||
MDB_cursor *m3, *m0 = mc;
|
||||
MDB_xcursor *mx;
|
||||
MDB_page *dp, *mp;
|
||||
MDBX_page *dp, *mp;
|
||||
MDBX_node *leaf;
|
||||
unsigned i, j;
|
||||
int rc = MDB_SUCCESS, level;
|
||||
@ -1298,7 +1270,7 @@ static int mdbx_page_flush(MDB_txn *txn, int keep);
|
||||
* Returns 0 on success, non-zero on failure. */
|
||||
static int mdbx_page_spill(MDB_cursor *m0, MDB_val *key, MDB_val *data) {
|
||||
MDB_txn *txn = m0->mc_txn;
|
||||
MDB_page *dp;
|
||||
MDBX_page *dp;
|
||||
MDB_ID2L dl = txn->mt_u.dirty_list;
|
||||
unsigned i, j, need;
|
||||
int rc;
|
||||
@ -1442,7 +1414,7 @@ static txnid_t mdbx_find_oldest(MDB_env *env, int *laggard) {
|
||||
}
|
||||
|
||||
/* Add a page to the txn's dirty list */
|
||||
static void mdbx_page_dirty(MDB_txn *txn, MDB_page *mp) {
|
||||
static void mdbx_page_dirty(MDB_txn *txn, MDBX_page *mp) {
|
||||
MDB_ID2 mid;
|
||||
int rc, (*insert)(MDB_ID2L, MDB_ID2 *);
|
||||
|
||||
@ -1482,13 +1454,13 @@ static void mdbx_page_dirty(MDB_txn *txn, MDB_page *mp) {
|
||||
#define MDBX_ALLOC_ALL \
|
||||
(MDBX_ALLOC_CACHE | MDBX_ALLOC_GC | MDBX_ALLOC_NEW | MDBX_ALLOC_KICK)
|
||||
|
||||
static int mdbx_page_alloc(MDB_cursor *mc, int num, MDB_page **mp, int flags) {
|
||||
static int mdbx_page_alloc(MDB_cursor *mc, int num, MDBX_page **mp, int flags) {
|
||||
int rc;
|
||||
MDB_txn *txn = mc->mc_txn;
|
||||
MDB_env *env = txn->mt_env;
|
||||
pgno_t pgno, *mop = env->me_pghead;
|
||||
unsigned i = 0, j, mop_len = mop ? mop[0] : 0, n2 = num - 1;
|
||||
MDB_page *np;
|
||||
MDBX_page *np;
|
||||
txnid_t oldest = 0, last = 0;
|
||||
MDB_cursor_op op;
|
||||
MDB_cursor m2;
|
||||
@ -1764,7 +1736,7 @@ static int mdbx_page_alloc(MDB_cursor *mc, int num, MDB_page **mp, int flags) {
|
||||
done:
|
||||
assert(mp && num);
|
||||
if (env->me_flags & MDB_WRITEMAP) {
|
||||
np = (MDB_page *)(env->me_map + env->me_psize * pgno);
|
||||
np = (MDBX_page *)(env->me_map + env->me_psize * pgno);
|
||||
/* LY: reset no-access flag from mdbx_kill_page() */
|
||||
VALGRIND_MAKE_MEM_UNDEFINED(np, env->me_psize * num);
|
||||
ASAN_UNPOISON_MEMORY_REGION(np, env->me_psize * num);
|
||||
@ -1801,7 +1773,7 @@ done:
|
||||
* [in] dst page to copy into
|
||||
* [in] src page to copy from
|
||||
* [in] psize size of a page */
|
||||
static void mdbx_page_copy(MDB_page *dst, MDB_page *src, unsigned psize) {
|
||||
static void mdbx_page_copy(MDBX_page *dst, MDBX_page *src, unsigned psize) {
|
||||
enum { Align = sizeof(pgno_t) };
|
||||
indx_t upper = src->mp_upper, lower = src->mp_lower, unused = upper - lower;
|
||||
|
||||
@ -1826,7 +1798,7 @@ static void mdbx_page_copy(MDB_page *dst, MDB_page *src, unsigned psize) {
|
||||
* [in] mp the page being referenced. It must not be dirty.
|
||||
* [out] ret the writable page, if any.
|
||||
* ret is unchanged if mp wasn't spilled. */
|
||||
static int mdbx_page_unspill(MDB_txn *txn, MDB_page *mp, MDB_page **ret) {
|
||||
static int mdbx_page_unspill(MDB_txn *txn, MDBX_page *mp, MDBX_page **ret) {
|
||||
MDB_env *env = txn->mt_env;
|
||||
const MDB_txn *tx2;
|
||||
unsigned x;
|
||||
@ -1837,7 +1809,7 @@ static int mdbx_page_unspill(MDB_txn *txn, MDB_page *mp, MDB_page **ret) {
|
||||
continue;
|
||||
x = mdbx_midl_search(tx2->mt_spill_pgs, pn);
|
||||
if (x <= tx2->mt_spill_pgs[0] && tx2->mt_spill_pgs[x] == pn) {
|
||||
MDB_page *np;
|
||||
MDBX_page *np;
|
||||
int num;
|
||||
if (txn->mt_dirty_room == 0)
|
||||
return MDB_TXN_FULL;
|
||||
@ -1884,7 +1856,7 @@ static int mdbx_page_unspill(MDB_txn *txn, MDB_page *mp, MDB_page **ret) {
|
||||
*
|
||||
* Returns 0 on success, non-zero on failure. */
|
||||
static int mdbx_page_touch(MDB_cursor *mc) {
|
||||
MDB_page *mp = mc->mc_pg[mc->mc_top], *np;
|
||||
MDBX_page *mp = mc->mc_pg[mc->mc_top], *np;
|
||||
MDB_txn *txn = mc->mc_txn;
|
||||
MDB_cursor *m2, *m3;
|
||||
pgno_t pgno;
|
||||
@ -1909,7 +1881,7 @@ static int mdbx_page_touch(MDB_cursor *mc) {
|
||||
mdbx_midl_xappend(txn->mt_free_pgs, mp->mp_pgno);
|
||||
/* Update the parent page, if any, to point to the new page */
|
||||
if (mc->mc_top) {
|
||||
MDB_page *parent = mc->mc_pg[mc->mc_top - 1];
|
||||
MDBX_page *parent = mc->mc_pg[mc->mc_top - 1];
|
||||
MDBX_node *node = NODEPTR(parent, mc->mc_ki[mc->mc_top - 1]);
|
||||
SETPGNO(node, pgno);
|
||||
} else {
|
||||
@ -2707,7 +2679,7 @@ again:
|
||||
if (unlikely(!env->me_pghead) && txn->mt_loose_pgs) {
|
||||
/* Put loose page numbers in mt_free_pgs, since
|
||||
* we may be unable to return them to me_pghead. */
|
||||
MDB_page *mp = txn->mt_loose_pgs;
|
||||
MDBX_page *mp = txn->mt_loose_pgs;
|
||||
if (unlikely((rc = mdbx_midl_need(&txn->mt_free_pgs,
|
||||
txn->mt_loose_count)) != 0))
|
||||
return rc;
|
||||
@ -2844,7 +2816,7 @@ again:
|
||||
/* Return loose page numbers to me_pghead, though usually none are
|
||||
* left at this point. The pages themselves remain in dirty_list. */
|
||||
if (txn->mt_loose_pgs) {
|
||||
MDB_page *mp = txn->mt_loose_pgs;
|
||||
MDBX_page *mp = txn->mt_loose_pgs;
|
||||
unsigned count = txn->mt_loose_count;
|
||||
MDB_IDL loose;
|
||||
/* Room for loose pages + temp IDL with same */
|
||||
@ -2959,7 +2931,7 @@ static int mdbx_page_flush(MDB_txn *txn, int keep) {
|
||||
int i, pagecount = dl[0].mid, rc;
|
||||
size_t size = 0, pos = 0;
|
||||
pgno_t pgno = 0;
|
||||
MDB_page *dp = NULL;
|
||||
MDBX_page *dp = NULL;
|
||||
struct iovec iov[MDB_COMMIT_PAGES];
|
||||
ssize_t wpos = 0, wsize = 0;
|
||||
size_t next_pos = 1; /* impossible pos, so pos != next_pos */
|
||||
@ -3084,7 +3056,7 @@ int mdbx_txn_commit(MDB_txn *txn) {
|
||||
|
||||
if (txn->mt_parent) {
|
||||
MDB_txn *parent = txn->mt_parent;
|
||||
MDB_page **lp;
|
||||
MDBX_page **lp;
|
||||
MDB_ID2L dst, src;
|
||||
MDB_IDL pspill;
|
||||
unsigned i, x, y, len, ps_len;
|
||||
@ -3320,7 +3292,7 @@ static int __cold mdbx_read_header(MDB_env *env, MDB_meta *meta) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
MDB_page *p = (MDB_page *)&buf;
|
||||
MDBX_page *p = (MDBX_page *)&buf;
|
||||
if (!F_ISSET(p->mp_flags, P_META)) {
|
||||
mdbx_debug("page %" PRIaPGNO " not a meta-page", p->mp_pgno);
|
||||
return MDB_INVALID;
|
||||
@ -3390,14 +3362,14 @@ static int __cold mdbx_env_init_metas(const MDB_env *env, MDB_meta *model) {
|
||||
assert(offsetof(MDB_metabuf, mb_metabuf.mm_meta) == PAGEHDRSZ);
|
||||
|
||||
unsigned page_size = env->me_psize;
|
||||
MDB_page *first = calloc(NUM_METAS, page_size);
|
||||
MDBX_page *first = calloc(NUM_METAS, page_size);
|
||||
if (!first)
|
||||
return MDBX_ENOMEM;
|
||||
first->mp_pgno = 0;
|
||||
first->mp_flags = P_META;
|
||||
MDB_meta *first_meta = (MDB_meta *)PAGEDATA(first);
|
||||
|
||||
MDB_page *second = (MDB_page *)((char *)first + page_size);
|
||||
MDBX_page *second = (MDBX_page *)((char *)first + page_size);
|
||||
second->mp_pgno = 1;
|
||||
second->mp_flags = P_META;
|
||||
MDB_meta *second_meta = (MDB_meta *)PAGEDATA(second);
|
||||
@ -4226,7 +4198,7 @@ static void __cold mdbx_env_close0(MDB_env *env) {
|
||||
}
|
||||
|
||||
int __cold mdbx_env_close_ex(MDB_env *env, int dont_sync) {
|
||||
MDB_page *dp;
|
||||
MDBX_page *dp;
|
||||
int rc = MDB_SUCCESS;
|
||||
|
||||
if (unlikely(!env))
|
||||
@ -4415,7 +4387,7 @@ static MDBX_node *__hot mdbx_node_search(MDB_cursor *mc, MDB_val *key,
|
||||
unsigned i = 0, nkeys;
|
||||
int low, high;
|
||||
int rc = 0;
|
||||
MDB_page *mp = mc->mc_pg[mc->mc_top];
|
||||
MDBX_page *mp = mc->mc_pg[mc->mc_top];
|
||||
MDBX_node *node = NULL;
|
||||
MDB_val nodekey;
|
||||
MDB_cmp_func *cmp;
|
||||
@ -4425,7 +4397,7 @@ static MDBX_node *__hot mdbx_node_search(MDB_cursor *mc, MDB_val *key,
|
||||
|
||||
mdbx_debug("searching %u keys in %s %spage %" PRIaPGNO "", nkeys,
|
||||
IS_LEAF(mp) ? "leaf" : "branch", IS_SUBP(mp) ? "sub-" : "",
|
||||
mdbx_dbg_pgno(mp));
|
||||
mp->mp_pgno);
|
||||
|
||||
low = IS_LEAF(mp) ? 0 : 1;
|
||||
high = nkeys - 1;
|
||||
@ -4519,7 +4491,7 @@ static void mdbx_cursor_pop(MDB_cursor *mc) {
|
||||
|
||||
/* Push a page onto the top of the cursor's stack.
|
||||
* Set MDB_TXN_ERROR on failure. */
|
||||
static int mdbx_cursor_push(MDB_cursor *mc, MDB_page *mp) {
|
||||
static int mdbx_cursor_push(MDB_cursor *mc, MDBX_page *mp) {
|
||||
mdbx_debug("pushing page %" PRIaPGNO " on db %d cursor %p", mp->mp_pgno,
|
||||
DDBI(mc), (void *)mc);
|
||||
|
||||
@ -4546,11 +4518,11 @@ static int mdbx_cursor_push(MDB_cursor *mc, MDB_page *mp) {
|
||||
* 0=mapped page.
|
||||
*
|
||||
* Returns 0 on success, non-zero on failure. */
|
||||
static int mdbx_page_get(MDB_cursor *mc, pgno_t pgno, MDB_page **ret,
|
||||
static int mdbx_page_get(MDB_cursor *mc, pgno_t pgno, MDBX_page **ret,
|
||||
int *lvl) {
|
||||
MDB_txn *txn = mc->mc_txn;
|
||||
MDB_env *env = txn->mt_env;
|
||||
MDB_page *p = NULL;
|
||||
MDBX_page *p = NULL;
|
||||
int level;
|
||||
|
||||
if (!(txn->mt_flags & (MDB_TXN_RDONLY | MDB_TXN_WRITEMAP))) {
|
||||
@ -4588,7 +4560,7 @@ static int mdbx_page_get(MDB_cursor *mc, pgno_t pgno, MDB_page **ret,
|
||||
level = 0;
|
||||
|
||||
mapped:
|
||||
p = (MDB_page *)(env->me_map + env->me_psize * pgno);
|
||||
p = (MDBX_page *)(env->me_map + env->me_psize * pgno);
|
||||
|
||||
done:
|
||||
*ret = p;
|
||||
@ -4600,7 +4572,7 @@ done:
|
||||
/* Finish mdbx_page_search() / mdbx_page_search_lowest().
|
||||
* The cursor is at the root page, set up the rest of it. */
|
||||
static int mdbx_page_search_root(MDB_cursor *mc, MDB_val *key, int flags) {
|
||||
MDB_page *mp = mc->mc_pg[mc->mc_top];
|
||||
MDBX_page *mp = mc->mc_pg[mc->mc_top];
|
||||
int rc;
|
||||
DKBUF;
|
||||
|
||||
@ -4683,7 +4655,7 @@ static int mdbx_page_search_root(MDB_cursor *mc, MDB_val *key, int flags) {
|
||||
* are all in situations where the current page is known to
|
||||
* be underfilled. */
|
||||
static int mdbx_page_search_lowest(MDB_cursor *mc) {
|
||||
MDB_page *mp = mc->mc_pg[mc->mc_top];
|
||||
MDBX_page *mp = mc->mc_pg[mc->mc_top];
|
||||
MDBX_node *node = NODEPTR(mp, 0);
|
||||
int rc;
|
||||
|
||||
@ -4781,7 +4753,7 @@ static int mdbx_page_search(MDB_cursor *mc, MDB_val *key, int flags) {
|
||||
return mdbx_page_search_root(mc, key, flags);
|
||||
}
|
||||
|
||||
static int mdbx_ovpage_free(MDB_cursor *mc, MDB_page *mp) {
|
||||
static int mdbx_ovpage_free(MDB_cursor *mc, MDBX_page *mp) {
|
||||
MDB_txn *txn = mc->mc_txn;
|
||||
pgno_t pg = mp->mp_pgno;
|
||||
unsigned x = 0, ovpages = mp->mp_pages;
|
||||
@ -4861,7 +4833,7 @@ static int mdbx_ovpage_free(MDB_cursor *mc, MDB_page *mp) {
|
||||
* Returns 0 on success, non-zero on failure. */
|
||||
static __inline int mdbx_node_read(MDB_cursor *mc, MDBX_node *leaf,
|
||||
MDB_val *data) {
|
||||
MDB_page *omp; /* overflow page */
|
||||
MDBX_page *omp; /* overflow page */
|
||||
pgno_t pgno;
|
||||
int rc;
|
||||
|
||||
@ -4919,7 +4891,7 @@ int mdbx_get(MDB_txn *txn, MDB_dbi dbi, MDB_val *key, MDB_val *data) {
|
||||
static int mdbx_cursor_sibling(MDB_cursor *mc, int move_right) {
|
||||
int rc;
|
||||
MDBX_node *indx;
|
||||
MDB_page *mp;
|
||||
MDBX_page *mp;
|
||||
|
||||
if (unlikely(mc->mc_snum < 2)) {
|
||||
return MDB_NOTFOUND; /* root has no siblings */
|
||||
@ -4967,7 +4939,7 @@ static int mdbx_cursor_sibling(MDB_cursor *mc, int move_right) {
|
||||
/* Move the cursor to the next data item. */
|
||||
static int mdbx_cursor_next(MDB_cursor *mc, MDB_val *key, MDB_val *data,
|
||||
MDB_cursor_op op) {
|
||||
MDB_page *mp;
|
||||
MDBX_page *mp;
|
||||
MDBX_node *leaf;
|
||||
int rc;
|
||||
|
||||
@ -5002,8 +4974,8 @@ static int mdbx_cursor_next(MDB_cursor *mc, MDB_val *key, MDB_val *data,
|
||||
}
|
||||
}
|
||||
|
||||
mdbx_debug("cursor_next: top page is %" PRIaPGNO " in cursor %p",
|
||||
mdbx_dbg_pgno(mp), (void *)mc);
|
||||
mdbx_debug("cursor_next: top page is %" PRIaPGNO " in cursor %p", mp->mp_pgno,
|
||||
(void *)mc);
|
||||
if (mc->mc_flags & C_DEL) {
|
||||
mc->mc_flags ^= C_DEL;
|
||||
goto skip;
|
||||
@ -5024,7 +4996,7 @@ static int mdbx_cursor_next(MDB_cursor *mc, MDB_val *key, MDB_val *data,
|
||||
skip:
|
||||
mdbx_debug("==> cursor points to page %" PRIaPGNO
|
||||
" with %u keys, key index %u",
|
||||
mdbx_dbg_pgno(mp), NUMKEYS(mp), mc->mc_ki[mc->mc_top]);
|
||||
mp->mp_pgno, NUMKEYS(mp), mc->mc_ki[mc->mc_top]);
|
||||
|
||||
if (IS_LEAF2(mp)) {
|
||||
key->mv_size = mc->mc_db->md_xsize;
|
||||
@ -5056,7 +5028,7 @@ skip:
|
||||
/* Move the cursor to the previous data item. */
|
||||
static int mdbx_cursor_prev(MDB_cursor *mc, MDB_val *key, MDB_val *data,
|
||||
MDB_cursor_op op) {
|
||||
MDB_page *mp;
|
||||
MDBX_page *mp;
|
||||
MDBX_node *leaf;
|
||||
int rc;
|
||||
|
||||
@ -5092,8 +5064,8 @@ static int mdbx_cursor_prev(MDB_cursor *mc, MDB_val *key, MDB_val *data,
|
||||
}
|
||||
}
|
||||
|
||||
mdbx_debug("cursor_prev: top page is %" PRIaPGNO " in cursor %p",
|
||||
mdbx_dbg_pgno(mp), (void *)mc);
|
||||
mdbx_debug("cursor_prev: top page is %" PRIaPGNO " in cursor %p", mp->mp_pgno,
|
||||
(void *)mc);
|
||||
|
||||
mc->mc_flags &= ~(C_EOF | C_DEL);
|
||||
|
||||
@ -5111,7 +5083,7 @@ static int mdbx_cursor_prev(MDB_cursor *mc, MDB_val *key, MDB_val *data,
|
||||
|
||||
mdbx_debug("==> cursor points to page %" PRIaPGNO
|
||||
" with %u keys, key index %u",
|
||||
mdbx_dbg_pgno(mp), NUMKEYS(mp), mc->mc_ki[mc->mc_top]);
|
||||
mp->mp_pgno, NUMKEYS(mp), mc->mc_ki[mc->mc_top]);
|
||||
|
||||
if (IS_LEAF2(mp)) {
|
||||
key->mv_size = mc->mc_db->md_xsize;
|
||||
@ -5144,7 +5116,7 @@ static int mdbx_cursor_prev(MDB_cursor *mc, MDB_val *key, MDB_val *data,
|
||||
static int mdbx_cursor_set(MDB_cursor *mc, MDB_val *key, MDB_val *data,
|
||||
MDB_cursor_op op, int *exactp) {
|
||||
int rc;
|
||||
MDB_page *mp;
|
||||
MDBX_page *mp;
|
||||
MDBX_node *leaf = NULL;
|
||||
DKBUF;
|
||||
|
||||
@ -5438,7 +5410,7 @@ int mdbx_cursor_get(MDB_cursor *mc, MDB_val *key, MDB_val *data,
|
||||
case MDB_GET_CURRENT: {
|
||||
if (unlikely(!(mc->mc_flags & C_INITIALIZED)))
|
||||
return MDBX_EINVAL;
|
||||
MDB_page *mp = mc->mc_pg[mc->mc_top];
|
||||
MDBX_page *mp = mc->mc_pg[mc->mc_top];
|
||||
unsigned nkeys = NUMKEYS(mp);
|
||||
if (mc->mc_ki[mc->mc_top] >= nkeys) {
|
||||
mc->mc_ki[mc->mc_top] = nkeys;
|
||||
@ -5616,7 +5588,7 @@ static int mdbx_cursor_touch(MDB_cursor *mc) {
|
||||
int mdbx_cursor_put(MDB_cursor *mc, MDB_val *key, MDB_val *data,
|
||||
unsigned flags) {
|
||||
MDB_env *env;
|
||||
MDB_page *fp, *sub_root = NULL;
|
||||
MDBX_page *fp, *sub_root = NULL;
|
||||
uint16_t fp_flags;
|
||||
MDB_val xdata, *rdata, dkey, olddata;
|
||||
MDB_db dummy;
|
||||
@ -5765,7 +5737,7 @@ int mdbx_cursor_put(MDB_cursor *mc, MDB_val *key, MDB_val *data,
|
||||
}
|
||||
|
||||
if (rc == MDB_NO_ROOT) {
|
||||
MDB_page *np;
|
||||
MDBX_page *np;
|
||||
/* new database, write a root leaf page */
|
||||
mdbx_debug("allocating new root leaf page");
|
||||
if (unlikely(rc2 = mdbx_page_new(mc, P_LEAF, 1, &np))) {
|
||||
@ -5844,7 +5816,7 @@ int mdbx_cursor_put(MDB_cursor *mc, MDB_val *key, MDB_val *data,
|
||||
* mp: new (sub-)page. offset: growth in page size.
|
||||
* xdata: node data with new page or DB. */
|
||||
unsigned i, offset = 0;
|
||||
MDB_page *mp = fp = xdata.mv_data = env->me_pbuf;
|
||||
MDBX_page *mp = fp = xdata.mv_data = env->me_pbuf;
|
||||
mp->mp_pgno = mc->mc_pg[mc->mc_top]->mp_pgno;
|
||||
|
||||
/* Was a single item before, must convert now */
|
||||
@ -5903,7 +5875,7 @@ int mdbx_cursor_put(MDB_cursor *mc, MDB_val *key, MDB_val *data,
|
||||
case MDB_CURRENT | MDB_NODUPDATA:
|
||||
case MDB_CURRENT:
|
||||
fp->mp_flags |= P_DIRTY;
|
||||
COPY_PGNO(fp->mp_pgno, mp->mp_pgno);
|
||||
fp->mp_pgno = mp->mp_pgno;
|
||||
mc->mc_xcursor->mx_cursor.mc_pg[0] = fp;
|
||||
flags |= F_DUPDATA;
|
||||
goto put_sub;
|
||||
@ -5968,7 +5940,7 @@ int mdbx_cursor_put(MDB_cursor *mc, MDB_val *key, MDB_val *data,
|
||||
return MDB_INCOMPATIBLE;
|
||||
/* overflow page overwrites need special handling */
|
||||
if (F_ISSET(leaf->mn_flags, F_BIGDATA)) {
|
||||
MDB_page *omp;
|
||||
MDBX_page *omp;
|
||||
pgno_t pg;
|
||||
int level, ovpages, dpages = OVPAGES(data->mv_size, env->me_psize);
|
||||
|
||||
@ -5993,7 +5965,7 @@ int mdbx_cursor_put(MDB_cursor *mc, MDB_val *key, MDB_val *data,
|
||||
* is smaller than the overflow threshold. */
|
||||
if (unlikely(level > 1)) {
|
||||
/* It is writable only in a parent txn */
|
||||
MDB_page *np = mdbx_page_malloc(mc->mc_txn, ovpages);
|
||||
MDBX_page *np = mdbx_page_malloc(mc->mc_txn, ovpages);
|
||||
MDB_ID2 id2;
|
||||
if (unlikely(!np))
|
||||
return MDBX_ENOMEM;
|
||||
@ -6073,7 +6045,7 @@ new_sub:
|
||||
MDB_cursor *m2, *m3;
|
||||
MDB_dbi dbi = mc->mc_dbi;
|
||||
unsigned i = mc->mc_top;
|
||||
MDB_page *mp = mc->mc_pg[i];
|
||||
MDBX_page *mp = mc->mc_pg[i];
|
||||
|
||||
for (m2 = mc->mc_txn->mt_cursors[dbi]; m2; m2 = m2->mc_next) {
|
||||
if (mc->mc_flags & C_SUB)
|
||||
@ -6127,7 +6099,7 @@ new_sub:
|
||||
MDB_cursor *m2;
|
||||
MDB_xcursor *mx = mc->mc_xcursor;
|
||||
unsigned i = mc->mc_top;
|
||||
MDB_page *mp = mc->mc_pg[i];
|
||||
MDBX_page *mp = mc->mc_pg[i];
|
||||
int nkeys = NUMKEYS(mp);
|
||||
|
||||
for (m2 = mc->mc_txn->mt_cursors[mc->mc_dbi]; m2; m2 = m2->mc_next) {
|
||||
@ -6189,7 +6161,7 @@ new_sub:
|
||||
|
||||
int mdbx_cursor_del(MDB_cursor *mc, unsigned flags) {
|
||||
MDBX_node *leaf;
|
||||
MDB_page *mp;
|
||||
MDBX_page *mp;
|
||||
int rc;
|
||||
|
||||
if (unlikely(!mc))
|
||||
@ -6284,7 +6256,7 @@ int mdbx_cursor_del(MDB_cursor *mc, unsigned flags) {
|
||||
|
||||
/* add overflow pages to free list */
|
||||
if (F_ISSET(leaf->mn_flags, F_BIGDATA)) {
|
||||
MDB_page *omp;
|
||||
MDBX_page *omp;
|
||||
pgno_t pg;
|
||||
|
||||
memcpy(&pg, NODEDATA(leaf), sizeof(pg));
|
||||
@ -6312,8 +6284,8 @@ fail:
|
||||
*
|
||||
* Returns 0 on success, non-zero on failure. */
|
||||
static int mdbx_page_new(MDB_cursor *mc, uint32_t flags, int num,
|
||||
MDB_page **mp) {
|
||||
MDB_page *np;
|
||||
MDBX_page **mp) {
|
||||
MDBX_page *np;
|
||||
int rc;
|
||||
|
||||
if (unlikely((rc = mdbx_page_alloc(mc, num, &np, MDBX_ALLOC_ALL))))
|
||||
@ -6413,8 +6385,8 @@ static int mdbx_node_add(MDB_cursor *mc, indx_t indx, MDB_val *key,
|
||||
ssize_t room;
|
||||
unsigned ofs;
|
||||
MDBX_node *node;
|
||||
MDB_page *mp = mc->mc_pg[mc->mc_top];
|
||||
MDB_page *ofp = NULL; /* overflow page */
|
||||
MDBX_page *mp = mc->mc_pg[mc->mc_top];
|
||||
MDBX_page *ofp = NULL; /* overflow page */
|
||||
void *ndata;
|
||||
DKBUF;
|
||||
|
||||
@ -6423,7 +6395,7 @@ static int mdbx_node_add(MDB_cursor *mc, indx_t indx, MDB_val *key,
|
||||
mdbx_debug("add to %s %spage %" PRIaPGNO " index %i, data size %" PRIuPTR
|
||||
" key size %" PRIuPTR " [%s]",
|
||||
IS_LEAF(mp) ? "leaf" : "branch", IS_SUBP(mp) ? "sub-" : "",
|
||||
mdbx_dbg_pgno(mp), indx, data ? data->mv_size : 0,
|
||||
mp->mp_pgno, indx, data ? data->mv_size : 0,
|
||||
key ? key->mv_size : 0, DKEY(key));
|
||||
|
||||
if (IS_LEAF2(mp)) {
|
||||
@ -6521,8 +6493,8 @@ update:
|
||||
return MDB_SUCCESS;
|
||||
|
||||
full:
|
||||
mdbx_debug("not enough room in page %" PRIaPGNO ", got %u ptrs",
|
||||
mdbx_dbg_pgno(mp), NUMKEYS(mp));
|
||||
mdbx_debug("not enough room in page %" PRIaPGNO ", got %u ptrs", mp->mp_pgno,
|
||||
NUMKEYS(mp));
|
||||
mdbx_debug("upper-lower = %u - %u = %" PRIiPTR "", mp->mp_upper, mp->mp_lower,
|
||||
room);
|
||||
mdbx_debug("node size = %" PRIuPTR "", node_size);
|
||||
@ -6535,7 +6507,7 @@ full:
|
||||
* [in] ksize The size of a node. Only used if the page is
|
||||
* part of a MDB_DUPFIXED database. */
|
||||
static void mdbx_node_del(MDB_cursor *mc, int ksize) {
|
||||
MDB_page *mp = mc->mc_pg[mc->mc_top];
|
||||
MDBX_page *mp = mc->mc_pg[mc->mc_top];
|
||||
indx_t indx = mc->mc_ki[mc->mc_top];
|
||||
unsigned sz;
|
||||
indx_t i, j, numkeys, ptr;
|
||||
@ -6543,7 +6515,7 @@ static void mdbx_node_del(MDB_cursor *mc, int ksize) {
|
||||
char *base;
|
||||
|
||||
mdbx_debug("delete node %u on %s page %" PRIaPGNO "", indx,
|
||||
IS_LEAF(mp) ? "leaf" : "branch", mdbx_dbg_pgno(mp));
|
||||
IS_LEAF(mp) ? "leaf" : "branch", mp->mp_pgno);
|
||||
numkeys = NUMKEYS(mp);
|
||||
mdbx_cassert(mc, indx < numkeys);
|
||||
|
||||
@ -6587,15 +6559,15 @@ static void mdbx_node_del(MDB_cursor *mc, int ksize) {
|
||||
/* Compact the main page after deleting a node on a subpage.
|
||||
* [in] mp The main page to operate on.
|
||||
* [in] indx The index of the subpage on the main page. */
|
||||
static void mdbx_node_shrink(MDB_page *mp, indx_t indx) {
|
||||
static void mdbx_node_shrink(MDBX_page *mp, indx_t indx) {
|
||||
MDBX_node *node;
|
||||
MDB_page *sp, *xp;
|
||||
MDBX_page *sp, *xp;
|
||||
char *base;
|
||||
unsigned nsize, delta, len, ptr;
|
||||
int i;
|
||||
|
||||
node = NODEPTR(mp, indx);
|
||||
sp = (MDB_page *)NODEDATA(node);
|
||||
sp = (MDBX_page *)NODEDATA(node);
|
||||
delta = SIZELEFT(sp);
|
||||
nsize = NODEDSZ(node) - delta;
|
||||
|
||||
@ -6605,13 +6577,13 @@ static void mdbx_node_shrink(MDB_page *mp, indx_t indx) {
|
||||
if (nsize & 1)
|
||||
return; /* do not make the node uneven-sized */
|
||||
} else {
|
||||
xp = (MDB_page *)((char *)sp + delta); /* destination subpage */
|
||||
xp = (MDBX_page *)((char *)sp + delta); /* destination subpage */
|
||||
for (i = NUMKEYS(sp); --i >= 0;)
|
||||
xp->mp_ptrs[i] = sp->mp_ptrs[i] - delta;
|
||||
len = PAGEHDRSZ;
|
||||
}
|
||||
sp->mp_upper = sp->mp_lower;
|
||||
COPY_PGNO(sp->mp_pgno, mp->mp_pgno);
|
||||
sp->mp_pgno = mp->mp_pgno;
|
||||
SETDSZ(node, nsize);
|
||||
|
||||
/* Shift <lower nodes...initial part of subpage> upward */
|
||||
@ -6669,7 +6641,7 @@ static void mdbx_xcursor_init1(MDB_cursor *mc, MDBX_node *node) {
|
||||
mx->mx_cursor.mc_top = 0;
|
||||
mx->mx_cursor.mc_flags = C_SUB;
|
||||
} else {
|
||||
MDB_page *fp = NODEDATA(node);
|
||||
MDBX_page *fp = NODEDATA(node);
|
||||
mx->mx_db.md_xsize = 0;
|
||||
mx->mx_db.md_flags = 0;
|
||||
mx->mx_db.md_depth = 1;
|
||||
@ -6677,7 +6649,7 @@ static void mdbx_xcursor_init1(MDB_cursor *mc, MDBX_node *node) {
|
||||
mx->mx_db.md_leaf_pages = 1;
|
||||
mx->mx_db.md_overflow_pages = 0;
|
||||
mx->mx_db.md_entries = NUMKEYS(fp);
|
||||
COPY_PGNO(mx->mx_db.md_root, fp->mp_pgno);
|
||||
mx->mx_db.md_root = fp->mp_pgno;
|
||||
mx->mx_cursor.mc_snum = 1;
|
||||
mx->mx_cursor.mc_top = 0;
|
||||
mx->mx_cursor.mc_flags = C_INITIALIZED | C_SUB;
|
||||
@ -6845,7 +6817,7 @@ int mdbx_cursor_count(MDB_cursor *mc, uint64_t *countp) {
|
||||
return MDB_NOTFOUND;
|
||||
}
|
||||
|
||||
MDB_page *mp = mc->mc_pg[mc->mc_top];
|
||||
MDBX_page *mp = mc->mc_pg[mc->mc_top];
|
||||
if ((mc->mc_flags & C_EOF) && mc->mc_ki[mc->mc_top] >= NUMKEYS(mp)) {
|
||||
*countp = 0;
|
||||
return MDB_NOTFOUND;
|
||||
@ -6906,7 +6878,7 @@ MDB_dbi mdbx_cursor_dbi(MDB_cursor *mc) {
|
||||
* [in] key The new key to use.
|
||||
* Returns 0 on success, non-zero on failure. */
|
||||
static int mdbx_update_key(MDB_cursor *mc, MDB_val *key) {
|
||||
MDB_page *mp;
|
||||
MDBX_page *mp;
|
||||
MDBX_node *node;
|
||||
char *base;
|
||||
size_t len;
|
||||
@ -7086,7 +7058,7 @@ static int mdbx_node_move(MDB_cursor *csrc, MDB_cursor *cdst, int fromleft) {
|
||||
/* Adjust other cursors pointing to mp */
|
||||
MDB_cursor *m2, *m3;
|
||||
MDB_dbi dbi = csrc->mc_dbi;
|
||||
MDB_page *mpd, *mps;
|
||||
MDBX_page *mpd, *mps;
|
||||
|
||||
mps = csrc->mc_pg[csrc->mc_top];
|
||||
/* If we're adding on the left, bump others up */
|
||||
@ -7214,7 +7186,7 @@ static int mdbx_node_move(MDB_cursor *csrc, MDB_cursor *cdst, int fromleft) {
|
||||
*
|
||||
* Returns 0 on success, non-zero on failure. */
|
||||
static int mdbx_page_merge(MDB_cursor *csrc, MDB_cursor *cdst) {
|
||||
MDB_page *psrc, *pdst;
|
||||
MDBX_page *psrc, *pdst;
|
||||
MDBX_node *srcnode;
|
||||
MDB_val key, data;
|
||||
unsigned nkeys;
|
||||
@ -7389,19 +7361,18 @@ static int mdbx_rebalance(MDB_cursor *mc) {
|
||||
}
|
||||
mdbx_debug("rebalancing %s page %" PRIaPGNO " (has %u keys, %.1f%% full)",
|
||||
IS_LEAF(mc->mc_pg[mc->mc_top]) ? "leaf" : "branch",
|
||||
mdbx_dbg_pgno(mc->mc_pg[mc->mc_top]),
|
||||
NUMKEYS(mc->mc_pg[mc->mc_top]),
|
||||
mc->mc_pg[mc->mc_top]->mp_pgno, NUMKEYS(mc->mc_pg[mc->mc_top]),
|
||||
(float)PAGEFILL(mc->mc_txn->mt_env, mc->mc_pg[mc->mc_top]) / 10);
|
||||
|
||||
if (PAGEFILL(mc->mc_txn->mt_env, mc->mc_pg[mc->mc_top]) >= thresh &&
|
||||
NUMKEYS(mc->mc_pg[mc->mc_top]) >= minkeys) {
|
||||
mdbx_debug("no need to rebalance page %" PRIaPGNO ", above fill threshold",
|
||||
mdbx_dbg_pgno(mc->mc_pg[mc->mc_top]));
|
||||
mc->mc_pg[mc->mc_top]->mp_pgno);
|
||||
return MDB_SUCCESS;
|
||||
}
|
||||
|
||||
if (mc->mc_snum < 2) {
|
||||
MDB_page *mp = mc->mc_pg[0];
|
||||
MDBX_page *mp = mc->mc_pg[0];
|
||||
unsigned nkeys = NUMKEYS(mp);
|
||||
if (IS_SUBP(mp)) {
|
||||
mdbx_debug("Can't rebalance a subpage, ignoring");
|
||||
@ -7554,7 +7525,7 @@ static int mdbx_rebalance(MDB_cursor *mc) {
|
||||
/* Complete a delete operation started by mdbx_cursor_del(). */
|
||||
static int mdbx_cursor_del0(MDB_cursor *mc) {
|
||||
int rc;
|
||||
MDB_page *mp;
|
||||
MDBX_page *mp;
|
||||
indx_t ki;
|
||||
unsigned nkeys;
|
||||
MDB_cursor *m2, *m3;
|
||||
@ -7721,8 +7692,8 @@ static int mdbx_page_split(MDB_cursor *mc, MDB_val *newkey, MDB_val *newdata,
|
||||
MDB_env *env = mc->mc_txn->mt_env;
|
||||
MDBX_node *node;
|
||||
MDB_val sepkey, rkey, xdata, *rdata = &xdata;
|
||||
MDB_page *copy = NULL;
|
||||
MDB_page *mp, *rp, *pp;
|
||||
MDBX_page *copy = NULL;
|
||||
MDBX_page *mp, *rp, *pp;
|
||||
int ptop;
|
||||
MDB_cursor mn;
|
||||
DKBUF;
|
||||
@ -8259,7 +8230,7 @@ static int __cold mdbx_env_cthr_toggle(mdbx_copy *my, int adjust) {
|
||||
static int __cold mdbx_env_cwalk(mdbx_copy *my, pgno_t *pg, int flags) {
|
||||
MDB_cursor mc;
|
||||
MDBX_node *ni;
|
||||
MDB_page *mo, *mp, *leaf;
|
||||
MDBX_page *mo, *mp, *leaf;
|
||||
char *buf, *ptr;
|
||||
int rc, toggle;
|
||||
unsigned i;
|
||||
@ -8285,13 +8256,13 @@ static int __cold mdbx_env_cwalk(mdbx_copy *my, pgno_t *pg, int flags) {
|
||||
return MDBX_ENOMEM;
|
||||
|
||||
for (i = 0; i < mc.mc_top; i++) {
|
||||
mdbx_page_copy((MDB_page *)ptr, mc.mc_pg[i], my->mc_env->me_psize);
|
||||
mc.mc_pg[i] = (MDB_page *)ptr;
|
||||
mdbx_page_copy((MDBX_page *)ptr, mc.mc_pg[i], my->mc_env->me_psize);
|
||||
mc.mc_pg[i] = (MDBX_page *)ptr;
|
||||
ptr += my->mc_env->me_psize;
|
||||
}
|
||||
|
||||
/* This is writable space for a leaf page. Usually not needed. */
|
||||
leaf = (MDB_page *)ptr;
|
||||
leaf = (MDBX_page *)ptr;
|
||||
|
||||
toggle = my->mc_toggle;
|
||||
while (mc.mc_snum > 0) {
|
||||
@ -8304,7 +8275,7 @@ static int __cold mdbx_env_cwalk(mdbx_copy *my, pgno_t *pg, int flags) {
|
||||
for (i = 0; i < n; i++) {
|
||||
ni = NODEPTR(mp, i);
|
||||
if (ni->mn_flags & F_BIGDATA) {
|
||||
MDB_page *omp;
|
||||
MDBX_page *omp;
|
||||
|
||||
/* Need writable leaf */
|
||||
if (mp != leaf) {
|
||||
@ -8326,7 +8297,7 @@ static int __cold mdbx_env_cwalk(mdbx_copy *my, pgno_t *pg, int flags) {
|
||||
goto done;
|
||||
toggle = my->mc_toggle;
|
||||
}
|
||||
mo = (MDB_page *)(my->mc_wbuf[toggle] + my->mc_wlen[toggle]);
|
||||
mo = (MDBX_page *)(my->mc_wbuf[toggle] + my->mc_wlen[toggle]);
|
||||
memcpy(mo, omp, my->mc_env->me_psize);
|
||||
mo->mp_pgno = my->mc_next_pgno;
|
||||
my->mc_next_pgno += omp->mp_pages;
|
||||
@ -8389,7 +8360,7 @@ static int __cold mdbx_env_cwalk(mdbx_copy *my, pgno_t *pg, int flags) {
|
||||
goto done;
|
||||
toggle = my->mc_toggle;
|
||||
}
|
||||
mo = (MDB_page *)(my->mc_wbuf[toggle] + my->mc_wlen[toggle]);
|
||||
mo = (MDBX_page *)(my->mc_wbuf[toggle] + my->mc_wlen[toggle]);
|
||||
mdbx_page_copy(mo, mp, my->mc_env->me_psize);
|
||||
mo->mp_pgno = my->mc_next_pgno++;
|
||||
my->mc_wlen[toggle] += my->mc_env->me_psize;
|
||||
@ -8412,7 +8383,7 @@ done:
|
||||
/* Copy environment with compaction. */
|
||||
static int __cold mdbx_env_compact(MDB_env *env, mdbx_filehandle_t fd) {
|
||||
MDB_meta *mm;
|
||||
MDB_page *mp;
|
||||
MDBX_page *mp;
|
||||
mdbx_copy my;
|
||||
MDB_txn *txn = NULL;
|
||||
mdbx_thread_t thr;
|
||||
@ -8440,14 +8411,14 @@ static int __cold mdbx_env_compact(MDB_env *env, mdbx_filehandle_t fd) {
|
||||
if (rc)
|
||||
goto finish;
|
||||
|
||||
mp = (MDB_page *)my.mc_wbuf[0];
|
||||
mp = (MDBX_page *)my.mc_wbuf[0];
|
||||
memset(mp, 0, NUM_METAS * env->me_psize);
|
||||
mp->mp_pgno = 0;
|
||||
mp->mp_flags = P_META;
|
||||
mm = (MDB_meta *)PAGEDATA(mp);
|
||||
mdbx_meta_model(env, mm);
|
||||
|
||||
mp = (MDB_page *)(my.mc_wbuf[0] + env->me_psize);
|
||||
mp = (MDBX_page *)(my.mc_wbuf[0] + env->me_psize);
|
||||
mp->mp_pgno = 1;
|
||||
mp->mp_flags = P_META;
|
||||
*(MDB_meta *)PAGEDATA(mp) = *mm;
|
||||
@ -8999,13 +8970,13 @@ static int mdbx_drop0(MDB_cursor *mc, int subs) {
|
||||
|
||||
mdbx_cursor_copy(mc, &mx);
|
||||
while (mc->mc_snum > 0) {
|
||||
MDB_page *mp = mc->mc_pg[mc->mc_top];
|
||||
MDBX_page *mp = mc->mc_pg[mc->mc_top];
|
||||
unsigned n = NUMKEYS(mp);
|
||||
if (IS_LEAF(mp)) {
|
||||
for (i = 0; i < n; i++) {
|
||||
ni = NODEPTR(mp, i);
|
||||
if (ni->mn_flags & F_BIGDATA) {
|
||||
MDB_page *omp;
|
||||
MDBX_page *omp;
|
||||
pgno_t pg;
|
||||
memcpy(&pg, NODEDATA(ni), sizeof(pg));
|
||||
rc = mdbx_page_get(mc, pg, &omp, NULL);
|
||||
@ -9710,7 +9681,7 @@ typedef struct mdbx_walk_ctx {
|
||||
/* Depth-first tree traversal. */
|
||||
static int __cold mdbx_env_walk(mdbx_walk_ctx_t *ctx, const char *dbi,
|
||||
pgno_t pg, int deep) {
|
||||
MDB_page *mp;
|
||||
MDBX_page *mp;
|
||||
int rc, i, nkeys;
|
||||
unsigned header_size, unused_size, payload_size, align_bytes;
|
||||
const char *type;
|
||||
@ -9726,7 +9697,7 @@ static int __cold mdbx_env_walk(mdbx_walk_ctx_t *ctx, const char *dbi,
|
||||
rc = mdbx_page_get(&mc, pg, &mp, NULL);
|
||||
if (rc)
|
||||
return rc;
|
||||
if (pg != mp->mp_p.p_pgno)
|
||||
if (pg != mp->mp_pgno)
|
||||
return MDB_CORRUPTED;
|
||||
|
||||
nkeys = NUMKEYS(mp);
|
||||
@ -9783,7 +9754,7 @@ static int __cold mdbx_env_walk(mdbx_walk_ctx_t *ctx, const char *dbi,
|
||||
|
||||
assert(IS_LEAF(mp));
|
||||
if (node->mn_flags & F_BIGDATA) {
|
||||
MDB_page *omp;
|
||||
MDBX_page *omp;
|
||||
pgno_t *opg;
|
||||
size_t over_header, over_payload, over_unused;
|
||||
|
||||
@ -9792,7 +9763,7 @@ static int __cold mdbx_env_walk(mdbx_walk_ctx_t *ctx, const char *dbi,
|
||||
rc = mdbx_page_get(&mc, *opg, &omp, NULL);
|
||||
if (rc)
|
||||
return rc;
|
||||
if (*opg != omp->mp_p.p_pgno)
|
||||
if (*opg != omp->mp_pgno)
|
||||
return MDB_CORRUPTED;
|
||||
/* LY: Don't use mask here, e.g bitwise
|
||||
* (P_BRANCH|P_LEAF|P_LEAF2|P_META|P_OVERFLOW|P_SUBP).
|
||||
@ -9831,7 +9802,7 @@ static int __cold mdbx_env_walk(mdbx_walk_ctx_t *ctx, const char *dbi,
|
||||
}
|
||||
}
|
||||
|
||||
return ctx->mw_visitor(mp->mp_p.p_pgno, 1, ctx->mw_user, dbi, type, nkeys,
|
||||
return ctx->mw_visitor(mp->mp_pgno, 1, ctx->mw_user, dbi, type, nkeys,
|
||||
payload_size, header_size, unused_size + align_bytes);
|
||||
}
|
||||
|
||||
@ -10055,7 +10026,7 @@ int mdbx_replace(MDB_txn *txn, MDB_dbi dbi, MDB_val *key, MDB_val *new_data,
|
||||
*old_data = present_data;
|
||||
goto bailout;
|
||||
} else {
|
||||
MDB_page *page = mc.mc_pg[mc.mc_top];
|
||||
MDBX_page *page = mc.mc_pg[mc.mc_top];
|
||||
if (txn->mt_dbs[dbi].md_flags & MDB_DUPSORT) {
|
||||
if (flags & MDB_CURRENT) {
|
||||
/* для не-уникальных ключей позволяем update/delete только если ключ
|
||||
@ -10195,7 +10166,7 @@ int mdbx_is_dirty(const MDB_txn *txn, const void *ptr) {
|
||||
|
||||
const MDB_env *env = txn->mt_env;
|
||||
const uintptr_t mask = ~(uintptr_t)(env->me_psize - 1);
|
||||
const MDB_page *page = (const MDB_page *)((uintptr_t)ptr & mask);
|
||||
const MDBX_page *page = (const MDBX_page *)((uintptr_t)ptr & mask);
|
||||
|
||||
/* LY: Тут не всё хорошо с абсолютной достоверностью результата,
|
||||
* так как флажок P_DIRTY в LMDB может означать не совсем то,
|
||||
|
Loading…
x
Reference in New Issue
Block a user