* BerkeleyDB API, but much simplified.
*/
/*
- * Copyright 2011-2017 Howard Chu, Symas Corp.
+ * Copyright 2011-2018 Howard Chu, Symas Corp.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
unsigned char mx_dbflag;
} MDB_xcursor;
- /** Check if there is an inited xcursor, so #XCURSOR_REFRESH() is proper */
+ /** Check if there is an inited xcursor */
#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
+ /** Update the xcursor's sub-page pointer, if any, in \b mc. 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].
+ * with leaf page \b mp = mc->mc_pg[\b top].
*/
-#define XCURSOR_REFRESH(mc, mp, ki) do { \
+#define XCURSOR_REFRESH(mc, top, mp) do { \
MDB_page *xr_pg = (mp); \
- MDB_node *xr_node = NODEPTR(xr_pg, ki); \
+ MDB_node *xr_node; \
+ if (!XCURSOR_INITED(mc) || (mc)->mc_ki[top] >= NUMKEYS(xr_pg)) break; \
+ xr_node = NODEPTR(xr_pg, (mc)->mc_ki[top]); \
if ((xr_node->mn_flags & (F_DUPDATA|F_SUBDATA)) == F_DUPDATA) \
(mc)->mc_xcursor->mx_cursor.mc_pg[0] = NODEDATA(xr_node); \
} while (0)
if (m2 == mc) continue;
if (m2->mc_pg[mc->mc_top] == mp) {
m2->mc_pg[mc->mc_top] = np;
- if (XCURSOR_INITED(m2) && IS_LEAF(np))
- XCURSOR_REFRESH(m2, np, m2->mc_ki[mc->mc_top]);
+ if (IS_LEAF(np))
+ XCURSOR_REFRESH(m2, mc->mc_top, np);
}
}
}
} else {
memcpy((char *)mp + mp->mp_upper + PAGEBASE, (char *)fp + fp->mp_upper + PAGEBASE,
olddata.mv_size - fp->mp_upper - PAGEBASE);
+ memcpy((char *)(&mp->mp_ptrs), (char *)(&fp->mp_ptrs), NUMKEYS(fp) * sizeof(mp->mp_ptrs[0]));
for (i=0; i<NUMKEYS(fp); i++)
- mp->mp_ptrs[i] = fp->mp_ptrs[i] + offset;
+ mp->mp_ptrs[i] += offset;
}
}
if (m3->mc_ki[i] >= mc->mc_ki[i] && insert_key) {
m3->mc_ki[i]++;
}
- if (XCURSOR_INITED(m3))
- XCURSOR_REFRESH(m3, mp, m3->mc_ki[i]);
+ XCURSOR_REFRESH(m3, i, mp);
}
}
}
MDB_xcursor *mx = mc->mc_xcursor;
unsigned i = mc->mc_top;
MDB_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) {
if (m2 == mc || m2->mc_snum < mc->mc_snum) continue;
if (m2->mc_pg[i] == mp) {
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) {
- XCURSOR_REFRESH(m2, mp, m2->mc_ki[i]);
+ } else if (!insert_key) {
+ XCURSOR_REFRESH(m2, i, mp);
}
}
}
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) {
- MDB_node *n2 = leaf;
- if (m2->mc_ki[mc->mc_top] >= NUMKEYS(mp)) continue;
- 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);
+ XCURSOR_REFRESH(m2, mc->mc_top, mp);
}
}
}
m3->mc_ki[csrc->mc_top] = cdst->mc_ki[cdst->mc_top];
m3->mc_ki[csrc->mc_top-1]++;
}
- if (XCURSOR_INITED(m3) && IS_LEAF(mps))
- XCURSOR_REFRESH(m3, m3->mc_pg[csrc->mc_top], m3->mc_ki[csrc->mc_top]);
+ if (IS_LEAF(mps))
+ XCURSOR_REFRESH(m3, csrc->mc_top, m3->mc_pg[csrc->mc_top]);
}
} else
/* Adding on the right, bump others down */
} else {
m3->mc_ki[csrc->mc_top]--;
}
- if (XCURSOR_INITED(m3) && IS_LEAF(mps))
- XCURSOR_REFRESH(m3, m3->mc_pg[csrc->mc_top], m3->mc_ki[csrc->mc_top]);
+ if (IS_LEAF(mps))
+ XCURSOR_REFRESH(m3, csrc->mc_top, m3->mc_pg[csrc->mc_top]);
}
}
}
m3->mc_ki[top-1] > csrc->mc_ki[top-1]) {
m3->mc_ki[top-1]--;
}
- if (XCURSOR_INITED(m3) && IS_LEAF(psrc))
- XCURSOR_REFRESH(m3, m3->mc_pg[top], m3->mc_ki[top]);
+ if (IS_LEAF(psrc))
+ XCURSOR_REFRESH(m3, top, m3->mc_pg[top]);
}
}
{
} else if (m3->mc_ki[mc->mc_top] > ki) {
m3->mc_ki[mc->mc_top]--;
}
- if (XCURSOR_INITED(m3))
- XCURSOR_REFRESH(m3, m3->mc_pg[mc->mc_top], m3->mc_ki[mc->mc_top]);
+ XCURSOR_REFRESH(m3, mc->mc_top, mp);
}
}
}
m3->mc_ki[ptop] >= mc->mc_ki[ptop]) {
m3->mc_ki[ptop]++;
}
- if (XCURSOR_INITED(m3) && IS_LEAF(mp))
- XCURSOR_REFRESH(m3, m3->mc_pg[mc->mc_top], m3->mc_ki[mc->mc_top]);
+ if (IS_LEAF(mp))
+ XCURSOR_REFRESH(m3, mc->mc_top, m3->mc_pg[mc->mc_top]);
}
}
DPRINTF(("mp left: %d, rp left: %d", SIZELEFT(mp), SIZELEFT(rp)));