diff options
author | David Robillard <d@drobilla.net> | 2020-12-26 19:23:44 +0100 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2020-12-26 19:23:44 +0100 |
commit | 87aca493cd6ad0ffc49a896c9f8342d52ad6aa96 (patch) | |
tree | 25d222a5f8db03780cd1836dbca28ab5051cc173 /src/sord.c | |
parent | c05ab9add46d84e39bea5ee59258564ba35a9582 (diff) | |
download | sord-87aca493cd6ad0ffc49a896c9f8342d52ad6aa96.tar.gz sord-87aca493cd6ad0ffc49a896c9f8342d52ad6aa96.tar.bz2 sord-87aca493cd6ad0ffc49a896c9f8342d52ad6aa96.zip |
Format all code with clang-format
Diffstat (limited to 'src/sord.c')
-rw-r--r-- | src/sord.c | 1661 |
1 files changed, 838 insertions, 823 deletions
@@ -37,67 +37,73 @@ #include <string.h> #ifdef __GNUC__ -# define SORD_LOG_FUNC(fmt, arg1) __attribute__((format(printf, fmt, arg1))) +# define SORD_LOG_FUNC(fmt, arg1) __attribute__((format(printf, fmt, arg1))) #else -# define SORD_LOG_FUNC(fmt, arg1) +# define SORD_LOG_FUNC(fmt, arg1) #endif #define SORD_LOG(prefix, ...) fprintf(stderr, "[Sord::" prefix "] " __VA_ARGS__) #ifdef SORD_DEBUG_ITER -# define SORD_ITER_LOG(...) SORD_LOG("iter", __VA_ARGS__) +# define SORD_ITER_LOG(...) SORD_LOG("iter", __VA_ARGS__) #else -# define SORD_ITER_LOG(...) +# define SORD_ITER_LOG(...) #endif #ifdef SORD_DEBUG_SEARCH -# define SORD_FIND_LOG(...) SORD_LOG("search", __VA_ARGS__) +# define SORD_FIND_LOG(...) SORD_LOG("search", __VA_ARGS__) #else -# define SORD_FIND_LOG(...) +# define SORD_FIND_LOG(...) #endif #ifdef SORD_DEBUG_WRITE -# define SORD_WRITE_LOG(...) SORD_LOG("write", __VA_ARGS__) +# define SORD_WRITE_LOG(...) SORD_LOG("write", __VA_ARGS__) #else -# define SORD_WRITE_LOG(...) +# define SORD_WRITE_LOG(...) #endif -#define NUM_ORDERS 12 -#define STATEMENT_LEN 3 -#define TUP_LEN (STATEMENT_LEN + 1) -#define DEFAULT_ORDER SPO +#define NUM_ORDERS 12 +#define STATEMENT_LEN 3 +#define TUP_LEN (STATEMENT_LEN + 1) +#define DEFAULT_ORDER SPO #define DEFAULT_GRAPH_ORDER GSPO -#define TUP_FMT "(%s %s %s %s)" +#define TUP_FMT "(%s %s %s %s)" #define TUP_FMT_ELEM(e) ((e) ? sord_node_get_string(e) : (const uint8_t*)"*") -#define TUP_FMT_ARGS(t) \ - TUP_FMT_ELEM((t)[0]), \ - TUP_FMT_ELEM((t)[1]), \ - TUP_FMT_ELEM((t)[2]), \ - TUP_FMT_ELEM((t)[3]) +#define TUP_FMT_ARGS(t) \ + TUP_FMT_ELEM((t)[0]), TUP_FMT_ELEM((t)[1]), TUP_FMT_ELEM((t)[2]), \ + TUP_FMT_ELEM((t)[3]) #define TUP_G 3 /** Triple ordering */ typedef enum { - SPO, ///< Subject, Predicate, Object - SOP, ///< Subject, Object, Predicate - OPS, ///< Object, Predicate, Subject - OSP, ///< Object, Subject, Predicate - PSO, ///< Predicate, Subject, Object - POS, ///< Predicate, Object, Subject - GSPO, ///< Graph, Subject, Predicate, Object - GSOP, ///< Graph, Subject, Object, Predicate - GOPS, ///< Graph, Object, Predicate, Subject - GOSP, ///< Graph, Object, Subject, Predicate - GPSO, ///< Graph, Predicate, Subject, Object - GPOS ///< Graph, Predicate, Object, Subject + SPO, ///< Subject, Predicate, Object + SOP, ///< Subject, Object, Predicate + OPS, ///< Object, Predicate, Subject + OSP, ///< Object, Subject, Predicate + PSO, ///< Predicate, Subject, Object + POS, ///< Predicate, Object, Subject + GSPO, ///< Graph, Subject, Predicate, Object + GSOP, ///< Graph, Subject, Object, Predicate + GOPS, ///< Graph, Object, Predicate, Subject + GOSP, ///< Graph, Object, Subject, Predicate + GPSO, ///< Graph, Predicate, Subject, Object + GPOS ///< Graph, Predicate, Object, Subject } SordOrder; #ifdef SORD_DEBUG_SEARCH /** String name of each ordering (array indexed by SordOrder) */ -static const char* const order_names[NUM_ORDERS] = { - "spo", "sop", "ops", "osp", "pso", "pos", - "gspo", "gsop", "gops", "gosp", "gpso", "gpos" -}; +static const char* const order_names[NUM_ORDERS] = {"spo", + "sop", + "ops", + "osp", + "pso", + "pos", + "gspo", + "gsop", + "gops", + "gosp", + "gpso", + "gpos"}; #endif /** @@ -105,128 +111,134 @@ static const char* const order_names[NUM_ORDERS] = { (array indexed by SordOrder) */ static const int orderings[NUM_ORDERS][TUP_LEN] = { - { 0, 1, 2, 3 }, { 0, 2, 1, 3 }, // SPO, SOP - { 2, 1, 0, 3 }, { 2, 0, 1, 3 }, // OPS, OSP - { 1, 0, 2, 3 }, { 1, 2, 0, 3 }, // PSO, POS - { 3, 0, 1, 2 }, { 3, 0, 2, 1 }, // GSPO, GSOP - { 3, 2, 1, 0 }, { 3, 2, 0, 1 }, // GOPS, GOSP - { 3, 1, 0, 2 }, { 3, 1, 2, 0 } // GPSO, GPOS + {0, 1, 2, 3}, // SPO + {0, 2, 1, 3}, // SOP + {2, 1, 0, 3}, // OPS + {2, 0, 1, 3}, // OSP + {1, 0, 2, 3}, // PSO + {1, 2, 0, 3}, // POS + {3, 0, 1, 2}, // GSPO + {3, 0, 2, 1}, // GSOP + {3, 2, 1, 0}, // GOPS + {3, 2, 0, 1}, // GOSP + {3, 1, 0, 2}, // GPSO + {3, 1, 2, 0} // GPOS }; /** World */ struct SordWorldImpl { - ZixHash* nodes; - SerdErrorSink error_sink; - void* error_handle; + ZixHash* nodes; + SerdErrorSink error_sink; + void* error_handle; }; /** Store */ struct SordModelImpl { - SordWorld* world; + SordWorld* world; - /** Index for each possible triple ordering (may or may not exist). - * Each index is a tree of SordQuad with the appropriate ordering. - */ - ZixBTree* indices[NUM_ORDERS]; + /** Index for each possible triple ordering (may or may not exist). + * Each index is a tree of SordQuad with the appropriate ordering. + */ + ZixBTree* indices[NUM_ORDERS]; - size_t n_quads; - size_t n_iters; + size_t n_quads; + size_t n_iters; }; /** Mode for searching or iteration */ typedef enum { - ALL, ///< Iterate over entire store - SINGLE, ///< Iteration over a single element (exact search) - RANGE, ///< Iterate over range with equal prefix - FILTER_RANGE, ///< Iterate over range with equal prefix, filtering - FILTER_ALL ///< Iterate to end of store, filtering + ALL, ///< Iterate over entire store + SINGLE, ///< Iteration over a single element (exact search) + RANGE, ///< Iterate over range with equal prefix + FILTER_RANGE, ///< Iterate over range with equal prefix, filtering + FILTER_ALL ///< Iterate to end of store, filtering } SearchMode; /** Iterator over some range of a store */ struct SordIterImpl { - const SordModel* sord; ///< Model being iterated over - ZixBTreeIter* cur; ///< Current DB cursor - SordQuad pat; ///< Pattern (in ordering order) - SordOrder order; ///< Store order (which index) - SearchMode mode; ///< Iteration mode - int n_prefix; ///< Prefix for RANGE and FILTER_RANGE - bool end; ///< True iff reached end - bool skip_graphs; ///< Iteration should ignore graphs + const SordModel* sord; ///< Model being iterated over + ZixBTreeIter* cur; ///< Current DB cursor + SordQuad pat; ///< Pattern (in ordering order) + SordOrder order; ///< Store order (which index) + SearchMode mode; ///< Iteration mode + int n_prefix; ///< Prefix for RANGE and FILTER_RANGE + bool end; ///< True iff reached end + bool skip_graphs; ///< Iteration should ignore graphs }; static uint32_t sord_node_hash(const void* n) { - const SordNode* node = (const SordNode*)n; - uint32_t hash = zix_digest_start(); - hash = zix_digest_add(hash, node->node.buf, node->node.n_bytes); - hash = zix_digest_add(hash, &node->node.type, sizeof(node->node.type)); - if (node->node.type == SERD_LITERAL) { - hash = zix_digest_add(hash, &node->meta.lit, sizeof(node->meta.lit)); - } - return hash; + const SordNode* node = (const SordNode*)n; + uint32_t hash = zix_digest_start(); + hash = zix_digest_add(hash, node->node.buf, node->node.n_bytes); + hash = zix_digest_add(hash, &node->node.type, sizeof(node->node.type)); + if (node->node.type == SERD_LITERAL) { + hash = zix_digest_add(hash, &node->meta.lit, sizeof(node->meta.lit)); + } + return hash; } static bool sord_node_hash_equal(const void* a, const void* b) { - const SordNode* a_node = (const SordNode*)a; - const SordNode* b_node = (const SordNode*)b; - return (a_node == b_node) - || ((a_node->node.type == b_node->node.type) && - (a_node->node.type != SERD_LITERAL || - (a_node->meta.lit.datatype == b_node->meta.lit.datatype && - !strncmp(a_node->meta.lit.lang, - b_node->meta.lit.lang, - sizeof(a_node->meta.lit.lang)))) && - (serd_node_equals(&a_node->node, &b_node->node))); + const SordNode* a_node = (const SordNode*)a; + const SordNode* b_node = (const SordNode*)b; + return (a_node == b_node) || + ((a_node->node.type == b_node->node.type) && + (a_node->node.type != SERD_LITERAL || + (a_node->meta.lit.datatype == b_node->meta.lit.datatype && + !strncmp(a_node->meta.lit.lang, + b_node->meta.lit.lang, + sizeof(a_node->meta.lit.lang)))) && + (serd_node_equals(&a_node->node, &b_node->node))); } SORD_LOG_FUNC(3, 4) static void error(SordWorld* world, SerdStatus st, const char* fmt, ...) { - va_list args; - va_start(args, fmt); - const SerdError e = { st, NULL, 0, 0, fmt, &args }; - if (world->error_sink) { - world->error_sink(world->error_handle, &e); - } else { - fprintf(stderr, "error: "); - vfprintf(stderr, fmt, args); - } - va_end(args); + va_list args; + va_start(args, fmt); + const SerdError e = {st, NULL, 0, 0, fmt, &args}; + if (world->error_sink) { + world->error_sink(world->error_handle, &e); + } else { + fprintf(stderr, "error: "); + vfprintf(stderr, fmt, args); + } + va_end(args); } SordWorld* sord_world_new(void) { - SordWorld* world = (SordWorld*)malloc(sizeof(SordWorld)); - world->error_sink = NULL; - world->error_handle = NULL; + SordWorld* world = (SordWorld*)malloc(sizeof(SordWorld)); + world->error_sink = NULL; + world->error_handle = NULL; - world->nodes = zix_hash_new( - sord_node_hash, sord_node_hash_equal, sizeof(SordNode)); + world->nodes = + zix_hash_new(sord_node_hash, sord_node_hash_equal, sizeof(SordNode)); - return world; + return world; } static void free_node_entry(void* value, void* user_data) { - SordNode* node = (SordNode*)value; - if (node->node.type == SERD_LITERAL) { - sord_node_free((SordWorld*)user_data, node->meta.lit.datatype); - } - free((uint8_t*)node->node.buf); + SordNode* node = (SordNode*)value; + if (node->node.type == SERD_LITERAL) { + sord_node_free((SordWorld*)user_data, node->meta.lit.datatype); + } + free((uint8_t*)node->node.buf); } void sord_world_free(SordWorld* world) { - zix_hash_foreach(world->nodes, free_node_entry, world); - zix_hash_free(world->nodes); - free(world); + zix_hash_foreach(world->nodes, free_node_entry, world); + zix_hash_free(world->nodes); + free(world); } void @@ -234,96 +246,94 @@ sord_world_set_error_sink(SordWorld* world, SerdErrorSink error_sink, void* handle) { - world->error_sink = error_sink; - world->error_handle = handle; + world->error_sink = error_sink; + world->error_handle = handle; } static inline int sord_node_compare_literal(const SordNode* a, const SordNode* b) { - const int cmp = strcmp((const char*)sord_node_get_string(a), - (const char*)sord_node_get_string(b)); - if (cmp != 0) { - return cmp; - } - - const bool a_has_lang = a->meta.lit.lang[0]; - const bool b_has_lang = b->meta.lit.lang[0]; - const bool a_has_datatype = a->meta.lit.datatype; - const bool b_has_datatype = b->meta.lit.datatype; - const bool a_has_meta = a_has_lang || a_has_datatype; - const bool b_has_meta = b_has_lang || b_has_datatype; - - assert(!(a_has_lang && a_has_datatype)); - assert(!(b_has_lang && b_has_datatype)); - - if (!a_has_meta && !b_has_meta) { - return 0; - } else if (!a_has_meta || (a_has_lang && b_has_datatype)) { - return -1; - } else if (!b_has_meta || (a_has_datatype && b_has_lang)) { - return 1; - } else if (a_has_lang) { - assert(b_has_lang); - return strcmp(a->meta.lit.lang, b->meta.lit.lang); - } - - assert(a_has_datatype); - assert(b_has_datatype); - return strcmp((const char*)a->meta.lit.datatype->node.buf, - (const char*)b->meta.lit.datatype->node.buf); + const int cmp = strcmp((const char*)sord_node_get_string(a), + (const char*)sord_node_get_string(b)); + if (cmp != 0) { + return cmp; + } + + const bool a_has_lang = a->meta.lit.lang[0]; + const bool b_has_lang = b->meta.lit.lang[0]; + const bool a_has_datatype = a->meta.lit.datatype; + const bool b_has_datatype = b->meta.lit.datatype; + const bool a_has_meta = a_has_lang || a_has_datatype; + const bool b_has_meta = b_has_lang || b_has_datatype; + + assert(!(a_has_lang && a_has_datatype)); + assert(!(b_has_lang && b_has_datatype)); + + if (!a_has_meta && !b_has_meta) { + return 0; + } else if (!a_has_meta || (a_has_lang && b_has_datatype)) { + return -1; + } else if (!b_has_meta || (a_has_datatype && b_has_lang)) { + return 1; + } else if (a_has_lang) { + assert(b_has_lang); + return strcmp(a->meta.lit.lang, b->meta.lit.lang); + } + + assert(a_has_datatype); + assert(b_has_datatype); + return strcmp((const char*)a->meta.lit.datatype->node.buf, + (const char*)b->meta.lit.datatype->node.buf); } /** Compare nodes, considering NULL a wildcard match. */ static inline int sord_node_compare(const SordNode* a, const SordNode* b) { - if (a == b || !a || !b) { - return 0; // Exact or wildcard match - } else if (a->node.type != b->node.type) { - return (a->node.type < b->node.type) ? -1 : 1; - } - - int cmp = 0; - switch (a->node.type) { - case SERD_URI: - case SERD_BLANK: - return strcmp((const char*)a->node.buf, (const char*)b->node.buf); - case SERD_LITERAL: - cmp = sord_node_compare_literal(a, b); - break; - default: - break; - } - return cmp; + if (a == b || !a || !b) { + return 0; // Exact or wildcard match + } else if (a->node.type != b->node.type) { + return (a->node.type < b->node.type) ? -1 : 1; + } + + int cmp = 0; + switch (a->node.type) { + case SERD_URI: + case SERD_BLANK: + return strcmp((const char*)a->node.buf, (const char*)b->node.buf); + case SERD_LITERAL: + cmp = sord_node_compare_literal(a, b); + break; + default: + break; + } + return cmp; } bool sord_node_equals(const SordNode* a, const SordNode* b) { - return a == b; // Nodes are interned + return a == b; // Nodes are interned } /** Return true iff IDs are equivalent, or one is a wildcard */ static inline bool sord_id_match(const SordNode* a, const SordNode* b) { - return !a || !b || (a == b); + return !a || !b || (a == b); } static inline bool sord_quad_match_inline(const SordQuad x, const SordQuad y) { - return sord_id_match(x[0], y[0]) - && sord_id_match(x[1], y[1]) - && sord_id_match(x[2], y[2]) - && sord_id_match(x[3], y[3]); + return sord_id_match(x[0], y[0]) && sord_id_match(x[1], y[1]) && + sord_id_match(x[2], y[2]) && sord_id_match(x[3], y[3]); } bool sord_quad_match(const SordQuad x, const SordQuad y) { - return sord_quad_match_inline(x, y); + return sord_quad_match_inline(x, y); } /** @@ -334,44 +344,44 @@ sord_quad_match(const SordQuad x, const SordQuad y) static int sord_quad_compare(const void* x_ptr, const void* y_ptr, const void* user_data) { - const int* const ordering = (const int*)user_data; - const SordNode*const*const x = (const SordNode*const*)x_ptr; - const SordNode*const*const y = (const SordNode*const*)y_ptr; + const int* const ordering = (const int*)user_data; + const SordNode* const* const x = (const SordNode* const*)x_ptr; + const SordNode* const* const y = (const SordNode* const*)y_ptr; - for (int i = 0; i < TUP_LEN; ++i) { - const int idx = ordering[i]; - const int cmp = sord_node_compare(x[idx], y[idx]); - if (cmp) { - return cmp; - } - } + for (int i = 0; i < TUP_LEN; ++i) { + const int idx = ordering[i]; + const int cmp = sord_node_compare(x[idx], y[idx]); + if (cmp) { + return cmp; + } + } - return 0; + return 0; } static inline bool sord_iter_forward(SordIter* iter) { - if (!iter->skip_graphs) { - zix_btree_iter_increment(iter->cur); - return zix_btree_iter_is_end(iter->cur); - } + if (!iter->skip_graphs) { + zix_btree_iter_increment(iter->cur); + return zix_btree_iter_is_end(iter->cur); + } - SordNode** key = (SordNode**)zix_btree_get(iter->cur); - const SordQuad initial = { key[0], key[1], key[2], key[3] }; - zix_btree_iter_increment(iter->cur); - while (!zix_btree_iter_is_end(iter->cur)) { - key = (SordNode**)zix_btree_get(iter->cur); - for (int i = 0; i < 3; ++i) { - if (key[i] != initial[i]) { - return false; - } - } + SordNode** key = (SordNode**)zix_btree_get(iter->cur); + const SordQuad initial = {key[0], key[1], key[2], key[3]}; + zix_btree_iter_increment(iter->cur); + while (!zix_btree_iter_is_end(iter->cur)) { + key = (SordNode**)zix_btree_get(iter->cur); + for (int i = 0; i < 3; ++i) { + if (key[i] != initial[i]) { + return false; + } + } - zix_btree_iter_increment(iter->cur); - } + zix_btree_iter_increment(iter->cur); + } - return true; + return true; } /** @@ -381,15 +391,14 @@ sord_iter_forward(SordIter* iter) static inline bool sord_iter_seek_match(SordIter* iter) { - for (iter->end = true; - !zix_btree_iter_is_end(iter->cur); - sord_iter_forward(iter)) { - const SordNode** const key = (const SordNode**)zix_btree_get(iter->cur); - if (sord_quad_match_inline(key, iter->pat)) { - return (iter->end = false); - } - } - return true; + for (iter->end = true; !zix_btree_iter_is_end(iter->cur); + sord_iter_forward(iter)) { + const SordNode** const key = (const SordNode**)zix_btree_get(iter->cur); + if (sord_quad_match_inline(key, iter->pat)) { + return (iter->end = false); + } + } + return true; } /** @@ -400,178 +409,183 @@ sord_iter_seek_match(SordIter* iter) static inline bool sord_iter_seek_match_range(SordIter* iter) { - assert(!iter->end); + assert(!iter->end); - do { - const SordNode** key = (const SordNode**)zix_btree_get(iter->cur); + do { + const SordNode** key = (const SordNode**)zix_btree_get(iter->cur); - if (sord_quad_match_inline(key, iter->pat)) { - return false; // Found match - } + if (sord_quad_match_inline(key, iter->pat)) { + return false; // Found match + } - for (int i = 0; i < iter->n_prefix; ++i) { - const int idx = orderings[iter->order][i]; - if (!sord_id_match(key[idx], iter->pat[idx])) { - iter->end = true; // Reached end of valid range - return true; - } - } - } while (!sord_iter_forward(iter)); + for (int i = 0; i < iter->n_prefix; ++i) { + const int idx = orderings[iter->order][i]; + if (!sord_id_match(key[idx], iter->pat[idx])) { + iter->end = true; // Reached end of valid range + return true; + } + } + } while (!sord_iter_forward(iter)); - return (iter->end = true); // Reached end + return (iter->end = true); // Reached end } static SordIter* -sord_iter_new(const SordModel* sord, ZixBTreeIter* cur, const SordQuad pat, - SordOrder order, SearchMode mode, int n_prefix) -{ - SordIter* iter = (SordIter*)malloc(sizeof(SordIter)); - iter->sord = sord; - iter->cur = cur; - iter->order = order; - iter->mode = mode; - iter->n_prefix = n_prefix; - iter->end = false; - iter->skip_graphs = order < GSPO; - for (int i = 0; i < TUP_LEN; ++i) { - iter->pat[i] = pat[i]; - } - - switch (iter->mode) { - case ALL: - case SINGLE: - case RANGE: - assert( - sord_quad_match_inline((const SordNode**)zix_btree_get(iter->cur), - iter->pat)); - break; - case FILTER_RANGE: - sord_iter_seek_match_range(iter); - break; - case FILTER_ALL: - sord_iter_seek_match(iter); - break; - } +sord_iter_new(const SordModel* sord, + ZixBTreeIter* cur, + const SordQuad pat, + SordOrder order, + SearchMode mode, + int n_prefix) +{ + SordIter* iter = (SordIter*)malloc(sizeof(SordIter)); + iter->sord = sord; + iter->cur = cur; + iter->order = order; + iter->mode = mode; + iter->n_prefix = n_prefix; + iter->end = false; + iter->skip_graphs = order < GSPO; + for (int i = 0; i < TUP_LEN; ++i) { + iter->pat[i] = pat[i]; + } + + switch (iter->mode) { + case ALL: + case SINGLE: + case RANGE: + assert(sord_quad_match_inline((const SordNode**)zix_btree_get(iter->cur), + iter->pat)); + break; + case FILTER_RANGE: + sord_iter_seek_match_range(iter); + break; + case FILTER_ALL: + sord_iter_seek_match(iter); + break; + } #ifdef SORD_DEBUG_ITER - SordQuad value; - sord_iter_get(iter, value); - SORD_ITER_LOG("New %p pat=" TUP_FMT " cur=" TUP_FMT " end=%d skip=%d\n", - (void*)iter, TUP_FMT_ARGS(pat), TUP_FMT_ARGS(value), - iter->end, iter->skip_graphs); + SordQuad value; + sord_iter_get(iter, value); + SORD_ITER_LOG("New %p pat=" TUP_FMT " cur=" TUP_FMT " end=%d skip=%d\n", + (void*)iter, + TUP_FMT_ARGS(pat), + TUP_FMT_ARGS(value), + iter->end, + iter->skip_graphs); #endif - ++((SordModel*)sord)->n_iters; - return iter; + ++((SordModel*)sord)->n_iters; + return iter; } const SordModel* sord_iter_get_model(SordIter* iter) { - return iter->sord; + return iter->sord; } void sord_iter_get(const SordIter* iter, SordQuad tup) { - SordNode** key = (SordNode**)zix_btree_get(iter->cur); - for (int i = 0; i < TUP_LEN; ++i) { - tup[i] = key[i]; - } + SordNode** key = (SordNode**)zix_btree_get(iter->cur); + for (int i = 0; i < TUP_LEN; ++i) { + tup[i] = key[i]; + } } const SordNode* sord_iter_get_node(const SordIter* iter, SordQuadIndex index) { - return (!sord_iter_end(iter) - ? ((SordNode**)zix_btree_get(iter->cur))[index] - : NULL); + return (!sord_iter_end(iter) ? ((SordNode**)zix_btree_get(iter->cur))[index] + : NULL); } static bool sord_iter_scan_next(SordIter* iter) { - if (iter->end) { - return true; - } - - const SordNode** key; - if (!iter->end) { - switch (iter->mode) { - case ALL: - // At the end if the cursor is (assigned above) - break; - case SINGLE: - iter->end = true; - SORD_ITER_LOG("%p reached single end\n", (void*)iter); - break; - case RANGE: - SORD_ITER_LOG("%p range next\n", (void*)iter); - // At the end if the MSNs no longer match - key = (const SordNode**)zix_btree_get(iter->cur); - assert(key); - for (int i = 0; i < iter->n_prefix; ++i) { - const int idx = orderings[iter->order][i]; - if (!sord_id_match(key[idx], iter->pat[idx])) { - iter->end = true; - SORD_ITER_LOG("%p reached non-match end\n", (void*)iter); - break; - } - } - break; - case FILTER_RANGE: - // Seek forward to next match, stopping if prefix changes - sord_iter_seek_match_range(iter); - break; - case FILTER_ALL: - // Seek forward to next match - sord_iter_seek_match(iter); - break; - } - } else { - SORD_ITER_LOG("%p reached index end\n", (void*)iter); - } - - if (iter->end) { - SORD_ITER_LOG("%p Reached end\n", (void*)iter); - return true; - } else { + if (iter->end) { + return true; + } + + const SordNode** key; + if (!iter->end) { + switch (iter->mode) { + case ALL: + // At the end if the cursor is (assigned above) + break; + case SINGLE: + iter->end = true; + SORD_ITER_LOG("%p reached single end\n", (void*)iter); + break; + case RANGE: + SORD_ITER_LOG("%p range next\n", (void*)iter); + // At the end if the MSNs no longer match + key = (const SordNode**)zix_btree_get(iter->cur); + assert(key); + for (int i = 0; i < iter->n_prefix; ++i) { + const int idx = orderings[iter->order][i]; + if (!sord_id_match(key[idx], iter->pat[idx])) { + iter->end = true; + SORD_ITER_LOG("%p reached non-match end\n", (void*)iter); + break; + } + } + break; + case FILTER_RANGE: + // Seek forward to next match, stopping if prefix changes + sord_iter_seek_match_range(iter); + break; + case FILTER_ALL: + // Seek forward to next match + sord_iter_seek_match(iter); + break; + } + } else { + SORD_ITER_LOG("%p reached index end\n", (void*)iter); + } + + if (iter->end) { + SORD_ITER_LOG("%p Reached end\n", (void*)iter); + return true; + } else { #ifdef SORD_DEBUG_ITER - SordQuad tup; - sord_iter_get(iter, tup); - SORD_ITER_LOG("%p Increment to " TUP_FMT "\n", - (void*)iter, TUP_FMT_ARGS(tup)); + SordQuad tup; + sord_iter_get(iter, tup); + SORD_ITER_LOG( + "%p Increment to " TUP_FMT "\n", (void*)iter, TUP_FMT_ARGS(tup)); #endif - return false; - } + return false; + } } bool sord_iter_next(SordIter* iter) { - if (iter->end) { - return true; - } + if (iter->end) { + return true; + } - iter->end = sord_iter_forward(iter); - return sord_iter_scan_next(iter); + iter->end = sord_iter_forward(iter); + return sord_iter_scan_next(iter); } bool sord_iter_end(const SordIter* iter) { - return !iter || iter->end; + return !iter || iter->end; } void sord_iter_free(SordIter* iter) { - SORD_ITER_LOG("%p Free\n", (void*)iter); - if (iter) { - --((SordModel*)iter->sord)->n_iters; - zix_btree_iter_free(iter->cur); - free(iter); - } + SORD_ITER_LOG("%p Free\n", (void*)iter); + if (iter) { + --((SordModel*)iter->sord)->n_iters; + zix_btree_iter_free(iter->cur); + free(iter); + } } /** @@ -582,12 +596,12 @@ sord_iter_free(SordIter* iter) static inline bool sord_has_index(SordModel* model, SordOrder* order, int* n_prefix, bool graphs) { - if (graphs) { - *order = (SordOrder)(*order + GSPO); - *n_prefix += 1; - } + if (graphs) { + *order = (SordOrder)(*order + GSPO); + *n_prefix += 1; + } - return model->indices[*order]; + return model->indices[*order]; } /** @@ -603,284 +617,286 @@ sord_best_index(SordModel* sord, SearchMode* mode, int* n_prefix) { - const bool graph_search = (pat[TUP_G] != 0); + const bool graph_search = (pat[TUP_G] != 0); - const unsigned sig - = (pat[0] ? 1 : 0) * 0x100 - + (pat[1] ? 1 : 0) * 0x010 - + (pat[2] ? 1 : 0) * 0x001; + const unsigned sig = (pat[0] ? 1 : 0) * 0x100 + (pat[1] ? 1 : 0) * 0x010 + + (pat[2] ? 1 : 0) * 0x001; - SordOrder good[2] = { (SordOrder)-1, (SordOrder)-1 }; + SordOrder good[2] = {(SordOrder)-1, (SordOrder)-1}; #define PAT_CASE(sig, m, g0, g1, np) \ - case sig: \ - *mode = m; \ - good[0] = g0; \ - good[1] = g1; \ - *n_prefix = np; \ - break - - // Good orderings that don't require filtering - *mode = RANGE; - *n_prefix = 0; - switch (sig) { - case 0x000: - assert(graph_search); - *mode = RANGE; - *n_prefix = 1; - return DEFAULT_GRAPH_ORDER; - case 0x111: - *mode = SINGLE; - 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); - } - - if (*mode == RANGE) { - if (sord_has_index(sord, &good[0], n_prefix, graph_search)) { - return good[0]; - } else if (sord_has_index(sord, &good[1], n_prefix, graph_search)) { - return good[1]; - } - } - - // 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); - // SPO is always present, so 0x110 is never reached here - default: break; - } - - if (*mode == FILTER_RANGE) { - if (sord_has_index(sord, &good[0], n_prefix, graph_search)) { - return good[0]; - } else if (sord_has_index(sord, &good[1], n_prefix, graph_search)) { - return good[1]; - } - } - - if (graph_search) { - *mode = FILTER_RANGE; - *n_prefix = 1; - return DEFAULT_GRAPH_ORDER; - } else { - *mode = FILTER_ALL; - return DEFAULT_ORDER; - } + case sig: \ + *mode = m; \ + good[0] = g0; \ + good[1] = g1; \ + *n_prefix = np; \ + break + + // Good orderings that don't require filtering + *mode = RANGE; + *n_prefix = 0; + switch (sig) { + case 0x000: + assert(graph_search); + *mode = RANGE; + *n_prefix = 1; + return DEFAULT_GRAPH_ORDER; + case 0x111: + *mode = SINGLE; + 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); + } + + if (*mode == RANGE) { + if (sord_has_index(sord, &good[0], n_prefix, graph_search)) { + return good[0]; + } else if (sord_has_index(sord, &good[1], n_prefix, graph_search)) { + return good[1]; + } + } + + // 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); + // SPO is always present, so 0x110 is never reached here + default: + break; + } + + if (*mode == FILTER_RANGE) { + if (sord_has_index(sord, &good[0], n_prefix, graph_search)) { + return good[0]; + } else if (sord_has_index(sord, &good[1], n_prefix, graph_search)) { + return good[1]; + } + } + + if (graph_search) { + *mode = FILTER_RANGE; + *n_prefix = 1; + return DEFAULT_GRAPH_ORDER; + } else { + *mode = FILTER_ALL; + return DEFAULT_ORDER; + } } SordModel* sord_new(SordWorld* world, unsigned indices, bool graphs) { - SordModel* model = (SordModel*)malloc(sizeof(struct SordModelImpl)); - model->world = world; - model->n_quads = 0; - model->n_iters = 0; - - for (unsigned i = 0; i < (NUM_ORDERS / 2); ++i) { - const int* const ordering = orderings[i]; - const int* const g_ordering = orderings[i + (NUM_ORDERS / 2)]; - - if (indices & (1 << i)) { - model->indices[i] = zix_btree_new( - sord_quad_compare, (void*)ordering, NULL); - if (graphs) { - model->indices[i + (NUM_ORDERS / 2)] = zix_btree_new( - sord_quad_compare, (void*)g_ordering, NULL); - } else { - model->indices[i + (NUM_ORDERS / 2)] = NULL; - } - } else { - model->indices[i] = NULL; - model->indices[i + (NUM_ORDERS / 2)] = NULL; - } - } - - if (!model->indices[DEFAULT_ORDER]) { - model->indices[DEFAULT_ORDER] = zix_btree_new( - sord_quad_compare, (void*)orderings[DEFAULT_ORDER], NULL); - } - if (graphs && !model->indices[DEFAULT_GRAPH_ORDER]) { - model->indices[DEFAULT_GRAPH_ORDER] = zix_btree_new( - sord_quad_compare, (void*)orderings[DEFAULT_GRAPH_ORDER], NULL); - } - - return model; + SordModel* model = (SordModel*)malloc(sizeof(struct SordModelImpl)); + model->world = world; + model->n_quads = 0; + model->n_iters = 0; + + for (unsigned i = 0; i < (NUM_ORDERS / 2); ++i) { + const int* const ordering = orderings[i]; + const int* const g_ordering = orderings[i + (NUM_ORDERS / 2)]; + + if (indices & (1 << i)) { + model->indices[i] = + zix_btree_new(sord_quad_compare, (void*)ordering, NULL); + if (graphs) { + model->indices[i + (NUM_ORDERS / 2)] = + zix_btree_new(sord_quad_compare, (void*)g_ordering, NULL); + } else { + model->indices[i + (NUM_ORDERS / 2)] = NULL; + } + } else { + model->indices[i] = NULL; + model->indices[i + (NUM_ORDERS / 2)] = NULL; + } + } + + if (!model->indices[DEFAULT_ORDER]) { + model->indices[DEFAULT_ORDER] = + zix_btree_new(sord_quad_compare, (void*)orderings[DEFAULT_ORDER], NULL); + } + if (graphs && !model->indices[DEFAULT_GRAPH_ORDER]) { + model->indices[DEFAULT_GRAPH_ORDER] = zix_btree_new( + sord_quad_compare, (void*)orderings[DEFAULT_GRAPH_ORDER], NULL); + } + + return model; } static void sord_node_free_internal(SordWorld* world, SordNode* node) { - assert(node->refs == 0); + assert(node->refs == 0); - // If you hit this, the world has probably been destroyed too early - assert(world); + // If you hit this, the world has probably been destroyed too early + assert(world); - // Cache pointer to buffer to free after node removal and destruction - const uint8_t* const buf = node->node.buf; + // Cache pointer to buffer to free after node removal and destruction + const uint8_t* const buf = node->node.buf; - // Remove node from hash (which frees the node) - if (zix_hash_remove(world->nodes, node)) { - error(world, SERD_ERR_INTERNAL, "failed to remove node from hash\n"); - } + // Remove node from hash (which frees the node) + if (zix_hash_remove(world->nodes, node)) { + error(world, SERD_ERR_INTERNAL, "failed to remove node from hash\n"); + } - // Free buffer - free((uint8_t*)buf); + // Free buffer + free((uint8_t*)buf); } static void sord_add_quad_ref(SordModel* model, const SordNode* node, SordQuadIndex i) { - if (node) { - assert(node->refs > 0); - ++((SordNode*)node)->refs; - if (node->node.type != SERD_LITERAL && i == SORD_OBJECT) { - ++((SordNode*)node)->meta.res.refs_as_obj; - } - } + if (node) { + assert(node->refs > 0); + ++((SordNode*)node)->refs; + if (node->node.type != SERD_LITERAL && i == SORD_OBJECT) { + ++((SordNode*)node)->meta.res.refs_as_obj; + } + } } static void sord_drop_quad_ref(SordModel* model, const SordNode* node, SordQuadIndex i) { - if (!node) { - return; - } + if (!node) { + return; + } - assert(node->refs > 0); - if (node->node.type != SERD_LITERAL && i == SORD_OBJECT) { - assert(node->meta.res.refs_as_obj > 0); - --((SordNode*)node)->meta.res.refs_as_obj; - } - if (--((SordNode*)node)->refs == 0) { - sord_node_free_internal(sord_get_world(model), (SordNode*)node); - } + assert(node->refs > 0); + if (node->node.type != SERD_LITERAL && i == SORD_OBJECT) { + assert(node->meta.res.refs_as_obj > 0); + --((SordNode*)node)->meta.res.refs_as_obj; + } + if (--((SordNode*)node)->refs == 0) { + sord_node_free_internal(sord_get_world(model), (SordNode*)node); + } } void sord_free(SordModel* model) { - if (!model) { - return; - } - - // Free nodes - SordQuad tup; - SordIter* i = sord_begin(model); - for (; !sord_iter_end(i); sord_iter_next(i)) { - sord_iter_get(i, tup); - for (int t = 0; t < TUP_LEN; ++t) { - sord_drop_quad_ref(model, tup[t], (SordQuadIndex)t); - } - } - sord_iter_free(i); - - // Free quads - ZixBTreeIter* t = zix_btree_begin(model->indices[DEFAULT_ORDER]); - for (; !zix_btree_iter_is_end(t); zix_btree_iter_increment(t)) { - free(zix_btree_get(t)); - } - zix_btree_iter_free(t); - - // Free indices - for (unsigned o = 0; o < NUM_ORDERS; ++o) { - if (model->indices[o]) { - zix_btree_free(model->indices[o]); - } - } - - free(model); + if (!model) { + return; + } + + // Free nodes + SordQuad tup; + SordIter* i = sord_begin(model); + for (; !sord_iter_end(i); sord_iter_next(i)) { + sord_iter_get(i, tup); + for (int t = 0; t < TUP_LEN; ++t) { + sord_drop_quad_ref(model, tup[t], (SordQuadIndex)t); + } + } + sord_iter_free(i); + + // Free quads + ZixBTreeIter* t = zix_btree_begin(model->indices[DEFAULT_ORDER]); + for (; !zix_btree_iter_is_end(t); zix_btree_iter_increment(t)) { + free(zix_btree_get(t)); + } + zix_btree_iter_free(t); + + // Free indices + for (unsigned o = 0; o < NUM_ORDERS; ++o) { + if (model->indices[o]) { + zix_btree_free(model->indices[o]); + } + } + + free(model); } SordWorld* sord_get_world(SordModel* model) { - return model->world; + return model->world; } size_t sord_num_quads(const SordModel* model) { - return model->n_quads; + return model->n_quads; } size_t sord_num_nodes(const SordWorld* world) { - return zix_hash_size(world->nodes); + return zix_hash_size(world->nodes); } SordIter* sord_begin(const SordModel* model) { - if (sord_num_quads(model) == 0) { - return NULL; - } else { - ZixBTreeIter* cur = zix_btree_begin(model->indices[DEFAULT_ORDER]); - SordQuad pat = { 0, 0, 0, 0 }; - return sord_iter_new(model, cur, pat, DEFAULT_ORDER, ALL, 0); - } + if (sord_num_quads(model) == 0) { + return NULL; + } else { + ZixBTreeIter* cur = zix_btree_begin(model->indices[DEFAULT_ORDER]); + SordQuad pat = {0, 0, 0, 0}; + return sord_iter_new(model, cur, pat, DEFAULT_ORDER, ALL, 0); + } } SordIter* sord_find(SordModel* model, const SordQuad pat) { - if (!pat[0] && !pat[1] && !pat[2] && !pat[3]) { - return sord_begin(model); - } - - SearchMode mode; - int n_prefix; - const SordOrder index_order = sord_best_index(model, pat, &mode, &n_prefix); - - SORD_FIND_LOG("Find " TUP_FMT " index=%s mode=%u n_prefix=%d\n", - TUP_FMT_ARGS(pat), order_names[index_order], mode, n_prefix); - - if (pat[0] && pat[1] && pat[2] && pat[3]) { - mode = SINGLE; // No duplicate quads (Sord is a set) - } - - ZixBTree* const db = model->indices[index_order]; - ZixBTreeIter* cur = NULL; - - if (mode == FILTER_ALL) { - // No prefix shared with an index at all, linear search (worst case) - cur = zix_btree_begin(db); - } else if (mode == FILTER_RANGE) { - /* Some prefix, but filtering still required. Build a search pattern - with only the prefix to find the lower bound in log time. */ - SordQuad prefix_pat = { NULL, NULL, NULL, NULL }; - const int* const ordering = orderings[index_order]; - for (int i = 0; i < n_prefix; ++i) { - prefix_pat[ordering[i]] = pat[ordering[i]]; - } - zix_btree_lower_bound(db, prefix_pat, &cur); - } else { - // Ideal case, pattern matches an index with no filtering required - zix_btree_lower_bound(db, pat, &cur); - } - - if (zix_btree_iter_is_end(cur)) { - SORD_FIND_LOG("No match found\n"); - zix_btree_iter_free(cur); - return NULL; - } - const SordNode** const key = (const SordNode**)zix_btree_get(cur); - if (!key || ( (mode == RANGE || mode == SINGLE) - && !sord_quad_match_inline(pat, key) )) { - SORD_FIND_LOG("No match found\n"); - zix_btree_iter_free(cur); - return NULL; - } - - return sord_iter_new(model, cur, pat, index_order, mode, n_prefix); + if (!pat[0] && !pat[1] && !pat[2] && !pat[3]) { + return sord_begin(model); + } + + SearchMode mode; + int n_prefix; + const SordOrder index_order = sord_best_index(model, pat, &mode, &n_prefix); + + SORD_FIND_LOG("Find " TUP_FMT " index=%s mode=%u n_prefix=%d\n", + TUP_FMT_ARGS(pat), + order_names[index_order], + mode, + n_prefix); + + if (pat[0] && pat[1] && pat[2] && pat[3]) { + mode = SINGLE; // No duplicate quads (Sord is a set) + } + + ZixBTree* const db = model->indices[index_order]; + ZixBTreeIter* cur = NULL; + + if (mode == FILTER_ALL) { + // No prefix shared with an index at all, linear search (worst case) + cur = zix_btree_begin(db); + } else if (mode == FILTER_RANGE) { + /* Some prefix, but filtering still required. Build a search pattern + with only the prefix to find the lower bound in log time. */ + SordQuad prefix_pat = {NULL, NULL, NULL, NULL}; + const int* const ordering = orderings[index_order]; + for (int i = 0; i < n_prefix; ++i) { + prefix_pat[ordering[i]] = pat[ordering[i]]; + } + zix_btree_lower_bound(db, prefix_pat, &cur); + } else { + // Ideal case, pattern matches an index with no filtering required + zix_btree_lower_bound(db, pat, &cur); + } + + if (zix_btree_iter_is_end(cur)) { + SORD_FIND_LOG("No match found\n"); + zix_btree_iter_free(cur); + return NULL; + } + const SordNode** const key = (const SordNode**)zix_btree_get(cur); + if (!key || ((mode == RANGE || mode == SINGLE) && + !sord_quad_match_inline(pat, key))) { + SORD_FIND_LOG("No match found\n"); + zix_btree_iter_free(cur); + return NULL; + } + + return sord_iter_new(model, cur, pat, index_order, mode, n_prefix); } SordIter* @@ -890,8 +906,8 @@ sord_search(SordModel* model, const SordNode* o, const SordNode* g) { - SordQuad pat = { s, p, o, g }; - return sord_find(model, pat); + SordQuad pat = {s, p, o, g}; + return sord_find(model, pat); } SordNode* @@ -901,22 +917,22 @@ sord_get(SordModel* model, const SordNode* o, const SordNode* g) { - if ((bool)s + (bool)p + (bool)o != 2) { - return NULL; - } + if ((bool)s + (bool)p + (bool)o != 2) { + return NULL; + } - SordIter* i = sord_search(model, s, p, o, g); - SordNode* ret = NULL; - if (!s) { - ret = sord_node_copy(sord_iter_get_node(i, SORD_SUBJECT)); - } else if (!p) { - ret = sord_node_copy(sord_iter_get_node(i, SORD_PREDICATE)); - } else if (!o) { - ret = sord_node_copy(sord_iter_get_node(i, SORD_OBJECT)); - } + SordIter* i = sord_search(model, s, p, o, g); + SordNode* ret = NULL; + if (!s) { + ret = sord_node_copy(sord_iter_get_node(i, SORD_SUBJECT)); + } else if (!p) { + ret = sord_node_copy(sord_iter_get_node(i, SORD_PREDICATE)); + } else if (!o) { + ret = sord_node_copy(sord_iter_get_node(i, SORD_OBJECT)); + } - sord_iter_free(i); - return ret; + sord_iter_free(i); + return ret; } bool @@ -926,8 +942,8 @@ sord_ask(SordModel* model, const SordNode* o, const SordNode* g) { - SordQuad pat = { s, p, o, g }; - return sord_contains(model, pat); + SordQuad pat = {s, p, o, g}; + return sord_contains(model, pat); } uint64_t @@ -937,57 +953,57 @@ sord_count(SordModel* model, const SordNode* o, const SordNode* g) { - SordIter* i = sord_search(model, s, p, o, g); - uint64_t n = 0; - for (; !sord_iter_end(i); sord_iter_next(i)) { - ++n; - } - sord_iter_free(i); - return n; + SordIter* i = sord_search(model, s, p, o, g); + uint64_t n = 0; + for (; !sord_iter_end(i); sord_iter_next(i)) { + ++n; + } + sord_iter_free(i); + return n; } bool sord_contains(SordModel* model, const SordQuad pat) { - SordIter* iter = sord_find(model, pat); - bool ret = (iter != NULL); - sord_iter_free(iter); - return ret; + SordIter* iter = sord_find(model, pat); + bool ret = (iter != NULL); + sord_iter_free(iter); + return ret; } static uint8_t* sord_strndup(const uint8_t* str, size_t len) { - uint8_t* dup = (uint8_t*)malloc(len + 1); - memcpy(dup, str, len + 1); - return dup; + uint8_t* dup = (uint8_t*)malloc(len + 1); + memcpy(dup, str, len + 1); + return dup; } SordNodeType sord_node_get_type(const SordNode* node) { - switch (node->node.type) { - case SERD_URI: - return SORD_URI; - case SERD_BLANK: - return SORD_BLANK; - default: - return SORD_LITERAL; - } - SORD_UNREACHABLE(); + switch (node->node.type) { + case SERD_URI: + return SORD_URI; + case SERD_BLANK: + return SORD_BLANK; + default: + return SORD_LITERAL; + } + SORD_UNREACHABLE(); } const uint8_t* sord_node_get_string(const SordNode* node) { - return node->node.buf; + return node->node.buf; } const uint8_t* sord_node_get_string_counted(const SordNode* node, size_t* bytes) { - *bytes = node->node.n_bytes; - return node->node.buf; + *bytes = node->node.n_bytes; + return node->node.buf; } const uint8_t* @@ -995,91 +1011,91 @@ sord_node_get_string_measured(const SordNode* node, size_t* bytes, size_t* chars) { - *bytes = node->node.n_bytes; - *chars = node->node.n_chars; - return node->node.buf; + *bytes = node->node.n_bytes; + *chars = node->node.n_chars; + return node->node.buf; } const char* sord_node_get_language(const SordNode* node) { - if (node->node.type != SERD_LITERAL || !node->meta.lit.lang[0]) { - return NULL; - } - return node->meta.lit.lang; + if (node->node.type != SERD_LITERAL || !node->meta.lit.lang[0]) { + return NULL; + } + return node->meta.lit.lang; } SordNode* sord_node_get_datatype(const SordNode* node) { - return (node->node.type == SERD_LITERAL) ? node->meta.lit.datatype : NULL; + return (node->node.type == SERD_LITERAL) ? node->meta.lit.datatype : NULL; } SerdNodeFlags sord_node_get_flags(const SordNode* node) { - return node->node.flags; + return node->node.flags; } bool sord_node_is_inline_object(const SordNode* node) { - return (node->node.type == SERD_BLANK) && (node->meta.res.refs_as_obj == 1); + return (node->node.type == SERD_BLANK) && (node->meta.res.refs_as_obj == 1); } static SordNode* sord_insert_node(SordWorld* world, const SordNode* key, bool copy) { - SordNode* node = NULL; - ZixStatus st = zix_hash_insert(world->nodes, key, (void**)&node); - switch (st) { - case ZIX_STATUS_EXISTS: - ++node->refs; - break; - case ZIX_STATUS_SUCCESS: - assert(node->refs == 1); - if (copy) { - node->node.buf = sord_strndup(node->node.buf, node->node.n_bytes); - } - if (node->node.type == SERD_LITERAL) { - node->meta.lit.datatype = sord_node_copy(node->meta.lit.datatype); - } - return node; - default: - error(world, SERD_ERR_INTERNAL, - "error inserting node `%s'\n", key->node.buf); - } - - if (!copy) { - // Free the buffer we would have copied if a new node was created - free((uint8_t*)key->node.buf); - } - - return node; + SordNode* node = NULL; + ZixStatus st = zix_hash_insert(world->nodes, key, (void**)&node); + switch (st) { + case ZIX_STATUS_EXISTS: + ++node->refs; + break; + case ZIX_STATUS_SUCCESS: + assert(node->refs == 1); + if (copy) { + node->node.buf = sord_strndup(node->node.buf, node->node.n_bytes); + } + if (node->node.type == SERD_LITERAL) { + node->meta.lit.datatype = sord_node_copy(node->meta.lit.datatype); + } + return node; + default: + error( + world, SERD_ERR_INTERNAL, "error inserting node `%s'\n", key->node.buf); + } + + if (!copy) { + // Free the buffer we would have copied if a new node was created + free((uint8_t*)key->node.buf); + } + + return node; } static SordNode* -sord_new_uri_counted(SordWorld* world, const uint8_t* str, - size_t n_bytes, size_t n_chars, bool copy) +sord_new_uri_counted(SordWorld* world, + const uint8_t* str, + size_t n_bytes, + size_t n_chars, + bool copy) { - if (!serd_uri_string_has_scheme(str)) { - error(world, SERD_ERR_BAD_ARG, - "attempt to map invalid URI `%s'\n", str); - return NULL; // Can't intern relative URIs - } + if (!serd_uri_string_has_scheme(str)) { + error(world, SERD_ERR_BAD_ARG, "attempt to map invalid URI `%s'\n", str); + return NULL; // Can't intern relative URIs + } - const SordNode key = { - { str, n_bytes, n_chars, 0, SERD_URI }, 1, { { 0 } } - }; + const SordNode key = {{str, n_bytes, n_chars, 0, SERD_URI}, 1, {{0}}}; - return sord_insert_node(world, &key, copy); + return sord_insert_node(world, &key, copy); } SordNode* sord_new_uri(SordWorld* world, const uint8_t* uri) { - const SerdNode node = serd_node_from_string(SERD_URI, uri); - return sord_new_uri_counted(world, uri, node.n_bytes, node.n_chars, true); + const SerdNode node = serd_node_from_string(SERD_URI, uri); + return sord_new_uri_counted(world, uri, node.n_bytes, node.n_chars, true); } SordNode* @@ -1087,36 +1103,36 @@ sord_new_relative_uri(SordWorld* world, const uint8_t* uri, const uint8_t* base_uri) { - if (serd_uri_string_has_scheme(uri)) { - return sord_new_uri(world, uri); - } - SerdURI buri = SERD_URI_NULL; - SerdNode base = serd_node_new_uri_from_string(base_uri, NULL, &buri); - SerdNode node = serd_node_new_uri_from_string(uri, &buri, NULL); + if (serd_uri_string_has_scheme(uri)) { + return sord_new_uri(world, uri); + } + SerdURI buri = SERD_URI_NULL; + SerdNode base = serd_node_new_uri_from_string(base_uri, NULL, &buri); + SerdNode node = serd_node_new_uri_from_string(uri, &buri, NULL); - SordNode* ret = sord_new_uri_counted( - world, node.buf, node.n_bytes, node.n_chars, false); + SordNode* ret = + sord_new_uri_counted(world, node.buf, node.n_bytes, node.n_chars, false); - serd_node_free(&base); - return ret; + serd_node_free(&base); + return ret; } static SordNode* -sord_new_blank_counted(SordWorld* world, const uint8_t* str, - size_t n_bytes, size_t n_chars) +sord_new_blank_counted(SordWorld* world, + const uint8_t* str, + size_t n_bytes, + size_t n_chars) { - const SordNode key = { - { str, n_bytes, n_chars, 0, SERD_BLANK }, 1, { { 0 } } - }; + const SordNode key = {{str, n_bytes, n_chars, 0, SERD_BLANK}, 1, {{0}}}; - return sord_insert_node(world, &key, true); + return sord_insert_node(world, &key, true); } SordNode* sord_new_blank(SordWorld* world, const uint8_t* str) { - const SerdNode node = serd_node_from_string(SERD_URI, str); - return sord_new_blank_counted(world, str, node.n_bytes, node.n_chars); + const SerdNode node = serd_node_from_string(SERD_URI, str); + return sord_new_blank_counted(world, str, node.n_bytes, node.n_chars); } static SordNode* @@ -1128,28 +1144,27 @@ sord_new_literal_counted(SordWorld* world, SerdNodeFlags flags, const char* lang) { - SordNode key = { - { str, n_bytes, n_chars, flags, SERD_LITERAL }, 1, { { 0 } } - }; - key.meta.lit.datatype = sord_node_copy(datatype); - memset(key.meta.lit.lang, 0, sizeof(key.meta.lit.lang)); - if (lang) { - strncpy(key.meta.lit.lang, lang, sizeof(key.meta.lit.lang) - 1); - } + SordNode key = {{str, n_bytes, n_chars, flags, SERD_LITERAL}, 1, {{0}}}; + key.meta.lit.datatype = sord_node_copy(datatype); + memset(key.meta.lit.lang, 0, sizeof(key.meta.lit.lang)); + if (lang) { + strncpy(key.meta.lit.lang, lang, sizeof(key.meta.lit.lang) - 1); + } - return sord_insert_node(world, &key, true); + return sord_insert_node(world, &key, true); } SordNode* -sord_new_literal(SordWorld* world, SordNode* datatype, - const uint8_t* str, const char* lang) +sord_new_literal(SordWorld* world, + SordNode* datatype, + const uint8_t* str, + const char* lang) { - SerdNodeFlags flags = 0; - size_t n_bytes = 0; - size_t n_chars = serd_strlen(str, &n_bytes, &flags); - return sord_new_literal_counted(world, datatype, - str, n_bytes, n_chars, flags, - lang); + SerdNodeFlags flags = 0; + size_t n_bytes = 0; + size_t n_chars = serd_strlen(str, &n_bytes, &flags); + return sord_new_literal_counted( + world, datatype, str, n_bytes, n_chars, flags, lang); } SordNode* @@ -1159,195 +1174,195 @@ sord_node_from_serd_node(SordWorld* world, const SerdNode* datatype, const SerdNode* lang) { - if (!node) { - return NULL; - } - - SordNode* datatype_node = NULL; - SordNode* ret = NULL; - switch (node->type) { - case SERD_NOTHING: - return NULL; - case SERD_LITERAL: - datatype_node = sord_node_from_serd_node( - world, env, datatype, NULL, NULL); - ret = sord_new_literal_counted( - world, - datatype_node, - node->buf, - node->n_bytes, - node->n_chars, - node->flags, - lang ? (const char*)lang->buf : NULL); - sord_node_free(world, datatype_node); - return ret; - case SERD_URI: - if (serd_uri_string_has_scheme(node->buf)) { - return sord_new_uri_counted( - world, node->buf, node->n_bytes, node->n_chars, true); - } else { - SerdURI base_uri; - serd_env_get_base_uri(env, &base_uri); - SerdURI abs_uri; - SerdNode abs_uri_node = serd_node_new_uri_from_node( - node, &base_uri, &abs_uri); - ret = sord_new_uri_counted(world, - abs_uri_node.buf, - abs_uri_node.n_bytes, - abs_uri_node.n_chars, - true); - serd_node_free(&abs_uri_node); - return ret; - } - case SERD_CURIE: { - SerdChunk uri_prefix; - SerdChunk uri_suffix; - if (serd_env_expand(env, node, &uri_prefix, &uri_suffix)) { - error(world, SERD_ERR_BAD_CURIE, - "failed to expand CURIE `%s'\n", node->buf); - return NULL; - } - const size_t uri_len = uri_prefix.len + uri_suffix.len; - uint8_t* buf = (uint8_t*)malloc(uri_len + 1); - memcpy(buf, uri_prefix.buf, uri_prefix.len); - memcpy(buf + uri_prefix.len, uri_suffix.buf, uri_suffix.len); - buf[uri_len] = '\0'; - ret = sord_new_uri_counted( - world, buf, uri_len, serd_strlen(buf, NULL, NULL), false); - return ret; - } - case SERD_BLANK: - return sord_new_blank_counted( - world, node->buf, node->n_bytes, node->n_chars); - } - return NULL; + if (!node) { + return NULL; + } + + SordNode* datatype_node = NULL; + SordNode* ret = NULL; + switch (node->type) { + case SERD_NOTHING: + return NULL; + case SERD_LITERAL: + datatype_node = sord_node_from_serd_node(world, env, datatype, NULL, NULL); + ret = sord_new_literal_counted(world, + datatype_node, + node->buf, + node->n_bytes, + node->n_chars, + node->flags, + lang ? (const char*)lang->buf : NULL); + sord_node_free(world, datatype_node); + return ret; + case SERD_URI: + if (serd_uri_string_has_scheme(node->buf)) { + return sord_new_uri_counted( + world, node->buf, node->n_bytes, node->n_chars, true); + } else { + SerdURI base_uri; + serd_env_get_base_uri(env, &base_uri); + SerdURI abs_uri; + SerdNode abs_uri_node = + serd_node_new_uri_from_node(node, &base_uri, &abs_uri); + ret = sord_new_uri_counted(world, + abs_uri_node.buf, + abs_uri_node.n_bytes, + abs_uri_node.n_chars, + true); + serd_node_free(&abs_uri_node); + return ret; + } + case SERD_CURIE: { + SerdChunk uri_prefix; + SerdChunk uri_suffix; + if (serd_env_expand(env, node, &uri_prefix, &uri_suffix)) { + error( + world, SERD_ERR_BAD_CURIE, "failed to expand CURIE `%s'\n", node->buf); + return NULL; + } + const size_t uri_len = uri_prefix.len + uri_suffix.len; + uint8_t* buf = (uint8_t*)malloc(uri_len + 1); + memcpy(buf, uri_prefix.buf, uri_prefix.len); + memcpy(buf + uri_prefix.len, uri_suffix.buf, uri_suffix.len); + buf[uri_len] = '\0'; + ret = sord_new_uri_counted( + world, buf, uri_len, serd_strlen(buf, NULL, NULL), false); + return ret; + } + case SERD_BLANK: + return sord_new_blank_counted( + world, node->buf, node->n_bytes, node->n_chars); + } + return NULL; } const SerdNode* sord_node_to_serd_node(const SordNode* node) { - return node ? &node->node : &SERD_NODE_NULL; + return node ? &node->node : &SERD_NODE_NULL; } void sord_node_free(SordWorld* world, SordNode* node) { - if (!node) { - return; - } else if (node->refs == 0) { - error(world, SERD_ERR_BAD_ARG, "attempt to free garbage node\n"); - } else if (--node->refs == 0) { - sord_node_free_internal(world, node); - } + if (!node) { + return; + } else if (node->refs == 0) { + error(world, SERD_ERR_BAD_ARG, "attempt to free garbage node\n"); + } else if (--node->refs == 0) { + sord_node_free_internal(world, node); + } } SordNode* sord_node_copy(const SordNode* node) { - SordNode* copy = (SordNode*)node; - if (copy) { - ++copy->refs; - } - return copy; + SordNode* copy = (SordNode*)node; + if (copy) { + ++copy->refs; + } + return copy; } static inline bool sord_add_to_index(SordModel* model, const SordNode** tup, SordOrder order) { - return !zix_btree_insert(model->indices[order], tup); + return !zix_btree_insert(model->indices[order], tup); } bool sord_add(SordModel* model, const SordQuad tup) { - SORD_WRITE_LOG("Add " TUP_FMT "\n", TUP_FMT_ARGS(tup)); - if (!tup[0] || !tup[1] || !tup[2]) { - error(model->world, SERD_ERR_BAD_ARG, - "attempt to add quad with NULL field\n"); - return false; - } else if (model->n_iters > 0) { - error(model->world, SERD_ERR_BAD_ARG, "added tuple during iteration\n"); - } + SORD_WRITE_LOG("Add " TUP_FMT "\n", TUP_FMT_ARGS(tup)); + if (!tup[0] || !tup[1] || !tup[2]) { + error( + model->world, SERD_ERR_BAD_ARG, "attempt to add quad with NULL field\n"); + return false; + } else if (model->n_iters > 0) { + error(model->world, SERD_ERR_BAD_ARG, "added tuple during iteration\n"); + } - const SordNode** quad = (const SordNode**)malloc(sizeof(SordQuad)); - memcpy(quad, tup, sizeof(SordQuad)); + const SordNode** quad = (const SordNode**)malloc(sizeof(SordQuad)); + memcpy(quad, tup, sizeof(SordQuad)); - for (unsigned i = 0; i < NUM_ORDERS; ++i) { - if (model->indices[i] && (i < GSPO || tup[3])) { - if (!sord_add_to_index(model, quad, (SordOrder)i)) { - assert(i == 0); // Assuming index coherency - free(quad); - return false; // Quad already stored, do nothing - } - } - } + for (unsigned i = 0; i < NUM_ORDERS; ++i) { + if (model->indices[i] && (i < GSPO || tup[3])) { + if (!sord_add_to_index(model, quad, (SordOrder)i)) { + assert(i == 0); // Assuming index coherency + free(quad); + return false; // Quad already stored, do nothing + } + } + } - for (int i = 0; i < TUP_LEN; ++i) { - sord_add_quad_ref(model, tup[i], (SordQuadIndex)i); - } + for (int i = 0; i < TUP_LEN; ++i) { + sord_add_quad_ref(model, tup[i], (SordQuadIndex)i); + } - ++model->n_quads; - return true; + ++model->n_quads; + return true; } void sord_remove(SordModel* model, const SordQuad tup) { - SORD_WRITE_LOG("Remove " TUP_FMT "\n", TUP_FMT_ARGS(tup)); - if (model->n_iters > 0) { - error(model->world, SERD_ERR_BAD_ARG, "remove with iterator\n"); - } + SORD_WRITE_LOG("Remove " TUP_FMT "\n", TUP_FMT_ARGS(tup)); + if (model->n_iters > 0) { + error(model->world, SERD_ERR_BAD_ARG, "remove with iterator\n"); + } - SordNode* quad = NULL; - for (unsigned i = 0; i < NUM_ORDERS; ++i) { - if (model->indices[i] && (i < GSPO || tup[3])) { - if (zix_btree_remove(model->indices[i], tup, (void**)&quad, NULL)) { - assert(i == 0); // Assuming index coherency - return; // Quad not found, do nothing - } - } - } + SordNode* quad = NULL; + for (unsigned i = 0; i < NUM_ORDERS; ++i) { + if (model->indices[i] && (i < GSPO || tup[3])) { + if (zix_btree_remove(model->indices[i], tup, (void**)&quad, NULL)) { + assert(i == 0); // Assuming index coherency + return; // Quad not found, do nothing + } + } + } - free(quad); + free(quad); - for (int i = 0; i < TUP_LEN; ++i) { - sord_drop_quad_ref(model, tup[i], (SordQuadIndex)i); - } + for (int i = 0; i < TUP_LEN; ++i) { + sord_drop_quad_ref(model, tup[i], (SordQuadIndex)i); + } - --model->n_quads; + --model->n_quads; } SerdStatus sord_erase(SordModel* model, SordIter* iter) { - if (model->n_iters > 1) { - error(model->world, SERD_ERR_BAD_ARG, "erased with many iterators\n"); - return SERD_ERR_BAD_ARG; - } - - SordQuad tup; - sord_iter_get(iter, tup); - - SORD_WRITE_LOG("Remove " TUP_FMT "\n", TUP_FMT_ARGS(tup)); - - SordNode* quad = NULL; - for (unsigned i = 0; i < NUM_ORDERS; ++i) { - if (model->indices[i] && (i < GSPO || tup[3])) { - if (zix_btree_remove(model->indices[i], tup, (void**)&quad, - i == iter->order ? &iter->cur : NULL)) { - return (i == 0) ? SERD_ERR_NOT_FOUND : SERD_ERR_INTERNAL; - } - } - } - iter->end = zix_btree_iter_is_end(iter->cur); - sord_iter_scan_next(iter); - - free(quad); - - for (int i = 0; i < TUP_LEN; ++i) { - sord_drop_quad_ref(model, tup[i], (SordQuadIndex)i); - } - - --model->n_quads; - return SERD_SUCCESS; + if (model->n_iters > 1) { + error(model->world, SERD_ERR_BAD_ARG, "erased with many iterators\n"); + return SERD_ERR_BAD_ARG; + } + + SordQuad tup; + sord_iter_get(iter, tup); + + SORD_WRITE_LOG("Remove " TUP_FMT "\n", TUP_FMT_ARGS(tup)); + + SordNode* quad = NULL; + for (unsigned i = 0; i < NUM_ORDERS; ++i) { + if (model->indices[i] && (i < GSPO || tup[3])) { + if (zix_btree_remove(model->indices[i], + tup, + (void**)&quad, + i == iter->order ? &iter->cur : NULL)) { + return (i == 0) ? SERD_ERR_NOT_FOUND : SERD_ERR_INTERNAL; + } + } + } + iter->end = zix_btree_iter_is_end(iter->cur); + sord_iter_scan_next(iter); + + free(quad); + + for (int i = 0; i < TUP_LEN; ++i) { + sord_drop_quad_ref(model, tup[i], (SordQuadIndex)i); + } + + --model->n_quads; + return SERD_SUCCESS; } |