unsigned int mc_flags; /**< @ref mdb_cursor */
MDB_page *mc_pg[CURSOR_STACK]; /**< stack of pushed pages */
indx_t mc_ki[CURSOR_STACK]; /**< stack of page indices */
+#ifdef MDB_VL32
+ MDB_page *mc_ovpg; /**< a referenced overflow page */
+#endif
};
/** Context for sorted-dup records.
return;
for (i=0; i<mc->mc_snum; i++)
mdb_page_unref(mc->mc_txn, mc->mc_pg[i]);
+ if (mc->mc_ovpg) {
+ mdb_page_unref(mc->mc_txn, mc->mc_ovpg);
+ mc->mc_ovpg = 0;
+ }
mc->mc_snum = mc->mc_top = 0;
mc->mc_pg[0] = NULL;
mc->mc_flags &= ~C_INITIALIZED;
* The caller must copy the data if it must be used later in the same txn.
*
* Also - our reference counting revolves around cursors, but overflow pages
- * aren't ever pointed to by a cursor. As such, they always remain referenced
- * in a txn until it ends.
+ * aren't pointed to by a cursor's page stack. We have to remember them
+ * explicitly, in the added mc_ovpg field. A single cursor can only hold a
+ * reference to one overflow page at a time.
*
* @param[in] txn the transaction for this access.
* @param[in] pgno the page number for the page to retrieve.
pgno_t pgno;
int rc;
+#ifdef MDB_VL32
+ if (mc->mc_ovpg) {
+ MDB_PAGE_UNREF(mc->mc_txn, mc->mc_ovpg);
+ mc->mc_ovpg = 0;
+ }
+#endif
if (!F_ISSET(leaf->mn_flags, F_BIGDATA)) {
data->mv_size = NODEDSZ(leaf);
data->mv_data = NODEDATA(leaf);
return rc;
}
data->mv_data = METADATA(omp);
+#ifdef MDB_VL32
+ mc->mc_ovpg = omp;
+#endif
return MDB_SUCCESS;
}
mx->mx_cursor.mc_dbflag = &mx->mx_dbflag;
mx->mx_cursor.mc_snum = 0;
mx->mx_cursor.mc_top = 0;
+#ifdef MDB_VL32
+ mx->mx_cursor.mc_ovpg = 0;
+#endif
mx->mx_cursor.mc_flags = C_SUB | (mc->mc_flags & (C_ORIG_RDONLY|C_WRITEMAP));
mx->mx_dbx.md_name.mv_size = 0;
mx->mx_dbx.md_name.mv_data = NULL;
mc->mc_top = 0;
mc->mc_pg[0] = 0;
mc->mc_ki[0] = 0;
+#ifdef MDB_VL32
+ mc->mc_ovpg = 0;
+#endif
mc->mc_flags = txn->mt_flags & (C_ORIG_RDONLY|C_WRITEMAP);
if (txn->mt_dbs[dbi].md_flags & MDB_DUPSORT) {
mdb_tassert(txn, mx != NULL);
cdst->mc_snum = csrc->mc_snum;
cdst->mc_top = csrc->mc_top;
cdst->mc_flags = csrc->mc_flags;
+#ifdef MDB_VL32
+ cdst->mc_ovpg = csrc->mc_ovpg;
+#endif
for (i=0; i<csrc->mc_snum; i++) {
cdst->mc_pg[i] = csrc->mc_pg[i];