diff options
Diffstat (limited to 'src/model.c')
-rw-r--r-- | src/model.c | 111 |
1 files changed, 76 insertions, 35 deletions
diff --git a/src/model.c b/src/model.c index f3e56971..f06a5e82 100644 --- a/src/model.c +++ b/src/model.c @@ -31,8 +31,10 @@ #include <stddef.h> #include <stdlib.h> -#define DEFAULT_ORDER SPO -#define DEFAULT_GRAPH_ORDER GSPO +#define DEFAULT_ORDER SERD_ORDER_SPO +#define DEFAULT_GRAPH_ORDER SERD_ORDER_GSPO + +static const SerdQuad wildcard_pattern = {0, 0, 0, 0}; /** Compare quads lexicographically, ignoring graph. @@ -81,13 +83,13 @@ serd_quad_compare(const void* x, const void* y, void* user_data) corresponding order with a G prepended (so G will be the MSN). */ static inline bool -serd_model_has_index(const SerdModel* model, - SerdOrder* order, - int* n_prefix, - bool graphs) +serd_model_has_index(const SerdModel* model, + SerdStatementOrder* order, + int* n_prefix, + bool graphs) { if (graphs) { - *order = (SerdOrder)(*order + GSPO); + *order = (SerdStatementOrder)(*order + SERD_ORDER_GSPO); *n_prefix += 1; } @@ -101,7 +103,7 @@ serd_model_has_index(const SerdModel* model, @param n_prefix Set to the length of the range prefix (for `mode` == RANGE and `mode` == FILTER_RANGE) */ -static SerdOrder +static SerdStatementOrder serd_model_best_index(const SerdModel* model, const SerdQuad pat, SearchMode* mode, @@ -113,7 +115,7 @@ serd_model_best_index(const SerdModel* model, ((pat[0] ? 1u : 0u) * 0x100 + (pat[1] ? 1u : 0u) * 0x010 + (pat[2] ? 1u : 0u) * 0x001); - SerdOrder good[2] = {(SerdOrder)-1, (SerdOrder)-1}; + SerdStatementOrder good[2] = {(SerdStatementOrder)-1, (SerdStatementOrder)-1}; #define PAT_CASE(sig, m, g0, g1, np) \ case sig: \ @@ -137,12 +139,12 @@ serd_model_best_index(const SerdModel* model, *n_prefix = graph_search ? 4 : 3; return graph_search ? DEFAULT_GRAPH_ORDER : DEFAULT_ORDER; - PAT_CASE(0x001, RANGE, OPS, OSP, 1); - PAT_CASE(0x010, RANGE, POS, PSO, 1); - PAT_CASE(0x011, RANGE, OPS, POS, 2); - PAT_CASE(0x100, RANGE, SPO, SOP, 1); - PAT_CASE(0x101, RANGE, SOP, OSP, 2); - PAT_CASE(0x110, RANGE, SPO, PSO, 2); + PAT_CASE(0x001, RANGE, SERD_ORDER_OPS, SERD_ORDER_OSP, 1); + PAT_CASE(0x010, RANGE, SERD_ORDER_POS, SERD_ORDER_PSO, 1); + PAT_CASE(0x011, RANGE, SERD_ORDER_OPS, SERD_ORDER_POS, 2); + PAT_CASE(0x100, RANGE, SERD_ORDER_SPO, SERD_ORDER_SOP, 1); + PAT_CASE(0x101, RANGE, SERD_ORDER_SOP, SERD_ORDER_OSP, 2); + PAT_CASE(0x110, RANGE, SERD_ORDER_SPO, SERD_ORDER_PSO, 2); default: break; } @@ -160,8 +162,8 @@ serd_model_best_index(const SerdModel* model, // Not so good orderings that require filtering, but can // still be constrained to a range switch (sig) { - PAT_CASE(0x011, FILTER_RANGE, OSP, PSO, 1); - PAT_CASE(0x101, FILTER_RANGE, SPO, OPS, 1); + PAT_CASE(0x011, FILTER_RANGE, SERD_ORDER_OSP, SERD_ORDER_PSO, 1); + PAT_CASE(0x101, FILTER_RANGE, SERD_ORDER_SPO, SERD_ORDER_OPS, 1); // SPO is always present, so 0x110 is never reached here default: break; @@ -212,9 +214,11 @@ serd_model_new(SerdWorld* world, SerdModelFlags flags) } // Create end iterator - const SerdOrder order = model->indices[GSPO] ? GSPO : SPO; - ZixBTreeIter* cur = zix_btree_end(model->indices[order]); - const SerdQuad pat = {0, 0, 0, 0}; + const SerdStatementOrder order = + model->indices[SERD_ORDER_GSPO] ? SERD_ORDER_GSPO : SERD_ORDER_SPO; + + ZixBTreeIter* cur = zix_btree_end(model->indices[order]); + const SerdQuad pat = {0, 0, 0, 0}; model->end = serd_iter_new(model, cur, pat, order, ALL, 0); @@ -230,7 +234,7 @@ serd_model_copy(const SerdModel* model) SerdModel* copy = serd_model_new(model->world, model->flags); - SerdRange* all = serd_model_all(model); + SerdRange* all = serd_model_all(model, SERD_ORDER_SPO); serd_model_add_range(copy, all); serd_range_free(all); @@ -250,8 +254,8 @@ serd_model_equals(const SerdModel* a, const SerdModel* b) return false; } - SerdRange* ra = serd_model_all(a); - SerdRange* rb = serd_model_all(b); + SerdRange* ra = serd_model_all(a, SERD_ORDER_SPO); + SerdRange* rb = serd_model_all(b, SERD_ORDER_SPO); bool result = true; while (!serd_range_empty(ra) && !serd_range_empty(rb)) { @@ -333,7 +337,8 @@ serd_model_flags(const SerdModel* model) size_t serd_model_size(const SerdModel* model) { - const SerdOrder order = model->indices[GSPO] ? GSPO : SPO; + const SerdStatementOrder order = + model->indices[SERD_ORDER_GSPO] ? SERD_ORDER_GSPO : SERD_ORDER_SPO; return zix_btree_size(model->indices[order]); } @@ -343,6 +348,34 @@ serd_model_empty(const SerdModel* model) return serd_model_size(model) == 0; } +// FIXME : expose + +static SerdIter* +serd_model_begin_ordered(const SerdModel* model, const SerdStatementOrder order) +{ + return model->indices[order] + ? serd_iter_new(model, + zix_btree_begin(model->indices[order]), + wildcard_pattern, + order, + ALL, + 0) + : NULL; +} + +static SerdIter* +serd_model_end_ordered(const SerdModel* model, const SerdStatementOrder order) +{ + return model->indices[order] + ? serd_iter_new(model, + zix_btree_end(model->indices[order]), + wildcard_pattern, + order, + ALL, + 0) + : NULL; +} + SerdIter* serd_model_begin(const SerdModel* model) { @@ -350,9 +383,10 @@ serd_model_begin(const SerdModel* model) return serd_iter_copy(serd_model_end(model)); } - const SerdOrder order = model->indices[GSPO] ? GSPO : SPO; - ZixBTreeIter* cur = zix_btree_begin(model->indices[order]); - const SerdQuad pat = {0, 0, 0, 0}; + const SerdStatementOrder order = + model->indices[SERD_ORDER_GSPO] ? SERD_ORDER_GSPO : SERD_ORDER_SPO; + ZixBTreeIter* cur = zix_btree_begin(model->indices[order]); + const SerdQuad pat = {0, 0, 0, 0}; return serd_iter_new(model, cur, pat, order, ALL, 0); } @@ -363,10 +397,17 @@ serd_model_end(const SerdModel* model) } SerdRange* -serd_model_all(const SerdModel* model) +serd_model_all(const SerdModel* model, const SerdStatementOrder order) { - return serd_range_new(serd_model_begin(model), - serd_iter_copy(serd_model_end(model))); + const SerdStatementOrder real_order = + (order >= SERD_ORDER_GSPO && !(model->flags & SERD_INDEX_GRAPHS)) + ? order - SERD_ORDER_GSPO + : order; + + return model->indices[real_order] + ? serd_range_new(serd_model_begin_ordered(model, real_order), + serd_model_end_ordered(model, real_order)) + : NULL; } SerdIter* @@ -381,9 +422,9 @@ serd_model_find(const SerdModel* model, return serd_model_begin(model); } - SearchMode mode = ALL; - int n_prefix = 0; - const SerdOrder index_order = + SearchMode mode = ALL; + int n_prefix = 0; + const SerdStatementOrder index_order = serd_model_best_index(model, pat, &mode, &n_prefix); ZixBTree* const db = model->indices[index_order]; @@ -560,7 +601,7 @@ serd_model_add_internal(SerdModel* model, if (model->indices[i]) { if (!zix_btree_insert(model->indices[i], statement)) { added = true; - } else if (i == GSPO) { + } else if (i == SERD_ORDER_GSPO) { break; // Statement already indexed } } @@ -631,7 +672,7 @@ serd_model_erase(SerdModel* model, SerdIter* iter) const SerdStatement* statement = serd_iter_get(iter); SerdStatement* removed = NULL; - for (int i = SPO; i <= GPOS; ++i) { + for (int i = SERD_ORDER_SPO; i <= SERD_ORDER_GPOS; ++i) { if (model->indices[i]) { zix_btree_remove(model->indices[i], statement, |