From e381191c0fc3c6587b2379e26daeebb7b36792e9 Mon Sep 17 00:00:00 2001 From: Leo Yuriev Date: Sun, 27 Nov 2016 12:56:27 +0300 Subject: [PATCH 1/4] mdbx: fix typo. Change-Id: I46344bf13a71b04b32d84bf0e0bc0a34ae6ef162 --- mdb_chk.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/mdb_chk.c b/mdb_chk.c index 4fe83ff0..b86b8f96 100644 --- a/mdb_chk.c +++ b/mdb_chk.c @@ -52,7 +52,7 @@ flagbit dbflags[] = { static volatile sig_atomic_t gotsignal; -static void signal_hanlder( int sig ) { +static void signal_handler( int sig ) { (void) sig; gotsignal = 1; } @@ -660,13 +660,13 @@ int main(int argc, char *argv[]) usage(prog); #ifdef SIGPIPE - signal(SIGPIPE, signal_hanlder); + signal(SIGPIPE, signal_handler); #endif #ifdef SIGHUP - signal(SIGHUP, signal_hanlder); + signal(SIGHUP, signal_handler); #endif - signal(SIGINT, signal_hanlder); - signal(SIGTERM, signal_hanlder); + signal(SIGINT, signal_handler); + signal(SIGTERM, signal_handler); envname = argv[optind]; print("Running mdbx_chk for '%s' in %s mode...\n", From 533ad276bbf68b4c62f18a3325dc144ddd13cf4c Mon Sep 17 00:00:00 2001 From: Howard Chu Date: Tue, 29 Nov 2016 19:19:45 +0000 Subject: [PATCH 2/4] mdbx: backport - more for cursor tracking after deletion (ITS#8406). xcursor fixup depends on init state Change-Id: I13139c401e2ae6bbe3d7e6b9fda3739f9ec789cf --- mdb.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/mdb.c b/mdb.c index 408cebdb..6d713ba7 100644 --- a/mdb.c +++ b/mdb.c @@ -8451,6 +8451,11 @@ mdb_cursor_del0(MDB_cursor *mc) if (m3->mc_pg[mc->mc_top] == mp) { if (m3->mc_ki[mc->mc_top] == ki) { m3->mc_flags |= C_DEL; + if (mc->mc_db->md_flags & MDB_DUPSORT) { + /* Sub-cursor referred into dataset which is gone */ + m3->mc_xcursor->mx_cursor.mc_flags &= ~(C_INITIALIZED|C_EOF); + } + continue; } else if (m3->mc_ki[mc->mc_top] > ki) { m3->mc_ki[mc->mc_top]--; } @@ -8496,10 +8501,14 @@ mdb_cursor_del0(MDB_cursor *mc) if (mc->mc_db->md_flags & MDB_DUPSORT) { MDB_node *node = NODEPTR(m3->mc_pg[m3->mc_top], m3->mc_ki[m3->mc_top]); /* If this node is a fake page, it needs to be reinited - * because its data has moved. + * because its data has moved. But just reset mc_pg[0] + * if the xcursor is already live. */ if ((node->mn_flags & (F_DUPDATA|F_SUBDATA)) == F_DUPDATA) { - mdb_xcursor_init1(m3, node); + if (m3->mc_xcursor->mx_cursor.mc_flags & C_INITIALIZED) + m3->mc_xcursor->mx_cursor.mc_pg[0] = NODEDATA(node); + else + mdb_xcursor_init1(m3, node); } } } From 2196a9b72c741fc922db1e5933df23f9b0e978ad Mon Sep 17 00:00:00 2001 From: Hallvard Furuseth Date: Thu, 1 Dec 2016 21:17:42 +0100 Subject: [PATCH 3/4] mdbx: backport - factor out refreshing sub-page pointers. Change-Id: If2d3efde19ff751da208959f6f2834ece1f64e56 --- mdb.c | 88 ++++++++++++++++++++++++----------------------------------- 1 file changed, 36 insertions(+), 52 deletions(-) diff --git a/mdb.c b/mdb.c index 6d713ba7..302a4256 100644 --- a/mdb.c +++ b/mdb.c @@ -973,6 +973,21 @@ typedef struct MDB_xcursor { unsigned char mx_dbflag; } MDB_xcursor; + /** Check if there is an inited xcursor, so #XCURSOR_REFRESH() is proper */ +#define XCURSOR_INITED(mc) \ + ((mc)->mc_xcursor && ((mc)->mc_xcursor->mx_cursor.mc_flags & C_INITIALIZED)) + + /** Update sub-page pointer, if any, in \b mc->mc_xcursor. Needed + * when the node which contains the sub-page may have moved. Called + * with \b mp = mc->mc_pg[mc->mc_top], \b ki = mc->mc_ki[mc->mc_top]. + */ +#define XCURSOR_REFRESH(mc, mp, ki) do { \ + MDB_page *xr_pg = (mp); \ + MDB_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); \ +} while (0) + /** State of FreeDB old pages, stored in the MDB_env */ typedef struct MDB_pgstate { pgno_t *mf_pghead; /**< Reclaimed freeDB pages, or NULL before use */ @@ -1445,7 +1460,7 @@ mdb_cursor_chk(MDB_cursor *mc) } if (unlikely(mc->mc_ki[i] >= NUMKEYS(mc->mc_pg[i]))) mdb_print("ack!\n"); - if (mc->mc_xcursor && (mc->mc_xcursor->mx_cursor.mc_flags & C_INITIALIZED)) { + if (XCURSOR_INITED(mc)) { node = NODEPTR(mc->mc_pg[mc->mc_top], mc->mc_ki[mc->mc_top]); if (((node->mn_flags & (F_DUPDATA|F_SUBDATA)) == F_DUPDATA) && mc->mc_xcursor->mx_cursor.mc_pg[0] != NODEDATA(node)) { @@ -2544,14 +2559,8 @@ done: if (m2 == mc) continue; if (m2->mc_pg[mc->mc_top] == mp) { m2->mc_pg[mc->mc_top] = np; - if ((mc->mc_db->md_flags & MDB_DUPSORT) && - IS_LEAF(np) && - (m2->mc_xcursor->mx_cursor.mc_flags & C_INITIALIZED)) - { - MDB_node *leaf = NODEPTR(np, m2->mc_ki[mc->mc_top]); - if ((leaf->mn_flags & (F_DUPDATA|F_SUBDATA)) == F_DUPDATA) - m2->mc_xcursor->mx_cursor.mc_pg[0] = NODEDATA(leaf); - } + if (XCURSOR_INITED(m2) && IS_LEAF(np)) + XCURSOR_REFRESH(m2, np, m2->mc_ki[mc->mc_top]); } } } @@ -6926,11 +6935,8 @@ new_sub: if (m3->mc_ki[i] >= mc->mc_ki[i] && insert_key) { m3->mc_ki[i]++; } - if (m3->mc_xcursor && (m3->mc_xcursor->mx_cursor.mc_flags & C_INITIALIZED)) { - MDB_node *n2 = NODEPTR(mp, m3->mc_ki[i]); - if ((n2->mn_flags & (F_SUBDATA|F_DUPDATA)) == F_DUPDATA) - m3->mc_xcursor->mx_cursor.mc_pg[0] = NODEDATA(n2); - } + if (XCURSOR_INITED(m3)) + XCURSOR_REFRESH(m3, mp, m3->mc_ki[i]); } } } @@ -6981,9 +6987,7 @@ put_sub: if (m2->mc_ki[i] == mc->mc_ki[i]) { mdb_xcursor_init2(m2, mx, new_dupdata); } else if (!insert_key && m2->mc_ki[i] < nkeys) { - MDB_node *n2 = NODEPTR(mp, m2->mc_ki[i]); - if ((n2->mn_flags & (F_SUBDATA|F_DUPDATA)) == F_DUPDATA) - m2->mc_xcursor->mx_cursor.mc_pg[0] = NODEDATA(n2); + XCURSOR_REFRESH(m2, mp, m2->mc_ki[i]); } } } @@ -7094,13 +7098,12 @@ mdb_cursor_del(MDB_cursor *mc, unsigned flags) if (m2 == mc || m2->mc_snum < mc->mc_snum) continue; if (!(m2->mc_flags & C_INITIALIZED)) continue; if (m2->mc_pg[mc->mc_top] == mp) { - if (m2->mc_ki[mc->mc_top] == mc->mc_ki[mc->mc_top]) { - m2->mc_xcursor->mx_cursor.mc_pg[0] = NODEDATA(leaf); - } else { - MDB_node *n2 = NODEPTR(mp, m2->mc_ki[mc->mc_top]); - if (!(n2->mn_flags & F_SUBDATA)) - m2->mc_xcursor->mx_cursor.mc_pg[0] = NODEDATA(n2); + MDB_node *n2 = leaf; + if (m2->mc_ki[mc->mc_top] != mc->mc_ki[mc->mc_top]) { + n2 = NODEPTR(mp, m2->mc_ki[mc->mc_top]); + if (n2->mn_flags & F_SUBDATA) continue; } + m2->mc_xcursor->mx_cursor.mc_pg[0] = NODEDATA(n2); } } } @@ -7962,12 +7965,8 @@ mdb_node_move(MDB_cursor *csrc, MDB_cursor *cdst, int fromleft) m3->mc_ki[csrc->mc_top] = cdst->mc_ki[cdst->mc_top]; m3->mc_ki[csrc->mc_top-1]++; } - if (m3->mc_xcursor && (m3->mc_xcursor->mx_cursor.mc_flags & C_INITIALIZED) && - IS_LEAF(mps)) { - MDB_node *node = NODEPTR(m3->mc_pg[csrc->mc_top], m3->mc_ki[csrc->mc_top]); - if ((node->mn_flags & (F_DUPDATA|F_SUBDATA)) == F_DUPDATA) - m3->mc_xcursor->mx_cursor.mc_pg[0] = NODEDATA(node); - } + if (XCURSOR_INITED(m3) && IS_LEAF(mps)) + XCURSOR_REFRESH(m3, m3->mc_pg[csrc->mc_top], m3->mc_ki[csrc->mc_top]); } } else /* Adding on the right, bump others down */ @@ -7988,12 +7987,8 @@ mdb_node_move(MDB_cursor *csrc, MDB_cursor *cdst, int fromleft) } else { m3->mc_ki[csrc->mc_top]--; } - if (m3->mc_xcursor && (m3->mc_xcursor->mx_cursor.mc_flags & C_INITIALIZED) && - IS_LEAF(mps)) { - MDB_node *node = NODEPTR(m3->mc_pg[csrc->mc_top], m3->mc_ki[csrc->mc_top]); - if ((node->mn_flags & (F_DUPDATA|F_SUBDATA)) == F_DUPDATA) - m3->mc_xcursor->mx_cursor.mc_pg[0] = NODEDATA(node); - } + if (XCURSOR_INITED(m3) && IS_LEAF(mps)) + XCURSOR_REFRESH(m3, m3->mc_pg[csrc->mc_top], m3->mc_ki[csrc->mc_top]); } } } @@ -8192,12 +8187,8 @@ mdb_page_merge(MDB_cursor *csrc, MDB_cursor *cdst) m3->mc_ki[top-1] > csrc->mc_ki[top-1]) { m3->mc_ki[top-1]--; } - if (m3->mc_xcursor && (m3->mc_xcursor->mx_cursor.mc_flags & C_INITIALIZED) && - IS_LEAF(psrc)) { - MDB_node *node = NODEPTR(m3->mc_pg[top], m3->mc_ki[top]); - if ((node->mn_flags & (F_DUPDATA|F_SUBDATA)) == F_DUPDATA) - m3->mc_xcursor->mx_cursor.mc_pg[0] = NODEDATA(node); - } + if (XCURSOR_INITED(m3) && IS_LEAF(psrc)) + XCURSOR_REFRESH(m3, m3->mc_pg[top], m3->mc_ki[top]); } } { @@ -8459,11 +8450,8 @@ mdb_cursor_del0(MDB_cursor *mc) } else if (m3->mc_ki[mc->mc_top] > ki) { m3->mc_ki[mc->mc_top]--; } - if (m3->mc_xcursor && (m3->mc_xcursor->mx_cursor.mc_flags & C_INITIALIZED)) { - MDB_node *node = NODEPTR(m3->mc_pg[mc->mc_top], m3->mc_ki[mc->mc_top]); - if ((node->mn_flags & (F_DUPDATA|F_SUBDATA)) == F_DUPDATA) - m3->mc_xcursor->mx_cursor.mc_pg[0] = NODEDATA(node); - } + if (XCURSOR_INITED(m3)) + XCURSOR_REFRESH(m3, m3->mc_pg[mc->mc_top], m3->mc_ki[mc->mc_top]); } } } @@ -8997,12 +8985,8 @@ mdb_page_split(MDB_cursor *mc, MDB_val *newkey, MDB_val *newdata, pgno_t newpgno m3->mc_ki[ptop] >= mc->mc_ki[ptop]) { m3->mc_ki[ptop]++; } - if (m3->mc_xcursor && (m3->mc_xcursor->mx_cursor.mc_flags & C_INITIALIZED) && - IS_LEAF(mp)) { - MDB_node *node = NODEPTR(m3->mc_pg[mc->mc_top], m3->mc_ki[mc->mc_top]); - if ((node->mn_flags & (F_DUPDATA|F_SUBDATA)) == F_DUPDATA) - m3->mc_xcursor->mx_cursor.mc_pg[0] = NODEDATA(node); - } + if (XCURSOR_INITED(m3) && IS_LEAF(mp)) + XCURSOR_REFRESH(m3, m3->mc_pg[mc->mc_top], m3->mc_ki[mc->mc_top]); } } mdb_debug("mp left: %d, rp left: %d", SIZELEFT(mp), SIZELEFT(rp)); From 2fb5a5426427bd49f5e227e3173edd23914cbbf5 Mon Sep 17 00:00:00 2001 From: Leo Yuriev Date: Sat, 3 Dec 2016 17:39:26 +0300 Subject: [PATCH 4/4] mdbx: minor simplify mc_signature. Change-Id: Ib3952853350d220dd62910bcd55ac74cf5f47886 --- mdb.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/mdb.c b/mdb.c index 302a4256..6a2782ff 100644 --- a/mdb.c +++ b/mdb.c @@ -7548,7 +7548,6 @@ mdb_xcursor_init1(MDB_cursor *mc, MDB_node *node) if (mx->mx_dbx.md_cmp == mdb_cmp_int && mx->mx_db.md_pad == sizeof(size_t)) mx->mx_dbx.md_cmp = mdb_cmp_clong; #endif */ - mc->mc_signature = MDBX_MC_SIGNATURE; } @@ -7587,6 +7586,7 @@ mdb_xcursor_init2(MDB_cursor *mc, MDB_xcursor *src_mx, int new_dupdata) static void mdb_cursor_init(MDB_cursor *mc, MDB_txn *txn, MDB_dbi dbi, MDB_xcursor *mx) { + mc->mc_signature = MDBX_MC_SIGNATURE; mc->mc_next = NULL; mc->mc_backup = NULL; mc->mc_dbi = dbi; @@ -7610,7 +7610,6 @@ mdb_cursor_init(MDB_cursor *mc, MDB_txn *txn, MDB_dbi dbi, MDB_xcursor *mx) if (*mc->mc_dbflag & DB_STALE) { mdb_page_search(mc, NULL, MDB_PS_ROOTONLY); } - mc->mc_signature = MDBX_MC_SIGNATURE; } int