mdb_cursor_close(txn->cursor);
txn->cursor = NULL;
}
+ if (txn->cursor_st != NULL) {
+ mdb_cursor_close(txn->cursor_st);
+ txn->cursor_st = NULL;
+ }
+
mdb_txn_abort(txn->txn);
txn->opened = false;
}
if (!txn_semcheck(txn)) {
return;
}
+
if (txn->cursor != NULL) {
mdb_cursor_close(txn->cursor);
txn->cursor = NULL;
}
+ if (txn->cursor_st != NULL) {
+ mdb_cursor_close(txn->cursor_st);
+ txn->cursor_st = NULL;
+ }
+
txn->ret = mdb_txn_commit(txn->txn);
err_to_knot(&txn->ret);
txn->opened = false;
return (txn->ret == KNOT_EOK);
}
+void knot_lmdb_cursor_swap(knot_lmdb_txn_t *txn)
+{
+ MDB_cursor *tmp = txn->cursor;
+ txn->cursor = txn->cursor_st;
+ txn->cursor_st = tmp;
+ if (txn->cursor != NULL) {
+ (void)curget(txn, MDB_GET_CURRENT);
+ }
+}
+
static int mdb_val_clone(const MDB_val *orig, MDB_val *clone)
{
clone->mv_data = malloc(orig->mv_size);
typedef struct {
MDB_txn *txn;
- MDB_cursor *cursor;
+ MDB_cursor *cursor; // Active cursor.
+ MDB_cursor *cursor_st; // Stored cursor.
MDB_val cur_key;
MDB_val cur_val;
*/
void knot_lmdb_commit(knot_lmdb_txn_t *txn);
+/*!
+ * \brief Swap two internal cursors in a transaction.
+ *
+ * \param txn Transaction in which cursors will be swapped.
+ *
+ * \note Both cursors retain their values.
+ * \note txn->cur_key and txn->cur_val are updated to reflect the new active cursor.
+ */
+void knot_lmdb_cursor_swap(knot_lmdb_txn_t *txn);
+
/*!
* \brief Find a key in database. The matched key will be in txn->cur_key and its value in txn->cur_val.
*