]> git.ipfire.org Git - thirdparty/knot-dns.git/commitdiff
lmdb: add one swappable database cursor to Knot LMDB transaction
authorDavid Vašek <david.vasek@nic.cz>
Wed, 11 Feb 2026 13:56:21 +0000 (14:56 +0100)
committerDavid Vašek <david.vasek@nic.cz>
Wed, 20 May 2026 07:10:38 +0000 (09:10 +0200)
src/knot/journal/knot_lmdb.c
src/knot/journal/knot_lmdb.h

index 73724ab657ba6137daaddc8403b9cdd0bea6c8eb..8f0e498c5cfc3671a593f4b597466780178db757 100644 (file)
@@ -289,6 +289,11 @@ void knot_lmdb_abort(knot_lmdb_txn_t *txn)
                        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;
        }
@@ -311,10 +316,16 @@ void knot_lmdb_commit(knot_lmdb_txn_t *txn)
        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;
@@ -355,6 +366,16 @@ static bool curget(knot_lmdb_txn_t *txn, MDB_cursor_op op)
        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);
index 7c4f65557cb6901c5a369539cb94bbf5e3e8437f..ed0482a4167337da3a3671e146ec5e25dd9e2ffc 100644 (file)
@@ -31,7 +31,8 @@ typedef struct knot_lmdb_db {
 
 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;
 
@@ -178,6 +179,16 @@ void knot_lmdb_abort(knot_lmdb_txn_t *txn);
  */
 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.
  *