Selaa lähdekoodia

Hide txn handle; link graph instead of store to iterator.

Stefano Cossu 2 vuotta sitten
vanhempi
commit
b1767ab6d3
2 muutettua tiedostoa jossa 76 lisäystä ja 80 poistoa
  1. 17 34
      include/graph.h
  2. 59 46
      src/graph.c

+ 17 - 34
include/graph.h

@@ -53,11 +53,9 @@ LSUP_graph_new (
  * @param src[in] Source graph.
  *
  * @param dest[in] Destination graph.
- *
- * @param[in] txn Transaction handle.
  */
 LSUP_rc
-LSUP_graph_copy_contents (const LSUP_Graph *src, LSUP_Graph *dest, void *txn);
+LSUP_graph_copy_contents (const LSUP_Graph *src, LSUP_Graph *dest);
 
 
 /** Perform a boolean operation between two graphs.
@@ -72,8 +70,6 @@ LSUP_graph_copy_contents (const LSUP_Graph *src, LSUP_Graph *dest, void *txn);
  *
  * @param gr2[in] Second operand.
  *
- * @param[in] txn Transaction handle.
- *
  * @param res[out] Result graph. The handle should be initialized via
  *  #LSUP_graph_new() or equivalent. Any preexisting contents are not removed.
  *  If an unrecoverable error occurs, this graph is freed.
@@ -93,17 +89,18 @@ LSUP_graph_free (LSUP_Graph *gr);
 
 
 /** @brief Compare two graphs.
+ *
+ * Note that if any of the two graphs has an open transaction, the function
+ * is performed in the first graph's transaction.
  *
  * @param[in] gr1 First operand.
  *
  * @param[in] gr2 Second operand.
  *
- * @param[in] txn Transaction handle.
- *
  * @return True if the graphs are topologically equal, false otherwise.
  */
 bool
-LSUP_graph_equals (const LSUP_Graph *gr1, const LSUP_Graph *gr2, void *txn);
+LSUP_graph_equals (const LSUP_Graph *gr1, const LSUP_Graph *gr2);
 
 
 /** @brief Read-only graph URI.
@@ -167,13 +164,13 @@ LSUP_graph_size (const LSUP_Graph *gr);
  * @return 1 if the triple is found, 0 if not found.
  */
 bool
-LSUP_graph_contains (const LSUP_Graph *gr, const LSUP_Triple *spo, void *txn);
+LSUP_graph_contains (const LSUP_Graph *gr, const LSUP_Triple *spo);
 
 
 /** @brief Begin a transaction.
  *
- * If the underlying store supports it, begin a transaction and return
- * an opaque handle.
+ * If the underlying store supports it, begin a transaction for the given
+ * graph. Note that each graph can only have one open transaction at a time.
  *
  * The transaction must be either committed with #LSUP_graph_commit() or
  * rolled back with #LSUP_graph_abort().
@@ -182,14 +179,12 @@ LSUP_graph_contains (const LSUP_Graph *gr, const LSUP_Triple *spo, void *txn);
  *
  * @param[in] flags Unused for now, use 0. TODO
  *
- * @param[out] txn Transaction handle. This may be passed to all subsequent
- * operations that one wants to perform within that transaction.
- *
  * @return LSUP_OK on success; LSUP_VALUE_ERR if the graph store does not
- *  support transactions; <0 on other errors from the underlying store.
+ *  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 (const LSUP_Graph *gr, int flags, void **txn);
+LSUP_graph_begin (LSUP_Graph *gr, int flags);
 
 
 /** @brief Commit a transaction.
@@ -200,12 +195,10 @@ LSUP_graph_begin (const LSUP_Graph *gr, int flags, void **txn);
  *
  * @param[in] gr Graph handle.
  *
- * @param[in] txn Transaction handle.
- *
  * @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 (const LSUP_Graph *gr, void *txn);
+LSUP_rc LSUP_graph_commit (LSUP_Graph *gr);
 
 
 /** @brief Abort (roll back) a transaction.
@@ -214,23 +207,19 @@ LSUP_rc LSUP_graph_commit (const LSUP_Graph *gr, void *txn);
  * all changes.
  *
  * @param[in] gr Graph handle.
- *
- * @param[in] txn Transaction handle.
  */
-void LSUP_graph_abort (const LSUP_Graph *gr, void *txn);
+void LSUP_graph_abort (LSUP_Graph *gr);
 
 
 /** @brief Initialize an iterator to add triples.
  *
  * @param[in] gr Graph to add to. It is added to the iterator state.
  *
- * @param[in] txn Transaction handle.
- *
  * @return Iterator handle. This should be passed to #LSUP_graph_add_iter() and
  * must be freed with #LSUP_graph_add_done().
  */
 LSUP_GraphIterator *
-LSUP_graph_add_init (LSUP_Graph *gr, void *txn);
+LSUP_graph_add_init (LSUP_Graph *gr);
 
 
 
@@ -262,14 +251,12 @@ LSUP_graph_add_done (LSUP_GraphIterator *it);
  *
  * @param[in] strp Array of buffer triples to add. The last one must be NULL.
  *
- * @param[in] txn Transaction handle.
- *
  * @param[out] ct This will be filled with the total number of triples
  *  inserted.
  */
 LSUP_rc
 LSUP_graph_add (
-        LSUP_Graph *gr, const LSUP_Triple trp[], void *txn, size_t *ct);
+        LSUP_Graph *gr, const LSUP_Triple trp[], size_t *ct);
 
 
 /** @brief Delete triples by a matching pattern.
@@ -278,15 +265,13 @@ LSUP_graph_add (
  *
  * @param ptn[in] Matching pattern. Any and all of s, p, o can be NULL.
  *
- * @param[in] txn Transaction handle.
- *
  * @param ct[out] If not NULL it is populated with the number of triples
  *  deleted.
  */
 LSUP_rc
 LSUP_graph_remove (
         LSUP_Graph *gr, const LSUP_Term *s, const LSUP_Term *p,
-        const LSUP_Term *o, void *txn, size_t *ct);
+        const LSUP_Term *o, size_t *ct);
 
 
 /** Look up triples by a matching pattern and yield an iterator.
@@ -296,14 +281,12 @@ LSUP_graph_remove (
  * @param spo[in] Triple to look for. Any and all terms can be NULL, which
  *  indicate unbound terms.
  *
- * @param[in] txn Transaction handle.
- *
  * @param it[out] Pointer to a #LSUP_GraphIterator to be generated. It must be
  *  freed with #LSUP_graph_iter_free after use.
  */
 LSUP_GraphIterator *
 LSUP_graph_lookup (const LSUP_Graph *gr, const LSUP_Term *s,
-        const LSUP_Term *p, const LSUP_Term *o, void *txn, size_t *ct);
+        const LSUP_Term *p, const LSUP_Term *o, size_t *ct);
 
 
 /** @brief Advance a cursor obtained by a lookup and return a matching triple.

+ 59 - 46
src/graph.c

@@ -7,15 +7,18 @@
 struct graph_t {
     LSUP_Term               *uri;           ///< Graph "name" (URI).
     LSUP_Store *            store;          ///< Store handle.
-    LSUP_NSMap *            nsm;            /**< Namespace map. NOTE: This is
-                                               * NULL for permanent stores. */
+    LSUP_NSMap *            nsm;            /**< Namespace map.
+                                              *
+                                              * NOTE: This is
+                                              * NULL for permanent stores.
+                                              */
+    void *                  txn;            ///< Store transaction.
 };
 
 struct graph_iter_t {
-    LSUP_Store *            store;          ///< Store tied to the iterator.
+    const LSUP_Graph *      graph;          ///< Parent graph.
     void *                  data;           ///< Iterator state.
     size_t                  ct;             ///< Total lookup matches.
-    void *                  txn;            ///< Store transaction.
 };
 
 
@@ -95,9 +98,9 @@ LSUP_graph_bool_op(
     }
 
     if (op == LSUP_BOOL_UNION) {
-        rc = LSUP_graph_copy_contents (gr1, res, txn);
+        rc = LSUP_graph_copy_contents (gr1, res);
         PCHECK (rc, fail);
-        rc = LSUP_graph_copy_contents (gr2, res, txn);
+        rc = LSUP_graph_copy_contents (gr2, res);
         PCHECK (rc, fail);
 
         return LSUP_OK;
@@ -211,10 +214,10 @@ LSUP_graph_size (const LSUP_Graph *gr)
 
 
 bool
-LSUP_graph_equals (const LSUP_Graph *gr1, const LSUP_Graph *gr2, void *txn)
+LSUP_graph_equals (const LSUP_Graph *gr1, const LSUP_Graph *gr2)
 {
     LSUP_Graph *res = LSUP_graph_new (NULL, LSUP_STORE_HTABLE, NULL, NULL, 0);
-    LSUP_graph_bool_op (LSUP_BOOL_XOR, gr1, gr2, txn, res);
+    LSUP_graph_bool_op (LSUP_BOOL_XOR, gr1, gr2, gr1->txn, res);
     bool ret = (LSUP_graph_size (res) == 0);
 
     LSUP_graph_free (res);
@@ -224,17 +227,17 @@ LSUP_graph_equals (const LSUP_Graph *gr1, const LSUP_Graph *gr2, void *txn)
 
 
 LSUP_GraphIterator *
-LSUP_graph_add_init (LSUP_Graph *gr, void *txn)
+LSUP_graph_add_init (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, txn);
+    it->data = gr->store->sif->add_init_fn (gr->store->data, sc, gr->txn);
     LSUP_buffer_free (sc);
 
-    it->store = gr->store;
+    it->graph = gr;
 
     return it;
 }
@@ -246,18 +249,19 @@ LSUP_graph_add_iter (LSUP_GraphIterator *it, const LSUP_Triple *spo)
 
     LSUP_BufferTriple *sspo = LSUP_triple_serialize (spo);
     if (UNLIKELY (!sspo)) return LSUP_MEM_ERR;
+    const LSUP_StoreInt *sif = it->graph->store->sif;
 
-    LSUP_rc rc = it->store->sif->add_iter_fn (it->data, sspo);
+    LSUP_rc rc = sif->add_iter_fn (it->data, sspo);
     PCHECK (rc, finally);
 
     // Store datatype term permanently if the store supports it.
-    if (rc == LSUP_OK && it->store->sif->add_term_fn) {
+    if (rc == LSUP_OK && sif->add_term_fn) {
         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);
-                it->store->sif->add_term_fn (
-                        it->store->data, ser_dtype, it->txn);
+                sif->add_term_fn (
+                        it->graph->store->data, ser_dtype, it->graph->txn);
                 LSUP_buffer_free (ser_dtype);
             }
         }
@@ -274,18 +278,18 @@ finally:
 void
 LSUP_graph_add_done (LSUP_GraphIterator *it)
 {
-    it->store->sif->add_done_fn (it->data);
+    it->graph->store->sif->add_done_fn (it->data);
     free (it);
 }
 
 
 LSUP_rc
-LSUP_graph_add (LSUP_Graph *gr, const LSUP_Triple trp[], void *txn, size_t *ct)
+LSUP_graph_add (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, txn);
+    LSUP_GraphIterator *it = LSUP_graph_add_init (gr);
 
     if (ct) *ct = 0;
     // Serialize and insert RDF triples.
@@ -316,7 +320,7 @@ finally:
 LSUP_rc
 LSUP_graph_remove (
         LSUP_Graph *gr, const LSUP_Term *s, const LSUP_Term *p,
-        const LSUP_Term *o, void *txn, size_t *ct)
+        const LSUP_Term *o, size_t *ct)
 {
     LSUP_rc rc;
 
@@ -326,7 +330,8 @@ LSUP_graph_remove (
         *so = LSUP_term_serialize (o),
         *sc = LSUP_term_serialize (gr->uri);
 
-    rc = gr->store->sif->remove_fn (gr->store->data, ss, sp, so, sc, txn, ct);
+    rc = gr->store->sif->remove_fn (
+            gr->store->data, ss, sp, so, sc, gr->txn, ct);
 
     LSUP_buffer_free (ss);
     LSUP_buffer_free (sp);
@@ -343,16 +348,15 @@ 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, void *txn)
+LSUP_graph_copy_contents (const LSUP_Graph *src, LSUP_Graph *dest)
 {
     LSUP_rc rc = LSUP_NOACTION;
 
-    LSUP_GraphIterator *it = LSUP_graph_lookup (
-            src, NULL, NULL, NULL, txn, NULL);
+    LSUP_GraphIterator *it = LSUP_graph_lookup (src, NULL, NULL, NULL, NULL);
 
     LSUP_Triple spo;
 
-    LSUP_GraphIterator *add_it = LSUP_graph_add_init (dest, txn);
+    LSUP_GraphIterator *add_it = LSUP_graph_add_init (dest);
     while (LSUP_graph_iter_next (it, &spo) != LSUP_END) {
         LSUP_rc add_rc = LSUP_graph_add_iter (add_it, &spo);
         LSUP_triple_done (&spo);
@@ -373,32 +377,32 @@ LSUP_graph_copy_contents (const LSUP_Graph *src, LSUP_Graph *dest, void *txn)
 LSUP_GraphIterator *
 LSUP_graph_lookup (
         const LSUP_Graph *gr, const LSUP_Term *s, const LSUP_Term *p,
-        const LSUP_Term *o, void *txn, size_t *ct)
+        const LSUP_Term *o, size_t *ct)
 {
     LSUP_GraphIterator *it;
     MALLOC_GUARD (it, NULL);
 
-    it->store = gr->store;
-
     LSUP_Buffer
         *ss = LSUP_term_serialize (s),
         *sp = LSUP_term_serialize (p),
         *so = LSUP_term_serialize (o),
         *sc = LSUP_term_serialize (gr->uri);
 
-    it->txn = txn;
-    it->data = it->store->sif->lookup_fn (
-            it->store->data, ss, sp, so, sc, it->txn, ct);
-    if (UNLIKELY (!it->data)) {
-        free (it);
-        it = NULL;
-    }
+    it->data = gr->store->sif->lookup_fn (
+            gr->store->data, ss, sp, so, sc, gr->txn, ct);
 
     LSUP_buffer_free (ss);
     LSUP_buffer_free (sp);
     LSUP_buffer_free (so);
     LSUP_buffer_free (sc);
 
+    if (UNLIKELY (!it->data)) {
+        free (it);
+        return NULL;
+    }
+
+    it->graph = gr;
+
     return it;
 }
 
@@ -408,7 +412,7 @@ LSUP_graph_iter_next (LSUP_GraphIterator *it, LSUP_Triple *spo)
 {
     LSUP_Buffer *ss, *sp, *so;
     LSUP_BufferTriple *sspo;
-    if (it->store->sif->features & LSUP_STORE_COW) {
+    if (it->graph->store->sif->features & LSUP_STORE_COW) {
         CALLOC_GUARD (ss, LSUP_MEM_ERR);
         CALLOC_GUARD (sp, LSUP_MEM_ERR);
         CALLOC_GUARD (so, LSUP_MEM_ERR);
@@ -428,7 +432,7 @@ LSUP_graph_iter_next (LSUP_GraphIterator *it, LSUP_Triple *spo)
         if (!spo->o) return LSUP_ERROR;
     }
 
-    if (it->store->sif->features & LSUP_STORE_COW) {
+    if (it->graph->store->sif->features & LSUP_STORE_COW) {
         LSUP_btriple_free_shallow (sspo);
     } else {
         // TODO copy-on-retrieval stores. None yet.
@@ -441,16 +445,16 @@ LSUP_graph_iter_next (LSUP_GraphIterator *it, LSUP_Triple *spo)
 void
 LSUP_graph_iter_free (LSUP_GraphIterator *it)
 {
-    it->store->sif->lu_free_fn (it->data);
+    it->graph->store->sif->lu_free_fn (it->data);
     free (it);
 }
 
 
 bool
-LSUP_graph_contains (const LSUP_Graph *gr, const LSUP_Triple *spo, void *txn)
+LSUP_graph_contains (const LSUP_Graph *gr, const LSUP_Triple *spo)
 {
     LSUP_GraphIterator *it = LSUP_graph_lookup (
-            gr, spo->s, spo->p, spo->o, txn, NULL);
+            gr, spo->s, spo->p, spo->o, NULL);
     LSUP_Triple *tmp_spo = TRP_DUMMY;
     bool rc = LSUP_graph_iter_next (it, tmp_spo) != LSUP_END;
 
@@ -462,21 +466,30 @@ LSUP_graph_contains (const LSUP_Graph *gr, const LSUP_Triple *spo, void *txn)
 
 
 LSUP_rc
-LSUP_graph_begin (const LSUP_Graph *gr, int flags, void **txn) {
+LSUP_graph_begin (LSUP_Graph *gr, int flags) {
     if (!(gr->store->sif->features & LSUP_STORE_TXN)) return LSUP_VALUE_ERR;
 
-    return gr->store->sif->txn_begin_fn(gr->store->data, flags, txn);
+    return gr->store->sif->txn_begin_fn(gr->store->data, flags, &gr->txn);
 }
 
 
 LSUP_rc
-LSUP_graph_commit (const LSUP_Graph *gr, void *txn)
-{ return gr->store->sif->txn_commit_fn (txn); }
+LSUP_graph_commit (LSUP_Graph *gr)
+{
+    LSUP_rc rc = gr->store->sif->txn_commit_fn (gr->txn);
+
+    if (rc == LSUP_OK) gr->txn = NULL;
+
+    return rc;
+}
 
 
 void
-LSUP_graph_abort (const LSUP_Graph *gr, void *txn)
-{ gr->store->sif->txn_abort_fn (txn); }
+LSUP_graph_abort (LSUP_Graph *gr)
+{
+    gr->store->sif->txn_abort_fn (gr->txn);
+    gr->txn = NULL;
+}
 
 
 /*
@@ -490,7 +503,7 @@ LSUP_graph_abort (const LSUP_Graph *gr, void *txn)
  */
 inline static LSUP_rc
 graph_iter_next_buffer (LSUP_GraphIterator *it, LSUP_BufferTriple *sspo)
-{ return it->store->sif->lu_next_fn (it->data, sspo, NULL); }
+{ return it->graph->store->sif->lu_next_fn (it->data, sspo, NULL); }
 
 
 /**