|
@@ -29,9 +29,6 @@ struct graph_iter_t {
|
|
inline static LSUP_rc
|
|
inline static LSUP_rc
|
|
graph_iter_next_buffer (LSUP_GraphIterator *it);
|
|
graph_iter_next_buffer (LSUP_GraphIterator *it);
|
|
|
|
|
|
-inline static LSUP_rc
|
|
|
|
-graph_iter_alloc_buffers (LSUP_GraphIterator *it);
|
|
|
|
-
|
|
|
|
|
|
|
|
#define ENTRY(a, b) (be) == (LSUP_STORE_##a) ||
|
|
#define ENTRY(a, b) (be) == (LSUP_STORE_##a) ||
|
|
static inline bool
|
|
static inline bool
|
|
@@ -64,6 +61,42 @@ LSUP_graph_new (LSUP_Store *store, LSUP_Term *uri, LSUP_NSMap *nsm)
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
+LSUP_Graph *
|
|
|
|
+LSUP_graph_get_txn (void *txn, LSUP_Store *store, LSUP_Term *uri, size_t *ct)
|
|
|
|
+{
|
|
|
|
+ LSUP_Buffer *sc = LSUP_term_serialize (uri);
|
|
|
|
+ void *it = store->sif->lookup_fn (
|
|
|
|
+ store->data, NULL, NULL, NULL, sc, NULL, NULL);
|
|
|
|
+
|
|
|
|
+ LSUP_Graph *gr = LSUP_graph_new (NULL, uri, NULL);
|
|
|
|
+ LSUP_BufferTriple *sspo = BTRP_DUMMY;
|
|
|
|
+ void *add_it = LSUP_graph_add_init_txn (txn, gr);
|
|
|
|
+
|
|
|
|
+ size_t _ct = 0;
|
|
|
|
+ while (store->sif->lu_next_fn (it, sspo, NULL) == LSUP_OK) {
|
|
|
|
+ // TODO This is inefficient, it's deserializing a buffer triple that
|
|
|
|
+ // will be re-serialized by LSUP_graph_add_iter.
|
|
|
|
+ LSUP_Triple *spo = LSUP_triple_new_from_btriple (sspo);
|
|
|
|
+ LSUP_graph_add_iter (add_it, spo);
|
|
|
|
+ LSUP_triple_free (spo);
|
|
|
|
+ _ct++;
|
|
|
|
+ }
|
|
|
|
+ LSUP_graph_add_done (add_it);
|
|
|
|
+ store->sif->lu_free_fn(it);
|
|
|
|
+ LSUP_buffer_free (sc);
|
|
|
|
+ LSUP_btriple_free_shallow (sspo);
|
|
|
|
+
|
|
|
|
+ // Do not create a new graph if no results were found.
|
|
|
|
+ if (_ct == 0) {
|
|
|
|
+ LSUP_graph_free (gr);
|
|
|
|
+ gr = NULL;
|
|
|
|
+ }
|
|
|
|
+ if (ct) *ct = _ct;
|
|
|
|
+
|
|
|
|
+ return gr;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+
|
|
LSUP_rc
|
|
LSUP_rc
|
|
LSUP_graph_bool_op_txn (
|
|
LSUP_graph_bool_op_txn (
|
|
void *txn, const LSUP_bool_op op,
|
|
void *txn, const LSUP_bool_op op,
|
|
@@ -80,6 +113,8 @@ LSUP_graph_bool_op_txn (
|
|
return LSUP_VALUE_ERR;
|
|
return LSUP_VALUE_ERR;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ /* BEGIN union block. */
|
|
|
|
+
|
|
if (op == LSUP_BOOL_UNION) {
|
|
if (op == LSUP_BOOL_UNION) {
|
|
rc = LSUP_graph_copy_contents (gr1, res);
|
|
rc = LSUP_graph_copy_contents (gr1, res);
|
|
PCHECK (rc, fail);
|
|
PCHECK (rc, fail);
|
|
@@ -89,6 +124,10 @@ LSUP_graph_bool_op_txn (
|
|
return LSUP_OK;
|
|
return LSUP_OK;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ /* END union block. */
|
|
|
|
+
|
|
|
|
+ /* BEGIN subtraction, intersection, XOR block. */
|
|
|
|
+
|
|
LSUP_Buffer
|
|
LSUP_Buffer
|
|
*res_sc = LSUP_term_serialize (res->uri),
|
|
*res_sc = LSUP_term_serialize (res->uri),
|
|
*gr1_sc = LSUP_term_serialize (gr1->uri),
|
|
*gr1_sc = LSUP_term_serialize (gr1->uri),
|
|
@@ -107,7 +146,7 @@ LSUP_graph_bool_op_txn (
|
|
lu1_it = gr1->store->sif->lookup_fn (
|
|
lu1_it = gr1->store->sif->lookup_fn (
|
|
gr1->store->data, sspo->s, sspo->p, sspo->o, gr1_sc,
|
|
gr1->store->data, sspo->s, sspo->p, sspo->o, gr1_sc,
|
|
txn, &ct);
|
|
txn, &ct);
|
|
- if (ct > 0)
|
|
|
|
|
|
+ if (ct == 0)
|
|
res->store->sif->add_iter_fn (add_it, sspo);
|
|
res->store->sif->add_iter_fn (add_it, sspo);
|
|
gr1->store->sif->lu_free_fn (lu1_it);
|
|
gr1->store->sif->lu_free_fn (lu1_it);
|
|
}
|
|
}
|
|
@@ -129,10 +168,13 @@ LSUP_graph_bool_op_txn (
|
|
gr1->store->sif->lu_free_fn (lu1_it);
|
|
gr1->store->sif->lu_free_fn (lu1_it);
|
|
|
|
|
|
res->store->sif->add_done_fn (add_it);
|
|
res->store->sif->add_done_fn (add_it);
|
|
|
|
+ LSUP_btriple_free_shallow (sspo);
|
|
LSUP_buffer_free (res_sc);
|
|
LSUP_buffer_free (res_sc);
|
|
LSUP_buffer_free (gr1_sc);
|
|
LSUP_buffer_free (gr1_sc);
|
|
LSUP_buffer_free (gr2_sc);
|
|
LSUP_buffer_free (gr2_sc);
|
|
|
|
|
|
|
|
+ /* END subtraction, intersection, XOR block. */
|
|
|
|
+
|
|
return rc;
|
|
return rc;
|
|
|
|
|
|
fail:
|
|
fail:
|
|
@@ -203,7 +245,17 @@ LSUP_graph_set_namespace (LSUP_Graph *gr, LSUP_NSMap *nsm)
|
|
|
|
|
|
size_t
|
|
size_t
|
|
LSUP_graph_size (const LSUP_Graph *gr)
|
|
LSUP_graph_size (const LSUP_Graph *gr)
|
|
-{ return gr->store->sif->size_fn (gr->store->data); }
|
|
|
|
|
|
+{
|
|
|
|
+ size_t ct = 0;
|
|
|
|
+ LSUP_Buffer *sc = LSUP_term_serialize (gr->uri);
|
|
|
|
+ void *it = gr->store->sif->lookup_fn (
|
|
|
|
+ gr->store->data, NULL, NULL, NULL, sc, NULL, &ct);
|
|
|
|
+ gr->store->sif->lu_free_fn (it);
|
|
|
|
+
|
|
|
|
+ LSUP_buffer_free (sc);
|
|
|
|
+
|
|
|
|
+ return ct;
|
|
|
|
+}
|
|
|
|
|
|
|
|
|
|
bool
|
|
bool
|
|
@@ -321,15 +373,13 @@ LSUP_graph_remove_txn (
|
|
const LSUP_Term *s, const LSUP_Term *p, const LSUP_Term *o,
|
|
const LSUP_Term *s, const LSUP_Term *p, const LSUP_Term *o,
|
|
size_t *ct)
|
|
size_t *ct)
|
|
{
|
|
{
|
|
- LSUP_rc rc;
|
|
|
|
-
|
|
|
|
LSUP_Buffer
|
|
LSUP_Buffer
|
|
*ss = LSUP_term_serialize (s),
|
|
*ss = LSUP_term_serialize (s),
|
|
*sp = LSUP_term_serialize (p),
|
|
*sp = LSUP_term_serialize (p),
|
|
*so = LSUP_term_serialize (o),
|
|
*so = LSUP_term_serialize (o),
|
|
*sc = LSUP_term_serialize (gr->uri);
|
|
*sc = LSUP_term_serialize (gr->uri);
|
|
|
|
|
|
- rc = gr->store->sif->remove_fn (
|
|
|
|
|
|
+ LSUP_rc rc = gr->store->sif->remove_fn (
|
|
gr->store->data, ss, sp, so, sc, txn, ct);
|
|
gr->store->data, ss, sp, so, sc, txn, ct);
|
|
|
|
|
|
LSUP_buffer_free (ss);
|
|
LSUP_buffer_free (ss);
|
|
@@ -403,7 +453,15 @@ LSUP_graph_lookup_txn (
|
|
}
|
|
}
|
|
|
|
|
|
it->graph = gr;
|
|
it->graph = gr;
|
|
- RCNL (graph_iter_alloc_buffers (it));
|
|
|
|
|
|
+
|
|
|
|
+ if (it->graph->store->sif->features & LSUP_STORE_COW) {
|
|
|
|
+ // Copy-on-wite store.
|
|
|
|
+ it->sspo = BTRP_DUMMY;
|
|
|
|
+
|
|
|
|
+ if (UNLIKELY (it->sspo == NULL)) return NULL;
|
|
|
|
+ } else {
|
|
|
|
+ // TODO copy-on-retrieval store. No implementations yet.
|
|
|
|
+ }
|
|
|
|
|
|
return it;
|
|
return it;
|
|
}
|
|
}
|
|
@@ -444,6 +502,7 @@ LSUP_graph_iter_free (LSUP_GraphIterator *it)
|
|
*/
|
|
*/
|
|
if (it->graph->store->sif->features & LSUP_STORE_COW) {
|
|
if (it->graph->store->sif->features & LSUP_STORE_COW) {
|
|
LSUP_btriple_free_shallow (it->sspo);
|
|
LSUP_btriple_free_shallow (it->sspo);
|
|
|
|
+ log_debug ("Freeing dummy triple @ %p", it->sspo);
|
|
} else {
|
|
} else {
|
|
// TODO copy-on-retrieval stores. None yet.
|
|
// TODO copy-on-retrieval stores. None yet.
|
|
}
|
|
}
|
|
@@ -662,24 +721,6 @@ graph_iter_next_buffer (LSUP_GraphIterator *it)
|
|
{ return it->graph->store->sif->lu_next_fn (it->data, it->sspo, NULL); }
|
|
{ return it->graph->store->sif->lu_next_fn (it->data, it->sspo, NULL); }
|
|
|
|
|
|
|
|
|
|
-/** @brief Properly allocate temporary byte buffers in advance of iteration.
|
|
|
|
- */
|
|
|
|
-inline LSUP_rc
|
|
|
|
-graph_iter_alloc_buffers (LSUP_GraphIterator *it)
|
|
|
|
-{
|
|
|
|
- if (it->graph->store->sif->features & LSUP_STORE_COW) {
|
|
|
|
- it->sspo = BTRP_DUMMY;
|
|
|
|
- CALLOC_GUARD (it->sspo->s, LSUP_MEM_ERR);
|
|
|
|
- CALLOC_GUARD (it->sspo->p, LSUP_MEM_ERR);
|
|
|
|
- CALLOC_GUARD (it->sspo->o, LSUP_MEM_ERR);
|
|
|
|
- } else {
|
|
|
|
- // TODO copy-on-retrieval stores. None yet.
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- return LSUP_OK;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-
|
|
|
|
/**
|
|
/**
|
|
* Extern inline definitions.
|
|
* Extern inline definitions.
|
|
*/
|
|
*/
|