Procházet zdrojové kódy

WIP Add context list.

scossu před 4 dny
rodič
revize
8151d8916d
7 změnil soubory, kde provedl 128 přidání a 4 odebrání
  1. 1 1
      Makefile
  2. 16 0
      include/lsup/graph.h
  3. 18 0
      include/lsup/store_interface.h
  4. 1 2
      src/core.c
  5. 23 0
      src/graph.c
  6. 42 1
      src/store_mdb.c
  7. 27 0
      test/test_graph.c

+ 1 - 1
Makefile

@@ -20,7 +20,7 @@ VALGRIND_DUMP = /tmp/lsup_valgrind.log
 CALLGRIND_DUMP = /tmp/lsup_callgrind.out
 MASSIF_DUMP = /tmp/lsup_massif.out
 
-INCLUDE_BASE := . -Iinclude -Iext/tpl/src -Iext/hashmap -Iext/log/src
+INCLUDE_BASE := . -Iinclude -I/opt/local/include -Iext/tpl/src -Iext/hashmap -Iext/log/src
 INCLUDE := -I$(INCLUDE_BASE)
 _CFLAGS := -std=gnu11 -Wall -fPIC $(INCLUDE)
 CFLAGS = $(_CFLAGS) -O3

+ 16 - 0
include/lsup/graph.h

@@ -466,6 +466,22 @@ LSUP_TermSet *
 LSUP_graph_unique_terms (const LSUP_Graph *gr, LSUP_TriplePos pos);
 
 
+/** @brief List all graph URIs in a store.
+ *
+ * @param[in] txn Transaction handle to work in. It may be NULL.
+ *
+ * @param[in] store Store to look for graphs.
+ *
+ * @return Term set of graph URIs, or NULL on error.
+ */
+LSUP_TermSet *
+LSUP_graph_list_txn (void *txn, LSUP_Store *store);
+
+
+/// Non-transactional version of #LSUP_graph_list_txn.
+#define LSUP_graph_list(...) LSUP_graph_list_txn (NULL, __VA_ARGS__)
+
+
 /** @brief Add triples for a term and related link map to a graph.
  *
  * The link map can be of inbound, outbound, or edge type; depending on

+ 18 - 0
include/lsup/store_interface.h

@@ -446,6 +446,18 @@ typedef LSUP_rc (*iter_next_fn_t)(
 typedef void (*iter_free_fn_t)(void * it);
 
 
+/** @brief Prototype: Get index of all graph (context) URIs in a store.
+ *
+ * Only applicable to stores with the LSUP_STORE_CTX feature flag.
+ *
+ * @param[in] store Store handle.
+ *
+ * @return Set of all context URIs.
+ */
+typedef LSUP_Buffer ** (*store_ctx_list_fn_t)(void *store);
+
+
+
 /*
  * Iterface type definitions.
  */
@@ -524,6 +536,10 @@ typedef struct store_if_t {
                                         ///< Only available (and mandatory)
                                         ///< in stores with the
                                         ///< #LSUP_STORE_IDX feature.
+    store_ctx_list_fn_t ctx_list_fn;    ///< Get all context URIs in a store.
+                                        ///<
+                                        ///< Only applicable to stores with
+                                        ///< LSUP_STORE_CTX feature.
 } LSUP_StoreInt;
 
 
@@ -563,6 +579,8 @@ const LSUP_StoreInt my_store_int = {
 
     .nsm_put_fn     = my_nsm_put_fn,
     .nsm_get_fn     = my_nsm_get_fn,
+
+    .ctx_list_fn   = my_ctx_list_fn,
 };
 */
 

+ 1 - 2
src/core.c

@@ -1,10 +1,9 @@
-#define _XOPEN_SOURCE 500
 #include <errno.h>
 #include <ftw.h>
 #include <string.h>
 
-#include "lsup/core.h"
 #include "lmdb.h"
+#include "lsup/core.h"
 
 
 bool LSUP_env_is_init = false;

+ 23 - 0
src/graph.c

@@ -637,6 +637,29 @@ LSUP_graph_iter_free (LSUP_GraphIterator *it)
 }
 
 
+LSUP_TermSet *
+LSUP_graph_list_txn (void *txn, LSUP_Store *store)
+{
+    LSUP_Term **tdata = store->sif->ctx_ls_fn (store->data, txn);
+    if (UNLIKELY (!tdata)) return NULL;
+
+    LSUP_TermSet ts = LSUP_term_set_new();
+
+    size_t i = 0;
+    while (tdata[i]) {
+        LSUP_Term *t = LSUP_term_new_from_buffer (tdata[i++]);
+        LSUP_rc rc = LSUP_term_set_add (ts, t, NULL);
+        if (UNLIKELY (rc != LSUP_OK)) {
+            LSUP_term_free (t);
+            LSUP_term_set_free (ts);
+
+            return NULL;
+        }
+    }
+    return tdata;
+}
+
+
 bool
 LSUP_graph_contains (const LSUP_Graph *gr, const LSUP_Triple *spo)
 {

+ 42 - 1
src/store_mdb.c

@@ -112,7 +112,7 @@ typedef struct mdbstore_iter_t {
 /*          #ID pfx #DB label   #Flags  */ \
     ENTRY(  T_ST,   "t:st",     0               )   /* Key to ser. term */  \
     ENTRY(  SPO_C,  "spo:c",    DUPFIXED_MASK   )   /* Triple to context */ \
-    ENTRY(  C_,     "c:",       0               )   /* Track empty ctx */   \
+    ENTRY(  C_,     "c:",       0               )   /* Track empty ctx TODO remove, unused. */   \
     ENTRY(  PFX_NS, "pfx:ns",   0               )   /* Prefix to NS */      \
     ENTRY(  IDK_ID, "idk:id",   0               )   /* ID key to ID */      \
 
@@ -1271,6 +1271,45 @@ fail:
 }
 
 
+LSUP_Buffer **
+mdbstore_ctx_list (void *h, void *th)
+{
+    MDBStore *store = h;
+    LSUP_rc rc;
+    mdb_txn *txn;
+    if (th) txn = th;
+    else CHECK (mdb_txn_begin (store->env, NULL, MDB_RDONLY, &txn), fail);
+    MDB_cursor *cur;
+
+    CHECK (mdb_cursor_open (txn, store->dbi[IDX_C_SPO], &cur), fail);
+
+    MDB_stat stat;
+    mdb_stat (txn, store->dbi[IDX_C_SPO], &stat);
+    size_t ct = stat.ms_entries;
+    LSUP_Buffer **tdata = malloc ((ct + 1) * sizeof(*data));
+    if (!UNLIKELY (!tdata)) goto fail;
+
+    mdb_value key, data;
+    size_t i = 0;
+    rc = mdb_cursor_get (cur, &key, &data, MDB_FIRST);
+    while (rc == MDB_SUCCESS) {
+I       CHECK (key_to_sterm (&key, &tdata[i++]), fail);
+        CHECK (mdb_cursor_get (cur, &key, &data, MDB_NEXT), fail);
+    }
+
+    tdata[ct] = NULL;  // Sentinel
+    mdb_cursor_close (cur);
+    if (txn != th && txn != NULL) mdb_txn_abort (txn);
+
+    return tdata;
+
+fail:
+    if (txn != th && txn != NULL) mdb_txn_abort (txn);
+    if (tdata) free (tdata);
+    return NULL;
+}
+
+
 const LSUP_StoreInt mdbstore_int = {
     .name           = "MDB Store",
     .features       = LSUP_STORE_PERM | LSUP_STORE_CTX | LSUP_STORE_IDX
@@ -1303,6 +1342,8 @@ const LSUP_StoreInt mdbstore_int = {
 
     .nsm_put_fn     = mdbstore_nsm_put,
     .nsm_get_fn     = mdbstore_nsm_get,
+
+    .ctx_index_fn   = mdbsore_ctx_index,
 };
 
 

+ 27 - 0
test/test_graph.c

@@ -640,6 +640,33 @@ _graph_relative (LSUP_StoreType type)
 }
 
 
+static int
+_graph_list (LSUP_StoreType type)
+{
+    const LSUP_StoreInt *sif = LSUP_store_int (type);
+    if (!(sif->features & LSUP_STORE_CTX)) return 0;
+
+    if (sif->setup_fn) sif->setup_fn (NULL, true);
+
+    LSUP_Store *store = LSUP_store_new (type, NULL, 0);
+
+    LSUP_Graph
+        *gr1 = LSUP_graph_new (store,  "urn:gr:1", NULL),
+        *gr2 = LSUP_graph_new (store,  "urn:gr:2", NULL),
+        *gr3 = LSUP_graph_new (store,  "urn:gr:3", NULL);
+
+    LSUP_Triple **trp = create_triples();
+    LSUP_graph_add (gr1, trp, NULL);
+
+    LSUP_TermSet *ts = LSUP_graph_list (store);
+    //TODO
+
+    free_triples (trp);
+
+    return 0;
+}
+
+
 static int
 test_environment()
 {