|
|
@ -1188,6 +1188,21 @@ typedef struct MDB_xcursor { |
|
|
|
unsigned char mx_dbflag; |
|
|
|
unsigned char mx_dbflag; |
|
|
|
} MDB_xcursor; |
|
|
|
} 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 */ |
|
|
|
/** State of FreeDB old pages, stored in the MDB_env */ |
|
|
|
typedef struct MDB_pgstate { |
|
|
|
typedef struct MDB_pgstate { |
|
|
|
pgno_t *mf_pghead; /**< Reclaimed freeDB pages, or NULL before use */ |
|
|
|
pgno_t *mf_pghead; /**< Reclaimed freeDB pages, or NULL before use */ |
|
|
@ -1618,7 +1633,7 @@ mdb_cursor_chk(MDB_cursor *mc) |
|
|
|
} |
|
|
|
} |
|
|
|
if (mc->mc_ki[i] >= NUMKEYS(mc->mc_pg[i])) |
|
|
|
if (mc->mc_ki[i] >= NUMKEYS(mc->mc_pg[i])) |
|
|
|
printf("ack!\n"); |
|
|
|
printf("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]); |
|
|
|
node = NODEPTR(mc->mc_pg[mc->mc_top], mc->mc_ki[mc->mc_top]); |
|
|
|
if (((node->mn_flags & (F_DUPDATA|F_SUBDATA)) == F_DUPDATA) && |
|
|
|
if (((node->mn_flags & (F_DUPDATA|F_SUBDATA)) == F_DUPDATA) && |
|
|
|
mc->mc_xcursor->mx_cursor.mc_pg[0] != NODEDATA(node)) { |
|
|
|
mc->mc_xcursor->mx_cursor.mc_pg[0] != NODEDATA(node)) { |
|
|
@ -2433,14 +2448,8 @@ done: |
|
|
|
if (m2 == mc) continue; |
|
|
|
if (m2 == mc) continue; |
|
|
|
if (m2->mc_pg[mc->mc_top] == mp) { |
|
|
|
if (m2->mc_pg[mc->mc_top] == mp) { |
|
|
|
m2->mc_pg[mc->mc_top] = np; |
|
|
|
m2->mc_pg[mc->mc_top] = np; |
|
|
|
if ((mc->mc_db->md_flags & MDB_DUPSORT) && |
|
|
|
if (XCURSOR_INITED(m2) && IS_LEAF(np)) |
|
|
|
IS_LEAF(np) && |
|
|
|
XCURSOR_REFRESH(m2, np, m2->mc_ki[mc->mc_top]); |
|
|
|
(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); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
@ -6726,11 +6735,8 @@ new_sub: |
|
|
|
if (m3->mc_ki[i] >= mc->mc_ki[i] && insert_key) { |
|
|
|
if (m3->mc_ki[i] >= mc->mc_ki[i] && insert_key) { |
|
|
|
m3->mc_ki[i]++; |
|
|
|
m3->mc_ki[i]++; |
|
|
|
} |
|
|
|
} |
|
|
|
if (m3->mc_xcursor && (m3->mc_xcursor->mx_cursor.mc_flags & C_INITIALIZED)) { |
|
|
|
if (XCURSOR_INITED(m3)) |
|
|
|
MDB_node *n2 = NODEPTR(mp, m3->mc_ki[i]); |
|
|
|
XCURSOR_REFRESH(m3, 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); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
@ -6781,9 +6787,7 @@ put_sub: |
|
|
|
if (m2->mc_ki[i] == mc->mc_ki[i]) { |
|
|
|
if (m2->mc_ki[i] == mc->mc_ki[i]) { |
|
|
|
mdb_xcursor_init2(m2, mx, new_dupdata); |
|
|
|
mdb_xcursor_init2(m2, mx, new_dupdata); |
|
|
|
} else if (!insert_key && m2->mc_ki[i] < nkeys) { |
|
|
|
} else if (!insert_key && m2->mc_ki[i] < nkeys) { |
|
|
|
MDB_node *n2 = NODEPTR(mp, m2->mc_ki[i]); |
|
|
|
XCURSOR_REFRESH(m2, 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); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
@ -6888,13 +6892,12 @@ mdb_cursor_del(MDB_cursor *mc, unsigned int flags) |
|
|
|
if (m2 == mc || m2->mc_snum < mc->mc_snum) continue; |
|
|
|
if (m2 == mc || m2->mc_snum < mc->mc_snum) continue; |
|
|
|
if (!(m2->mc_flags & C_INITIALIZED)) continue; |
|
|
|
if (!(m2->mc_flags & C_INITIALIZED)) continue; |
|
|
|
if (m2->mc_pg[mc->mc_top] == mp) { |
|
|
|
if (m2->mc_pg[mc->mc_top] == mp) { |
|
|
|
if (m2->mc_ki[mc->mc_top] == mc->mc_ki[mc->mc_top]) { |
|
|
|
MDB_node *n2 = leaf; |
|
|
|
m2->mc_xcursor->mx_cursor.mc_pg[0] = NODEDATA(leaf); |
|
|
|
if (m2->mc_ki[mc->mc_top] != mc->mc_ki[mc->mc_top]) { |
|
|
|
} else { |
|
|
|
n2 = NODEPTR(mp, m2->mc_ki[mc->mc_top]); |
|
|
|
MDB_node *n2 = NODEPTR(mp, m2->mc_ki[mc->mc_top]); |
|
|
|
if (n2->mn_flags & F_SUBDATA) continue; |
|
|
|
if (!(n2->mn_flags & F_SUBDATA)) |
|
|
|
|
|
|
|
m2->mc_xcursor->mx_cursor.mc_pg[0] = NODEDATA(n2); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
m2->mc_xcursor->mx_cursor.mc_pg[0] = NODEDATA(n2); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
@ -7731,12 +7734,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] = cdst->mc_ki[cdst->mc_top]; |
|
|
|
m3->mc_ki[csrc->mc_top-1]++; |
|
|
|
m3->mc_ki[csrc->mc_top-1]++; |
|
|
|
} |
|
|
|
} |
|
|
|
if (m3->mc_xcursor && (m3->mc_xcursor->mx_cursor.mc_flags & C_INITIALIZED) && |
|
|
|
if (XCURSOR_INITED(m3) && IS_LEAF(mps)) |
|
|
|
IS_LEAF(mps)) { |
|
|
|
XCURSOR_REFRESH(m3, m3->mc_pg[csrc->mc_top], m3->mc_ki[csrc->mc_top]); |
|
|
|
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); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} else |
|
|
|
} else |
|
|
|
/* Adding on the right, bump others down */ |
|
|
|
/* Adding on the right, bump others down */ |
|
|
@ -7757,12 +7756,8 @@ mdb_node_move(MDB_cursor *csrc, MDB_cursor *cdst, int fromleft) |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
m3->mc_ki[csrc->mc_top]--; |
|
|
|
m3->mc_ki[csrc->mc_top]--; |
|
|
|
} |
|
|
|
} |
|
|
|
if (m3->mc_xcursor && (m3->mc_xcursor->mx_cursor.mc_flags & C_INITIALIZED) && |
|
|
|
if (XCURSOR_INITED(m3) && IS_LEAF(mps)) |
|
|
|
IS_LEAF(mps)) { |
|
|
|
XCURSOR_REFRESH(m3, m3->mc_pg[csrc->mc_top], m3->mc_ki[csrc->mc_top]); |
|
|
|
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); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
@ -7963,12 +7958,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] > csrc->mc_ki[top-1]) { |
|
|
|
m3->mc_ki[top-1]--; |
|
|
|
m3->mc_ki[top-1]--; |
|
|
|
} |
|
|
|
} |
|
|
|
if (m3->mc_xcursor && (m3->mc_xcursor->mx_cursor.mc_flags & C_INITIALIZED) && |
|
|
|
if (XCURSOR_INITED(m3) && IS_LEAF(psrc)) |
|
|
|
IS_LEAF(psrc)) { |
|
|
|
XCURSOR_REFRESH(m3, m3->mc_pg[top], m3->mc_ki[top]); |
|
|
|
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); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
{ |
|
|
|
{ |
|
|
@ -8230,11 +8221,8 @@ mdb_cursor_del0(MDB_cursor *mc) |
|
|
|
} else if (m3->mc_ki[mc->mc_top] > ki) { |
|
|
|
} else if (m3->mc_ki[mc->mc_top] > ki) { |
|
|
|
m3->mc_ki[mc->mc_top]--; |
|
|
|
m3->mc_ki[mc->mc_top]--; |
|
|
|
} |
|
|
|
} |
|
|
|
if (m3->mc_xcursor && (m3->mc_xcursor->mx_cursor.mc_flags & C_INITIALIZED)) { |
|
|
|
if (XCURSOR_INITED(m3)) |
|
|
|
MDB_node *node = NODEPTR(m3->mc_pg[mc->mc_top], m3->mc_ki[mc->mc_top]); |
|
|
|
XCURSOR_REFRESH(m3, 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); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
@ -8764,12 +8752,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] >= mc->mc_ki[ptop]) { |
|
|
|
m3->mc_ki[ptop]++; |
|
|
|
m3->mc_ki[ptop]++; |
|
|
|
} |
|
|
|
} |
|
|
|
if (m3->mc_xcursor && (m3->mc_xcursor->mx_cursor.mc_flags & C_INITIALIZED) && |
|
|
|
if (XCURSOR_INITED(m3) && IS_LEAF(mp)) |
|
|
|
IS_LEAF(mp)) { |
|
|
|
XCURSOR_REFRESH(m3, m3->mc_pg[mc->mc_top], m3->mc_ki[mc->mc_top]); |
|
|
|
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); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
DPRINTF(("mp left: %d, rp left: %d", SIZELEFT(mp), SIZELEFT(rp))); |
|
|
|
DPRINTF(("mp left: %d, rp left: %d", SIZELEFT(mp), SIZELEFT(rp))); |
|
|
|