summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sord/sord.h62
-rw-r--r--src/sord.c102
-rw-r--r--src/sord_test.c33
-rw-r--r--src/sordi.c5
-rw-r--r--src/syntax.c6
5 files changed, 85 insertions, 123 deletions
diff --git a/sord/sord.h b/sord/sord.h
index bc69875..90c3bf6 100644
--- a/sord/sord.h
+++ b/sord/sord.h
@@ -53,12 +53,11 @@
typedef struct _Sord* Sord; ///< Quad store
typedef struct _SordIter* SordIter; ///< Store iterator
typedef struct _SordNode* SordNode; ///< Node
-typedef void* SordID; ///< Integer ID of a Node (0 reserved for NULL)
/** Quad of IDs (statement), or a quad pattern.
* Nodes are ordered (S P O G). The ID of the default graph is 0.
*/
-typedef SordID SordQuad[4];
+typedef SordNode SordQuad[4];
/** Index into a SordQuad. */
typedef enum {
@@ -89,85 +88,70 @@ typedef enum {
* @{
*/
-/** Create a new store. */
+/** Create a new store.
+ * @param indices SordIndexOption flags (e.g. SORD_SPO|SORD_OPS).
+ * Be sure to choose indices such that there is an index where the most
+ * significant node(s) are not variables for your queries. For example,
+ * if you are going to make (? P O) queries, you should enable either
+ * SORD_OPS or SORD_POS.
+ * @param graphs If true, store (and index) graph contexts.
+ */
SORD_API
Sord
sord_new(unsigned indices, bool graphs);
-/** Close and free @a sord, leaving disk data intact. */
+/** Close and free @a sord. */
SORD_API
void
sord_free(Sord sord);
/** @} */
-/** @name Node Loading
- * Searching for node IDs by value and loading nodes from disk by ID.
+/** @name Nodes
+ * A Node is a component of a Quad. Nodes may be URIs, blank nodes, or
+ * (in the case of quad objects only) string literals. Literal nodes may
+ * have an associate language or datatype (but not both).
* @{
*/
-/** Dereference an ID, loading node data into memory.
- * The returned node is allocated memory owned by @a sord,
- * it can only be freed by the caller via sord_clear_cache.
- */
-SORD_API
-SordNode
-sord_node_load(Sord sord, SordID id);
-
-/** Set @a s, @a p, and @a o to the nodes in @a tup. */
-SORD_API
-void
-sord_quad_load(Sord sord,
- SordQuad tup,
- SordNode* s,
- SordNode* p,
- SordNode* o);
-
/** Find a URI, creating a new one if necessary iff @a create is true.
* Use sord_get_uri_counted instead if the length of @a str is known.
*/
SORD_API
-SordID
+SordNode
sord_get_uri(Sord sord, bool create, const uint8_t* str);
/** Find a URI, creating a new one if necessary iff @a create is true. */
SORD_API
-SordID
+SordNode
sord_get_uri_counted(Sord sord, bool create, const uint8_t* str, int str_len);
/** Find a blank, creating a new one if necessary iff @a create is true
* Use sord_get_blank_counted instead if the length of @a str is known.
*/
SORD_API
-SordID
+SordNode
sord_get_blank(Sord sord, bool create, const uint8_t* str);
/** Find a blank, creating a new one if necessary iff @a create is true. */
SORD_API
-SordID
+SordNode
sord_get_blank_counted(Sord sord, bool create, const uint8_t* str, int str_len);
/** Find a literal, creating a new one if necessary iff @a create is true.
* Use sord_get_literal_counted instead if the length of @a str is known.
*/
SORD_API
-SordID
-sord_get_literal(Sord sord, bool create, SordID type,
+SordNode
+sord_get_literal(Sord sord, bool create, SordNode type,
const uint8_t* str, const char* lang);
/** Find a literal, creating a new one if necessary iff @a create is true. */
SORD_API
-SordID
-sord_get_literal_counted(Sord sord, bool create, SordID type,
+SordNode
+sord_get_literal_counted(Sord sord, bool create, SordNode type,
const uint8_t* str, int str_len,
const char* lang, uint8_t lang_len);
-
-/** @} */
-/** @name Node Values
- * Investigating loaded (in-memory) node values.
- * @{
- */
-
/** Return the type of a node (SORD_URI, SORD_BLANK, or SORD_LITERAL). */
SORD_API
SordNodeType
@@ -259,7 +243,7 @@ sord_remove_iter(Sord sord, SordIter iter);
/** Remove a graph from the store. */
SORD_API
void
-sord_remove_graph(Sord sord, SordID graph);
+sord_remove_graph(Sord sord, SordNode graph);
/** @} */
/** @name Iteration
diff --git a/src/sord.c b/src/sord.c
index f4209f7..ee5ed1b 100644
--- a/src/sord.c
+++ b/src/sord.c
@@ -18,7 +18,7 @@
/** @file
* Sord Implementation.
*
- * Quads are represented as simple arrays of SordID, of length 4,
+ * Quads are represented as simple arrays of SordNode, of length 4,
* which represent statements (RDF triples) with an optional
* context. When contexts are not used, only the first 3 elements
* are considered.
@@ -193,21 +193,18 @@ sord_node_equals(const SordNode a, const SordNode b)
* result set.
*/
static inline int
-sord_id_compare(Sord sord, const SordID a, const SordID b)
+sord_id_compare(Sord sord, const SordNode a, const SordNode b)
{
if (a == b || !a || !b) {
return (const char*)a - (const char*)b;
} else {
- SordNode a_node = sord_node_load(sord, a);
- SordNode b_node = sord_node_load(sord, b);
- const int ret = sord_node_compare(a_node, b_node);
- return ret;
+ return sord_node_compare(a, b);
}
}
/** Return true iff IDs are equivalent, or one is a wildcard */
static inline bool
-sord_id_match(const SordID a, const SordID b)
+sord_id_match(const SordNode a, const SordNode b)
{
return !a || !b || (a == b);
}
@@ -227,14 +224,6 @@ sord_quad_match(const SordQuad x, const SordQuad y)
return sord_quad_match_inline(x, y);
}
-void
-sord_quad_load(Sord sord, SordQuad tup, SordNode* s, SordNode* p, SordNode* o)
-{
- *s = sord_node_load(sord, tup[TUP_S]);
- *p = sord_node_load(sord, tup[TUP_P]);
- *o = sord_node_load(sord, tup[TUP_O]);
-}
-
/** Compare two quad IDs lexicographically.
* NULL IDs (equal to 0) are treated as wildcards, always less than every
* other possible ID, except itself.
@@ -243,8 +232,8 @@ static int
sord_quad_compare(const void* x_ptr, const void* y_ptr, void* user_data)
{
Sord const sord = (Sord)user_data;
- SordID* const x = (SordID*)x_ptr;
- SordID* const y = (SordID*)y_ptr;
+ SordNode* const x = (SordNode*)x_ptr;
+ SordNode* const y = (SordNode*)y_ptr;
for (int i = 0; i < TUP_LEN; ++i) {
const int cmp = sord_id_compare(sord, x[i], y[i]);
@@ -263,14 +252,14 @@ sord_iter_forward(SordIter iter)
return g_sequence_iter_is_end(iter->cur);
}
- const SordID* key = (const SordID*)g_sequence_get(iter->cur);
+ const SordNode* key = (const SordNode*)g_sequence_get(iter->cur);
const SordQuad initial = { key[0], key[1], key[2], key[3] };
while (true) {
iter->cur = g_sequence_iter_next(iter->cur);
if (g_sequence_iter_is_end(iter->cur))
return true;
- key = (const SordID*)g_sequence_get(iter->cur);
+ key = (const SordNode*)g_sequence_get(iter->cur);
for (int i = 0; i < 3; ++i)
if (key[i] != initial[i])
return false;
@@ -287,7 +276,7 @@ sord_iter_seek_match(SordIter iter)
for (iter->end = true;
!g_sequence_iter_is_end(iter->cur);
sord_iter_forward(iter)) {
- const SordID* const key = (const SordID*)g_sequence_get(iter->cur);
+ const SordNode* const key = (const SordNode*)g_sequence_get(iter->cur);
if (sord_quad_match_inline(key, iter->pat))
return (iter->end = false);
}
@@ -305,7 +294,7 @@ sord_iter_seek_match_range(SordIter iter)
return true;
do {
- const SordID* key = (const SordID*)g_sequence_get(iter->cur);
+ const SordNode* key = (const SordNode*)g_sequence_get(iter->cur);
if (sord_quad_match_inline(key, iter->pat))
return false; // Found match
@@ -344,7 +333,7 @@ sord_iter_new(Sord sord, GSequenceIter* cur, const SordQuad pat,
case SINGLE:
case RANGE:
assert(sord_quad_match_inline(
- (const SordID*)g_sequence_get(iter->cur),
+ (const SordNode*)g_sequence_get(iter->cur),
iter->pat));
break;
case FILTER_RANGE:
@@ -374,7 +363,7 @@ sord_iter_get_sord(SordIter iter)
void
sord_iter_get(SordIter iter, SordQuad id)
{
- const SordID* key = (const SordID*)g_sequence_get(iter->cur);
+ const SordNode* key = (const SordNode*)g_sequence_get(iter->cur);
id[iter->ordering[0]] = key[0];
id[iter->ordering[1]] = key[1];
id[iter->ordering[2]] = key[2];
@@ -387,7 +376,7 @@ sord_iter_next(SordIter iter)
if (iter->end)
return true;
- const SordID* key;
+ const SordNode* key;
iter->end = sord_iter_forward(iter);
if (!iter->end) {
switch (iter->mode) {
@@ -401,7 +390,7 @@ sord_iter_next(SordIter iter)
case RANGE:
SORD_ITER_LOG("%p range next\n", (void*)iter);
// At the end if the MSNs no longer match
- key = (const SordID*)g_sequence_get(iter->cur);
+ key = (const SordNode*)g_sequence_get(iter->cur);
assert(key);
for (int i = 0; i < iter->n_prefix; ++i) {
if (!sord_id_match(key[i], iter->pat[i])) {
@@ -563,29 +552,26 @@ sord_new(unsigned indices, bool graphs)
}
static void
-sord_add_quad_ref(Sord sord, const SordID id)
+sord_add_quad_ref(Sord sord, const SordNode node)
{
- if (id) {
- SordNode node = sord_node_load(sord, id);
+ if (node) {
++node->refs;
}
}
static void
-sord_drop_node(Sord sord, SordID id)
+sord_drop_node(Sord sord, SordNode node)
{
- SordNode node = sord_node_load(sord, id);
free(node->buf);
free(node);
}
static void
-sord_drop_quad_ref(Sord sord, const SordID id)
+sord_drop_quad_ref(Sord sord, const SordNode node)
{
- if (id) {
- SordNode node = sord_node_load(sord, id);
+ if (node) {
if (--node->refs == 0) {
- sord_drop_node(sord, id);
+ sord_drop_node(sord, node);
}
}
}
@@ -716,10 +702,10 @@ sord_find(Sord sord, const SordQuad pat)
// It's easiest to think about this algorithm in terms of (S P O) ordering,
// assuming (A B C) == (S P O). For other orderings this is not actually
// the case, but it works the same way.
- const SordID a = pat[ordering[0]]; // Most Significant Node (MSN)
- const SordID b = pat[ordering[1]]; // ...
- const SordID c = pat[ordering[2]]; // ...
- const SordID d = pat[ordering[3]]; // Least Significant Node (LSN)
+ const SordNode a = pat[ordering[0]]; // Most Significant Node (MSN)
+ const SordNode b = pat[ordering[1]]; // ...
+ const SordNode c = pat[ordering[2]]; // ...
+ const SordNode d = pat[ordering[3]]; // Least Significant Node (LSN)
if (a && b && c && d)
mode = SINGLE; // No duplicate quads (Sord is a set)
@@ -731,7 +717,7 @@ sord_find(Sord sord, const SordQuad pat)
SORD_FIND_LOG("No match found\n");
return NULL;
}
- const SordID* const key = (const SordID*)g_sequence_get(cur);
+ const SordNode* const key = (const SordNode*)g_sequence_get(cur);
if (!key || ( (mode == RANGE || mode == SINGLE)
&& !sord_quad_match_inline(search_key, key) )) {
SORD_FIND_LOG("No match found\n");
@@ -741,7 +727,7 @@ sord_find(Sord sord, const SordQuad pat)
return sord_iter_new(sord, cur, pat, index_order, mode, prefix_len);
}
-static SordID
+static SordNode
sord_lookup_name(Sord sord, const uint8_t* str, size_t str_len)
{
return g_hash_table_lookup(sord->names, str);
@@ -786,12 +772,6 @@ sord_lookup_literal(Sord sord, SordNode type,
}
}
-SordNode
-sord_node_load(Sord sord, SordID id)
-{
- return (SordNode)id;
-}
-
SordNodeType
sord_node_get_type(SordNode ref)
{
@@ -830,10 +810,10 @@ sord_add_node(Sord sord, SordNode node)
++sord->n_nodes;
}
-SordID
+SordNode
sord_get_uri_counted(Sord sord, bool create, const uint8_t* str, int str_len)
{
- SordID id = sord_lookup_name(sord, str, str_len);
+ SordNode id = sord_lookup_name(sord, str, str_len);
if (id || !create)
return id;
@@ -846,16 +826,16 @@ sord_get_uri_counted(Sord sord, bool create, const uint8_t* str, int str_len)
return id;
}
-SordID
+SordNode
sord_get_uri(Sord sord, bool create, const uint8_t* str)
{
return sord_get_uri_counted(sord, create, str, strlen((const char*)str));
}
-SordID
+SordNode
sord_get_blank_counted(Sord sord, bool create, const uint8_t* str, int str_len)
{
- SordID id = sord_lookup_name(sord, str, str_len);
+ SordNode id = sord_lookup_name(sord, str, str_len);
if (id || !create)
return id;
@@ -868,18 +848,18 @@ sord_get_blank_counted(Sord sord, bool create, const uint8_t* str, int str_len)
return id;
}
-SordID
+SordNode
sord_get_blank(Sord sord, bool create, const uint8_t* str)
{
return sord_get_blank_counted(sord, create, str, strlen((const char*)str));
}
-SordID
-sord_get_literal_counted(Sord sord, bool create, SordID type,
+SordNode
+sord_get_literal_counted(Sord sord, bool create, SordNode type,
const uint8_t* str, int str_len,
const char* lang, uint8_t lang_len)
{
- SordID id = sord_lookup_literal(sord, type, str, str_len, lang, lang_len);
+ SordNode id = sord_lookup_literal(sord, type, str, str_len, lang, lang_len);
if (id || !create)
return id;
@@ -891,8 +871,8 @@ sord_get_literal_counted(Sord sord, bool create, SordID type,
return id;
}
-SordID
-sord_get_literal(Sord sord, bool create, SordID type,
+SordNode
+sord_get_literal(Sord sord, bool create, SordNode type,
const uint8_t* str, const char* lang)
{
return sord_get_literal_counted(sord, create, type,
@@ -916,7 +896,7 @@ sord_add_to_index(Sord sord, const SordQuad tup, SordOrder order)
// FIXME: would be nice to share quads and just use a different comparator
// for each index (save significant space overhead per quad)
- SordID* key_copy = malloc(sizeof(SordQuad));
+ SordNode* key_copy = malloc(sizeof(SordQuad));
memcpy(key_copy, key, sizeof(SordQuad));
g_sequence_insert_before(cur, key_copy);
return true;
@@ -1005,7 +985,7 @@ sord_remove_iter(Sord sord, SordIter iter)
}
void
-sord_remove_graph(Sord sord, SordID graph)
+sord_remove_graph(Sord sord, SordNode graph)
{
#if 0
if (!sord->indices[GSPO])
@@ -1017,7 +997,7 @@ sord_remove_graph(Sord sord, SordID graph)
int key_size = sizeof(SordQuad);
tcbdbcurjump(cur, &search_key, key_size);
do {
- const SordID* key = (const SordID*)tcbdbcurkey3(cur, &key_size);
+ const SordNode* key = (const SordNode*)tcbdbcurkey3(cur, &key_size);
if (!key || key[0] != graph)
break;
@@ -1042,7 +1022,7 @@ sord_remove_graph(Sord sord, SordID graph)
BDBCUR* cur = tcbdbcurnew(sord->indices[i]);
tcbdbcurjump(cur, &search_key, key_size);
while (true) {
- const SordID* key = (const SordID*)tcbdbcurkey3(cur, &key_size);
+ const SordNode* key = (const SordNode*)tcbdbcurkey3(cur, &key_size);
if (!key || key[0] != graph) {
break;
} else if (i == GSPO) {
diff --git a/src/sord_test.c b/src/sord_test.c
index af2da40..ac6abbe 100644
--- a/src/sord_test.c
+++ b/src/sord_test.c
@@ -29,7 +29,7 @@ typedef struct { SordQuad query; int expected_num_results; } QueryTest;
#define USTR(s) ((const uint8_t*)(s))
-static SordID
+static SordNode
uri(Sord sord, int num)
{
if (num == 0)
@@ -51,7 +51,7 @@ generate(Sord sord, size_t n_quads, size_t n_objects_per)
for (size_t i = 0; i < n_quads; ++i) {
int num = (i * n_objects_per) + 1;
- SordID ids[2 + n_objects_per];
+ SordNode ids[2 + n_objects_per];
for (size_t j = 0; j < 2 + n_objects_per; ++j) {
ids[j] = uri(sord, num++);
}
@@ -100,12 +100,9 @@ test_fail()
#define TUP_FMT "(%6s %6s %6s)"
#define TUP_FMT_ARGS(t) \
- (sord_node_load(sord, (t)[0]) \
- ? sord_node_get_string(sord_node_load(sord, (t)[0])) : USTR("*")), \
- (sord_node_load(sord, (t)[1]) \
- ? sord_node_get_string(sord_node_load(sord, (t)[1])) : USTR("*")), \
- (sord_node_load(sord, (t)[2]) \
- ? sord_node_get_string(sord_node_load(sord, (t)[2])) : USTR("*"))
+ ((t)[0] ? sord_node_get_string((t)[0]) : USTR("*")), \
+ ((t)[1] ? sord_node_get_string((t)[1]) : USTR("*")), \
+ ((t)[2] ? sord_node_get_string((t)[2]) : USTR("*"))
int
test_read(Sord sord, const size_t n_quads, const int n_objects_per)
@@ -199,7 +196,7 @@ test_read(Sord sord, const size_t n_quads, const int n_objects_per)
// Test nested queries
fprintf(stderr, "Nested Queries... ");
pat[0] = pat[1] = pat[2] = 0;
- SordID last_subject = 0;
+ SordNode last_subject = 0;
iter = sord_find(sord, pat);
for (; !sord_iter_end(iter); sord_iter_next(iter)) {
sord_iter_get(iter, id);
@@ -277,13 +274,13 @@ main(int argc, char** argv)
}
// Check interning merges equivalent values
- SordID uri_id = sord_get_uri(sord, true, USTR("http://example.org"));
- SordID blank_id = sord_get_uri(sord, true, USTR("testblank"));
- SordID lit_id = sord_get_literal(sord, true, uri_id, USTR("hello"), NULL);
+ SordNode uri_id = sord_get_uri(sord, true, USTR("http://example.org"));
+ SordNode blank_id = sord_get_uri(sord, true, USTR("testblank"));
+ SordNode lit_id = sord_get_literal(sord, true, uri_id, USTR("hello"), NULL);
//sord_clear_cache(write);
- SordID uri_id2 = sord_get_uri(sord, false, USTR("http://example.org"));
- SordID blank_id2 = sord_get_uri(sord, false, USTR("testblank"));
- SordID lit_id2 = sord_get_literal(sord, false, uri_id, USTR("hello"), NULL);
+ SordNode uri_id2 = sord_get_uri(sord, false, USTR("http://example.org"));
+ SordNode blank_id2 = sord_get_uri(sord, false, USTR("testblank"));
+ SordNode lit_id2 = sord_get_literal(sord, false, uri_id, USTR("hello"), NULL);
if (uri_id2 != uri_id) {
fprintf(stderr, "Fail: URI interning failed (duplicates)\n");
goto fail;
@@ -296,9 +293,9 @@ main(int argc, char** argv)
}
// Check interning doesn't clash non-equivalent values
- SordID uri_id3 = sord_get_uri(sord, false, USTR("http://example.orgX"));
- SordID blank_id3 = sord_get_uri(sord, false, USTR("testblankX"));
- SordID lit_id3 = sord_get_literal(sord, false, uri_id, USTR("helloX"), NULL);
+ SordNode uri_id3 = sord_get_uri(sord, false, USTR("http://example.orgX"));
+ SordNode blank_id3 = sord_get_uri(sord, false, USTR("testblankX"));
+ SordNode lit_id3 = sord_get_literal(sord, false, uri_id, USTR("helloX"), NULL);
if (uri_id3 == uri_id) {
fprintf(stderr, "Fail: URI interning failed (clash)\n");
goto fail;
diff --git a/src/sordi.c b/src/sordi.c
index 883f300..ab2a10a 100644
--- a/src/sordi.c
+++ b/src/sordi.c
@@ -140,8 +140,9 @@ main(int argc, char** argv)
for (; !sord_iter_end(iter); sord_iter_next(iter)) {
SordQuad tup;
sord_iter_get(iter, tup);
- SordNode s, p, o;
- sord_quad_load(sord, tup, &s, &p, &o);
+ SordNode s = tup[SORD_SUBJECT];
+ SordNode p = tup[SORD_PREDICATE];
+ SordNode o = tup[SORD_OBJECT];
SerdNode ss = serd_node_from_sord_node(s);
SerdNode sp = serd_node_from_sord_node(p);
SerdNode so = serd_node_from_sord_node(o);
diff --git a/src/syntax.c b/src/syntax.c
index 911f70a..c06882a 100644
--- a/src/syntax.c
+++ b/src/syntax.c
@@ -92,7 +92,7 @@ event_prefix(void* handle,
return true;
}
-static inline SordID
+static inline SordNode
sord_node_from_serd_node(ReadState* state, const SerdNode* sn)
{
switch (sn->type) {
@@ -104,7 +104,7 @@ sord_node_from_serd_node(ReadState* state, const SerdNode* sn)
SerdURI abs_uri;
SerdNode abs_uri_node = serd_node_new_uri_from_node(
sn, &state->base_uri, &abs_uri);
- SordID ret = sord_get_uri(state->sord, true, abs_uri_node.buf);
+ SordNode ret = sord_get_uri(state->sord, true, abs_uri_node.buf);
serd_node_free(&abs_uri_node);
return ret;
}
@@ -120,7 +120,7 @@ sord_node_from_serd_node(ReadState* state, const SerdNode* sn)
memcpy(buf, uri_prefix.buf, uri_prefix.len);
memcpy(buf + uri_prefix.len, uri_suffix.buf, uri_suffix.len);
buf[uri_len] = '\0';
- SordID ret = sord_get_uri_counted(state->sord, true,
+ SordNode ret = sord_get_uri_counted(state->sord, true,
buf, uri_prefix.len + uri_suffix.len);
free(buf);
return ret;