Ver código fonte

Expose iterator transaction.

Stefano Cossu 2 anos atrás
pai
commit
13b523a4d6
3 arquivos alterados com 32 adições e 6 exclusões
  1. 20 4
      include/store_interface.h
  2. 6 2
      src/graph.c
  3. 6 0
      src/store_mdb.c

+ 20 - 4
include/store_interface.h

@@ -224,6 +224,25 @@ typedef LSUP_rc (*store_add_iter_fn_t)(
 typedef void (*store_add_abort_fn_t)(void *it);
 
 
+/*
+ * Iterator function types.
+ */
+
+/** @brief Get iterator active transaction handle.
+ *
+ * This function is used to get an active transaction during an iteration loop
+ * in order to perform an action using the store state within that loop. Some
+ * stores (e.g. MDB) only support one R/W open transaction per thread, so this
+ * is also the only way to perform anything else than iterating or committing
+ * while a loop is open.
+ *
+ * @param[in] it Iterator handle to get the transaction from.
+ *
+ * @return Transaction handle. DO NOT close this transaction directly.
+ */
+typedef void * (*iter_txn_fn_t)(void *it);
+
+
 /** @brief Finalize an add loop and free iterator.
  *
  * This must be called after #add_iter_fn.
@@ -355,10 +374,6 @@ typedef LSUP_rc (*store_nsm_put_fn_t)(
 typedef LSUP_NSMap * (*store_nsm_get_fn_t)(void *store);
 
 
-/*
- * Iterator function types.
- */
-
 /** @brief Prototype: yield the matching triples and advance the iterator.
  *
  * NOTE: Iterators keep transactions open. Don't hold on to them longer than
@@ -441,6 +456,7 @@ typedef struct store_if_t {
     store_txn_begin_fn_t txn_begin_fn;  ///< Begin transaction.
     store_txn_commit_fn_t txn_commit_fn; ///< Commit transaction.
     store_txn_abort_fn_t txn_abort_fn;  ///< Abort transaction.
+    iter_txn_fn_t       iter_txn_fn;    ///< Get iterator's transaction.
 
     // Addition.
     store_add_init_fn_t add_init_fn;    ///< Initialize add iteration.

+ 6 - 2
src/graph.c

@@ -76,6 +76,8 @@ BACKEND_TBL
     if (gr->store->sif->features & LSUP_STORE_PERM) gr->nsm = NULL;
     else gr->nsm = nsm ? nsm : LSUP_default_nsm;
 
+    gr->txn = NULL;
+
     log_debug ("Graph created.");
     return gr;
 }
@@ -256,12 +258,14 @@ LSUP_graph_add_iter (LSUP_GraphIterator *it, const LSUP_Triple *spo)
 
     // Store datatype term permanently if the store supports it.
     if (rc == LSUP_OK && sif->add_term_fn) {
+        void *txn;
         for (int i = 0; i < 3; i++) {
             LSUP_Term *term = LSUP_triple_pos (spo, i);
             if (term->type == LSUP_TERM_LITERAL) {
                 LSUP_Buffer *ser_dtype = LSUP_term_serialize (term->datatype);
-                sif->add_term_fn (
-                        it->graph->store->data, ser_dtype, it->graph->txn);
+                // Run add_term in the iterator's txn.
+                txn = sif->iter_txn_fn ? sif->iter_txn_fn (it->data) : NULL;
+                sif->add_term_fn ( it->graph->store->data, ser_dtype, txn);
                 LSUP_buffer_free (ser_dtype);
             }
         }

+ 6 - 0
src/store_mdb.c

@@ -534,6 +534,11 @@ mdbstore_txn_abort (void *th)
 { mdb_txn_abort ((MDB_txn *) th); }
 
 
+static void *
+mdbiter_txn (void *h)
+{ return ((MDBIterator *) h)->txn; }
+
+
 /** @brief Begin an add loop.
  *
  * @sa #store_add_init_fn_t
@@ -1142,6 +1147,7 @@ const LSUP_StoreInt mdbstore_int = {
     .txn_begin_fn   = mdbstore_txn_begin,
     .txn_commit_fn  = mdbstore_txn_commit,
     .txn_abort_fn   = mdbstore_txn_abort,
+    .iter_txn_fn    = mdbiter_txn,
 
     .add_init_fn    = mdbstore_add_init,
     .add_iter_fn    = mdbstore_add_iter,