Browse Source

Add txn to several graph ops; add non-txn inline versions.

Stefano Cossu 1 year ago
parent
commit
e452d6b4a3
2 changed files with 129 additions and 57 deletions
  1. 77 13
      include/graph.h
  2. 52 44
      src/graph.c

+ 77 - 13
include/graph.h

@@ -21,7 +21,8 @@ typedef struct graph_iter_t LSUP_GraphIterator;
 
 /** @brief Create an empty graph.
  *
- * @param[in] uri URI of the new graph. If NULL, a UUID4 URN is generated.
+ * @param[in] uri URI of the new graph. If NULL, a UUID4 URN is generated. The
+ *  graph owns the handle.
  *
  * @param store_type[in] Type of store backing the graph. One of the values of
  *  #LSUP_StoreType.
@@ -50,12 +51,21 @@ LSUP_graph_new (
  *
  * The destination graph is not initialized here, so the copy is cumulative.
  *
+ * @param[in] txn Transaction handle. It may be NULL.
+ *
  * @param src[in] Source graph.
  *
  * @param dest[in] Destination graph.
  */
 LSUP_rc
-LSUP_graph_copy_contents (const LSUP_Graph *src, LSUP_Graph *dest);
+LSUP_graph_copy_contents_txn (
+        void *txn, const LSUP_Graph *src, LSUP_Graph *dest);
+
+
+/// Non-transactional version of #LSUP_graph_copy_contents_txn.
+inline LSUP_rc
+LSUP_graph_copy_contents (const LSUP_Graph *src, LSUP_Graph *dest)
+{ return LSUP_graph_copy_contents_txn (NULL, src, dest); }
 
 
 /** Perform a boolean operation between two graphs.
@@ -64,6 +74,8 @@ LSUP_graph_copy_contents (const LSUP_Graph *src, LSUP_Graph *dest);
  * between two other graphs. The resulting graph may be of any store type and
  * may be the result of graphs of different store types.
  *
+ * @param[in] txn Transaction handle. It may be NULL.
+ *
  * @param op[in] Operation to perform. One of #LSUP_bool_op.
  *
  * @param gr1[in] First operand.
@@ -77,9 +89,17 @@ LSUP_graph_copy_contents (const LSUP_Graph *src, LSUP_Graph *dest);
  * @return LSUP_OK on success; <0 on error.
  */
 LSUP_rc
-LSUP_graph_bool_op(
-        const LSUP_bool_op op, const LSUP_Graph *gr1, const LSUP_Graph *gr2,
-        LSUP_Graph *res);
+LSUP_graph_bool_op_txn (
+        void *txn, const LSUP_bool_op op,
+        const LSUP_Graph *gr1, const LSUP_Graph *gr2, LSUP_Graph *res);
+
+
+/// Non-transactional version of #LSUP_graph_bool_op_txn.
+inline LSUP_rc
+LSUP_graph_bool_op (
+        const LSUP_bool_op op,
+        const LSUP_Graph *gr1, const LSUP_Graph *gr2, LSUP_Graph *res)
+{ return LSUP_graph_bool_op_txn (NULL, op, gr1, gr2, res); }
 
 
 /** @brief Free a graph.
@@ -190,12 +210,14 @@ LSUP_graph_contains (const LSUP_Graph *gr, const LSUP_Triple *spo);
  *
  * @param[in] flags Unused for now, use 0. TODO
  *
+ * @param[out] txn Address to be populated with the new transaction handle.
+ *
  * @return LSUP_OK on success; LSUP_VALUE_ERR if the graph store does not
  *  support transactions; LSUP_TXN_ERR if the store has already an uncommitted
  *  transaction; <0 on other errors from the underlying store.
  */
 LSUP_rc
-LSUP_graph_begin (LSUP_Graph *gr, int flags);
+LSUP_graph_begin (LSUP_Graph *gr, int flags, void **txn);
 
 
 /** @brief Commit a transaction.
@@ -211,7 +233,7 @@ LSUP_graph_begin (LSUP_Graph *gr, int flags);
  * @return LSUP_OK if the transaction was committed successfully; LSUP_NOACTION
  *  if NULL was passed; LSUP_TXN_ERR on error.
  */
-LSUP_rc LSUP_graph_commit (LSUP_Graph *gr);
+LSUP_rc LSUP_graph_commit (LSUP_Graph *gr, void *txn);
 
 
 /** @brief Abort (roll back) a transaction.
@@ -223,10 +245,12 @@ LSUP_rc LSUP_graph_commit (LSUP_Graph *gr);
  *
  * @param[in] gr Graph handle.
  */
-void LSUP_graph_abort (LSUP_Graph *gr);
+void LSUP_graph_abort (LSUP_Graph *gr, void *txn);
 
 
 /** @brief Initialize an iterator to add triples.
+ *
+ * @param[in] txn Transaction handle. It may be NULL.
  *
  * @param[in] gr Graph to add to. It is added to the iterator state.
  *
@@ -234,8 +258,13 @@ void LSUP_graph_abort (LSUP_Graph *gr);
  * must be freed with #LSUP_graph_add_done().
  */
 LSUP_GraphIterator *
-LSUP_graph_add_init (LSUP_Graph *gr);
+LSUP_graph_add_init_txn (void *txn, LSUP_Graph *gr);
+
 
+/// Non-transactional version of #LSUP_graph_init_txn.
+inline LSUP_GraphIterator *
+LSUP_graph_add_init (LSUP_Graph *gr)
+{ return LSUP_graph_add_init_txn (NULL, gr); }
 
 
 /** @brief Add a single triple to the store.
@@ -245,7 +274,14 @@ LSUP_graph_add_init (LSUP_Graph *gr);
  * @param[in] spo Triple to add. Caller retains ownership.
  */
 LSUP_rc
-LSUP_graph_add_iter (LSUP_GraphIterator *it, const LSUP_Triple *spo);
+LSUP_graph_add_iter_txn (
+        void *txn, LSUP_GraphIterator *it, const LSUP_Triple *spo);
+
+
+/// Non-transactional version of #LSUP_graph_add_iter_txn.
+inline LSUP_rc
+LSUP_graph_add_iter (LSUP_GraphIterator *it, const LSUP_Triple *spo)
+{ return LSUP_graph_add_iter_txn (NULL, it, spo); }
 
 
 /** @brief Finalize an add iteration loop and free the iterator.
@@ -259,6 +295,8 @@ LSUP_graph_add_done (LSUP_GraphIterator *it);
 
 
 /** @brief Add triples to a graph.
+ *
+ * @param[in] txn Transaction handle. It may be NULL.
  *
  * @param[in] gr Graph to add triples to.
  *
@@ -270,11 +308,20 @@ LSUP_graph_add_done (LSUP_GraphIterator *it);
  *  inserted.
  */
 LSUP_rc
+LSUP_graph_add_txn (
+        void *txn, LSUP_Graph *gr, const LSUP_Triple trp[], size_t *ct);
+
+
+/// Non-transactional version of #LSUP_graph_add_txn.
+inline LSUP_rc
 LSUP_graph_add (
-        LSUP_Graph *gr, const LSUP_Triple trp[], size_t *ct);
+        LSUP_Graph *gr, const LSUP_Triple trp[], size_t *ct)
+{ return LSUP_graph_add_txn (NULL, gr, trp, ct); }
 
 
 /** @brief Delete triples by a matching pattern.
+ *
+ * @param[in] txn Transaction handle. It may be NULL.
  *
  * @param gr[in] Graph to delete triples from.
  *
@@ -284,12 +331,22 @@ LSUP_graph_add (
  *  deleted.
  */
 LSUP_rc
+LSUP_graph_remove_txn (
+        void *txn, LSUP_Graph *gr, const LSUP_Term *s, const LSUP_Term *p,
+        const LSUP_Term *o, size_t *ct);
+
+
+/// Non-transactional version of #LSUP_graph_remove_txn.
+inline LSUP_rc
 LSUP_graph_remove (
         LSUP_Graph *gr, const LSUP_Term *s, const LSUP_Term *p,
-        const LSUP_Term *o, size_t *ct);
+        const LSUP_Term *o, size_t *ct)
+{ return LSUP_graph_remove_txn (NULL, gr, s, p, o, ct); }
 
 
 /** Look up triples by a matching pattern and yield an iterator.
+ *
+ * @param[in] txn Transaction handle. It may be NULL.
  *
  * @param gr[in] Graph to look up.
  *
@@ -300,10 +357,17 @@ LSUP_graph_remove (
  *  freed with #LSUP_graph_iter_free after use.
  */
 LSUP_GraphIterator *
-LSUP_graph_lookup (const LSUP_Graph *gr, const LSUP_Term *s,
+LSUP_graph_lookup_txn (void *txn, const LSUP_Graph *gr, const LSUP_Term *s,
         const LSUP_Term *p, const LSUP_Term *o, size_t *ct);
 
 
+/// Non-transactional version of #LSUP_graph_lookup_txn.
+inline LSUP_GraphIterator *
+LSUP_graph_lookup (const LSUP_Graph *gr, const LSUP_Term *s,
+        const LSUP_Term *p, const LSUP_Term *o, size_t *ct)
+{ return LSUP_graph_lookup_txn (NULL, gr, s, p, o, ct); }
+
+
 /** @brief Advance a cursor obtained by a lookup and return a matching triple.
  *
  * @param it[in] Iterator handle obtained through #LSUP_graph_lookup.

+ 52 - 44
src/graph.c

@@ -12,7 +12,6 @@ struct graph_t {
                                               * NOTE: This is
                                               * NULL for permanent stores.
                                               */
-    void *                  txn;            ///< Store transaction.
 };
 
 struct graph_iter_t {
@@ -87,17 +86,15 @@ LSUP_graph_new (
     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;
 }
 
 
 LSUP_rc
-LSUP_graph_bool_op(
-        const LSUP_bool_op op, const LSUP_Graph *gr1, const LSUP_Graph *gr2,
-        LSUP_Graph *res)
+LSUP_graph_bool_op_txn (
+        void *txn, const LSUP_bool_op op,
+        const LSUP_Graph *gr1, const LSUP_Graph *gr2, LSUP_Graph *res)
 {
     LSUP_rc rc = LSUP_NOACTION;
     if (UNLIKELY (
@@ -127,16 +124,16 @@ LSUP_graph_bool_op(
     LSUP_BufferTriple *sspo = BTRP_DUMMY;
     size_t ct;
 
-    add_it = res->store->sif->add_init_fn (res->store->data, res_sc, gr1->txn);
+    add_it = res->store->sif->add_init_fn (res->store->data, res_sc, txn);
 
     if (op == LSUP_BOOL_XOR) {
         // Add triples from gr2 if not found in gr1.
         lu2_it = gr2->store->sif->lookup_fn (
-                gr2->store->data, NULL, NULL, NULL, gr2_sc, NULL, gr1->txn);
+                gr2->store->data, NULL, NULL, NULL, gr2_sc, NULL, txn);
         while (gr2->store->sif->lu_next_fn (lu2_it, sspo, NULL) == LSUP_OK) {
             lu1_it = gr1->store->sif->lookup_fn (
                     gr1->store->data, sspo->s, sspo->p, sspo->o, gr1_sc,
-                    gr1->txn, &ct);
+                    txn, &ct);
             if (ct > 0)
                 res->store->sif->add_iter_fn (add_it, sspo);
             gr1->store->sif->lu_free_fn (lu1_it);
@@ -145,11 +142,11 @@ LSUP_graph_bool_op(
     }
 
     lu1_it = gr1->store->sif->lookup_fn (
-            gr1->store->data, NULL, NULL, NULL, gr1_sc, gr1->txn, NULL);
+            gr1->store->data, NULL, NULL, NULL, gr1_sc, txn, NULL);
     while (gr1->store->sif->lu_next_fn (lu1_it, sspo, NULL) == LSUP_OK) {
         lu2_it = gr2->store->sif->lookup_fn (
                 gr2->store->data, sspo->s, sspo->p, sspo->o, gr2_sc,
-                gr1->txn, &ct);
+                txn, &ct);
         // For XOR and subtraction, add if not found.
         // For intersection, add if found.
         if ((ct == 0) ^ (op == LSUP_BOOL_INTERSECTION))
@@ -246,14 +243,14 @@ LSUP_graph_equals (const LSUP_Graph *gr1, const LSUP_Graph *gr2)
 
 
 LSUP_GraphIterator *
-LSUP_graph_add_init (LSUP_Graph *gr)
+LSUP_graph_add_init_txn (void *txn, LSUP_Graph *gr)
 {
     LSUP_GraphIterator *it;
     CALLOC_GUARD (it, NULL);
 
     LSUP_Buffer *sc = LSUP_term_serialize (gr->uri);
 
-    it->data = gr->store->sif->add_init_fn (gr->store->data, sc, gr->txn);
+    it->data = gr->store->sif->add_init_fn (gr->store->data, sc, txn);
     LSUP_buffer_free (sc);
 
     it->graph = gr;
@@ -263,7 +260,8 @@ LSUP_graph_add_init (LSUP_Graph *gr)
 
 
 LSUP_rc
-LSUP_graph_add_iter (LSUP_GraphIterator *it, const LSUP_Triple *spo)
+LSUP_graph_add_iter_txn (
+        void *txn, LSUP_GraphIterator *it, const LSUP_Triple *spo)
 {
     log_trace (
             "Adding triple: {%s, %s, %s}",
@@ -277,13 +275,10 @@ 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);
-                // 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);
             }
@@ -307,19 +302,20 @@ LSUP_graph_add_done (LSUP_GraphIterator *it)
 
 
 LSUP_rc
-LSUP_graph_add (LSUP_Graph *gr, const LSUP_Triple trp[], size_t *ct)
+LSUP_graph_add_txn (
+        void *txn, LSUP_Graph *gr, const LSUP_Triple trp[], size_t *ct)
 {
     LSUP_rc rc = LSUP_NOACTION;
 
     // Initialize iterator.
-    LSUP_GraphIterator *it = LSUP_graph_add_init (gr);
+    LSUP_GraphIterator *it = LSUP_graph_add_init_txn (txn, gr);
 
     if (ct) *ct = 0;
     // Serialize and insert RDF triples.
     for (size_t i = 0; trp[i].s != NULL; i++) {
         log_trace ("Inserting triple #%lu", i);
 
-        LSUP_rc db_rc = LSUP_graph_add_iter (it, trp + i);
+        LSUP_rc db_rc = LSUP_graph_add_iter_txn (txn, it, trp + i);
 
         if (db_rc == LSUP_OK) {
             rc = LSUP_OK;
@@ -341,9 +337,10 @@ finally:
 
 
 LSUP_rc
-LSUP_graph_remove (
-        LSUP_Graph *gr, const LSUP_Term *s, const LSUP_Term *p,
-        const LSUP_Term *o, size_t *ct)
+LSUP_graph_remove_txn (
+        void *txn, LSUP_Graph *gr,
+        const LSUP_Term *s, const LSUP_Term *p, const LSUP_Term *o,
+        size_t *ct)
 {
     LSUP_rc rc;
 
@@ -354,7 +351,7 @@ LSUP_graph_remove (
         *sc = LSUP_term_serialize (gr->uri);
 
     rc = gr->store->sif->remove_fn (
-            gr->store->data, ss, sp, so, sc, gr->txn, ct);
+            gr->store->data, ss, sp, so, sc, txn, ct);
 
     LSUP_buffer_free (ss);
     LSUP_buffer_free (sp);
@@ -371,16 +368,18 @@ LSUP_graph_remove (
  * The destination graph is not initialized here, so the copy is cumulative.
  */
 LSUP_rc
-LSUP_graph_copy_contents (const LSUP_Graph *src, LSUP_Graph *dest)
+LSUP_graph_copy_contents_txn (
+        void *txn, const LSUP_Graph *src, LSUP_Graph *dest)
 {
     LSUP_rc rc = LSUP_NOACTION;
 
-    LSUP_GraphIterator *it = LSUP_graph_lookup (src, NULL, NULL, NULL, NULL);
+    LSUP_GraphIterator *it = LSUP_graph_lookup_txn (
+            txn, src, NULL, NULL, NULL, NULL);
 
     LSUP_Triple *spo = NULL;
-    LSUP_GraphIterator *add_it = LSUP_graph_add_init (dest);
+    LSUP_GraphIterator *add_it = LSUP_graph_add_init_txn (txn, dest);
     while (LSUP_graph_iter_next (it, &spo) != LSUP_END) {
-        LSUP_rc add_rc = LSUP_graph_add_iter (add_it, spo);
+        LSUP_rc add_rc = LSUP_graph_add_iter_txn (txn, add_it, spo);
         LSUP_triple_free (spo);
         if (LIKELY (add_rc == LSUP_OK)) rc = LSUP_OK;
         else if (add_rc < 0) {
@@ -397,9 +396,10 @@ LSUP_graph_copy_contents (const LSUP_Graph *src, LSUP_Graph *dest)
 
 
 LSUP_GraphIterator *
-LSUP_graph_lookup (
-        const LSUP_Graph *gr, const LSUP_Term *s, const LSUP_Term *p,
-        const LSUP_Term *o, size_t *ct)
+LSUP_graph_lookup_txn (
+        void *txn, const LSUP_Graph *gr,
+        const LSUP_Term *s, const LSUP_Term *p, const LSUP_Term *o,
+        size_t *ct)
 {
     LSUP_GraphIterator *it;
     MALLOC_GUARD (it, NULL);
@@ -411,7 +411,7 @@ LSUP_graph_lookup (
         *sc = LSUP_term_serialize (gr->uri);
 
     it->data = gr->store->sif->lookup_fn (
-            gr->store->data, ss, sp, so, sc, gr->txn, ct);
+            gr->store->data, ss, sp, so, sc, txn, ct);
 
     LSUP_buffer_free (ss);
     LSUP_buffer_free (sp);
@@ -489,30 +489,25 @@ LSUP_graph_contains (const LSUP_Graph *gr, const LSUP_Triple *spo)
 
 
 LSUP_rc
-LSUP_graph_begin (LSUP_Graph *gr, int flags) {
+LSUP_graph_begin (LSUP_Graph *gr, int flags, void **txn) {
     if (!(gr->store->sif->features & LSUP_STORE_TXN)) return LSUP_VALUE_ERR;
 
-    return gr->store->sif->txn_begin_fn(gr->store->data, flags, &gr->txn);
+    return gr->store->sif->txn_begin_fn (gr->store->data, flags, txn);
 }
 
 
 LSUP_rc
-LSUP_graph_commit (LSUP_Graph *gr)
+LSUP_graph_commit (LSUP_Graph *gr, void *txn)
 {
-    LSUP_rc rc = gr->store->sif->txn_commit_fn (gr->txn);
-
-    if (rc == LSUP_OK) gr->txn = NULL;
+    if (!(gr->store->sif->features & LSUP_STORE_TXN)) return LSUP_VALUE_ERR;
 
-    return rc;
+    return gr->store->sif->txn_commit_fn (txn);
 }
 
 
 void
-LSUP_graph_abort (LSUP_Graph *gr)
-{
-    gr->store->sif->txn_abort_fn (gr->txn);
-    gr->txn = NULL;
-}
+LSUP_graph_abort (LSUP_Graph *gr, void *txn)
+{ return gr->store->sif->txn_abort_fn (txn); }
 
 
 LSUP_LinkMap *
@@ -733,4 +728,17 @@ graph_iter_alloc_buffers (LSUP_GraphIterator *it)
  */
 
 size_t LSUP_graph_size (const LSUP_Graph *gr);
+LSUP_rc LSUP_graph_bool_op (
+        const LSUP_bool_op op,
+        const LSUP_Graph *gr1, const LSUP_Graph *gr2, LSUP_Graph *res);
+LSUP_rc LSUP_graph_copy_contents (const LSUP_Graph *src, LSUP_Graph *dest);
+LSUP_GraphIterator *LSUP_graph_add_init (LSUP_Graph *gr);
+LSUP_rc LSUP_graph_add_iter (LSUP_GraphIterator *it, const LSUP_Triple *spo);
+LSUP_rc LSUP_graph_add (LSUP_Graph *gr, const LSUP_Triple trp[], size_t *ct);
+LSUP_rc LSUP_graph_remove (
+        LSUP_Graph *gr, const LSUP_Term *s, const LSUP_Term *p,
+        const LSUP_Term *o, size_t *ct);
+LSUP_GraphIterator *
+LSUP_graph_lookup (const LSUP_Graph *gr, const LSUP_Term *s,
+        const LSUP_Term *p, const LSUP_Term *o, size_t *ct);