summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2011-03-07 20:10:55 +0000
committerDavid Robillard <d@drobilla.net>2011-03-07 20:10:55 +0000
commitf878de8597b639253e0a7c9de6d8349c34857806 (patch)
treee54e3f222807e63e56da883bded9ecc598a7d520
parent5d1d788b442bf53e3910d69d8cad214df63b47f8 (diff)
downloadsord-f878de8597b639253e0a7c9de6d8349c34857806.tar.gz
sord-f878de8597b639253e0a7c9de6d8349c34857806.tar.bz2
sord-f878de8597b639253e0a7c9de6d8349c34857806.zip
Sane reference counting semantics.
git-svn-id: http://svn.drobilla.net/sord/trunk@51 3d64ff67-21c5-427c-a301-fe4f08042e5a
-rw-r--r--sord/sord.h2
-rw-r--r--src/sord.c34
-rw-r--r--src/sord_test.c48
-rw-r--r--src/syntax.c4
4 files changed, 67 insertions, 21 deletions
diff --git a/sord/sord.h b/sord/sord.h
index e68f86d..0f0d982 100644
--- a/sord/sord.h
+++ b/sord/sord.h
@@ -329,7 +329,7 @@ sord_find(SordModel model, const SordQuad pat);
Add a quad to the store.
*/
SORD_API
-void
+bool
sord_add(SordModel model, const SordQuad quad);
/**
diff --git a/src/sord.c b/src/sord.c
index 628a301..f414c22 100644
--- a/src/sord.c
+++ b/src/sord.c
@@ -185,8 +185,12 @@ sord_world_free(SordWorld world)
static inline int
sord_node_compare(const SordNode a, const SordNode b)
{
- if (!a || !b) {
- return a - b;
+ if (!a && b) {
+ return 1;
+ } else if (a && !b) {
+ return -1;
+ } else if (!a && !b) {
+ return 0;
} else if (a->type != b->type) {
return a->type - b->type;
}
@@ -203,8 +207,10 @@ sord_node_compare(const SordNode a, const SordNode b)
cmp = sord_node_compare(a->datatype, b->datatype);
}
if (cmp == 0) {
- if (!a->lang || !b->lang) {
- cmp = a->lang - b->lang;
+ if (!a->lang && b->lang) {
+ cmp = 1;
+ } else if (a->lang && !b->lang) {
+ cmp = -1;
} else {
cmp = strcmp(a->lang, b->lang);
}
@@ -594,6 +600,7 @@ static void
sord_add_quad_ref(SordModel sord, const SordNode node)
{
if (node) {
+ assert(node->refs > 0);
++node->refs;
}
}
@@ -798,7 +805,7 @@ sord_lookup_literal(SordWorld world, SordNode type,
struct _SordNode key;
key.type = SORD_LITERAL;
key.n_bytes = str_len;
- key.refs = 0;
+ key.refs = 1;
key.datatype = type;
key.lang = lang ? g_intern_string(lang) : NULL;
key.buf = (uint8_t*)str;
@@ -853,6 +860,7 @@ sord_new_uri_counted(SordWorld world, const uint8_t* str, size_t str_len)
{
SordNode node = sord_lookup_name(world, str, str_len);
if (node) {
+ ++node->refs;
return node;
}
@@ -873,6 +881,7 @@ sord_new_blank_counted(SordWorld world, const uint8_t* str, size_t str_len)
{
SordNode node = sord_lookup_name(world, str, str_len);
if (node) {
+ ++node->refs;
return node;
}
@@ -895,12 +904,14 @@ sord_new_literal_counted(SordWorld world, SordNode type,
{
SordNode node = sord_lookup_literal(world, type, str, str_len, lang, lang_len);
if (node) {
+ ++node->refs;
return node;
}
node = sord_new_literal_node(type, str, str_len, lang, lang_len);
g_hash_table_insert(world->literals, node, node); // FIXME: correct?
sord_add_node(world, node);
+ assert(node->refs == 1);
return node;
}
@@ -941,6 +952,7 @@ sord_node_free(SordWorld world, SordNode node)
SordNode
sord_node_copy(SordNode node)
{
+ ++node->refs;
return node;
}
@@ -966,17 +978,24 @@ sord_add_to_index(SordModel sord, const SordQuad tup, SordOrder order)
return true;
}
-void
+bool
sord_add(SordModel sord, const SordQuad tup)
{
SORD_WRITE_LOG("Add " TUP_FMT "\n", TUP_FMT_ARGS(tup));
assert(tup[0] && tup[1] && tup[2]);
+ // FIXME: Remove double search
+ SordIter existing = sord_find(sord, tup);
+ if (existing) {
+ sord_iter_free(existing);
+ return false;
+ }
+
for (unsigned i = 0; i < NUM_ORDERS; ++i) {
if (sord->indices[i]) {
if (!sord_add_to_index(sord, tup, i)) {
assert(i == 0); // Assuming index coherency
- return; // Quad already stored, do nothing
+ return false; // Quad already stored, do nothing
}
}
}
@@ -986,6 +1005,7 @@ sord_add(SordModel sord, const SordQuad tup)
++sord->n_quads;
assert(sord->n_quads == g_sequence_get_length(sord->indices[SPO]));
+ return true;
}
void
diff --git a/src/sord_test.c b/src/sord_test.c
index 9d607fc..feaead2 100644
--- a/src/sord_test.c
+++ b/src/sord_test.c
@@ -50,7 +50,14 @@ uri(SordWorld world, int num)
return sord_new_uri_counted(world, (const uint8_t*)uri, uri_len);
}
-void
+/** Trivial function to return EXIT_FAILURE (useful as a breakpoint) */
+int
+test_fail()
+{
+ return EXIT_FAILURE;
+}
+
+int
generate(SordWorld world, SordModel sord, size_t n_quads, size_t n_objects_per)
{
fprintf(stderr, "Generating %zu (S P *) quads with %zu objects each\n",
@@ -66,12 +73,15 @@ generate(SordWorld world, SordModel sord, size_t n_quads, size_t n_objects_per)
for (size_t j = 0; j < n_objects_per; ++j) {
SordQuad tup = { ids[0], ids[1], ids[2 + j] };
- sord_add(sord, tup);
- sord_node_free(world, ids[2 + j]);
+ if (!sord_add(sord, tup)) {
+ fprintf(stderr, "Fail: Failed to add quad\n");
+ return test_fail();
+ }
}
- sord_node_free(world, ids[0]);
- sord_node_free(world, ids[1]);
+ for (size_t j = 0; j < 2 + n_objects_per; ++j) {
+ sord_node_free(world, ids[j]);
+ }
}
// Add some literals
@@ -84,31 +94,40 @@ generate(SordWorld world, SordModel sord, size_t n_quads, size_t n_objects_per)
sord_node_free(world, tup[2]);
tup[2] = sord_new_literal(world, 0, USTR("hi"), NULL);
sord_add(sord, tup);
+ sord_node_free(world, tup[2]);
tup[0] = uri(world, 14);
tup[2] = sord_new_literal(world, 0, USTR("bonjour"), "fr");
sord_add(sord, tup);
+ sord_node_free(world, tup[2]);
tup[2] = sord_new_literal(world, 0, USTR("salut"), "fr");
sord_add(sord, tup);
// Attempt to add some duplicates
- sord_add(sord, tup);
- sord_add(sord, tup);
+ if (sord_add(sord, tup)) {
+ fprintf(stderr, "Fail: Successfully added duplicate quad\n");
+ return test_fail();
+ }
+ if (sord_add(sord, tup)) {
+ fprintf(stderr, "Fail: Successfully added duplicate quad\n");
+ return test_fail();
+ }
// Add a blank node subject
+ sord_node_free(world, tup[0]);
tup[0] = sord_new_blank(world, USTR("ablank"));
sord_add(sord, tup);
+ sord_node_free(world, tup[1]);
+ sord_node_free(world, tup[2]);
tup[1] = uri(world, 6);
tup[2] = uri(world, 7);
sord_add(sord, tup);
-}
+ sord_node_free(world, tup[0]);
+ sord_node_free(world, tup[1]);
+ sord_node_free(world, tup[2]);
-/** Trivial function to return EXIT_FAILURE (useful as a breakpoint) */
-int
-test_fail()
-{
- return EXIT_FAILURE;
+ return EXIT_SUCCESS;
}
#define TUP_FMT "(%6s %6s %6s)"
@@ -325,6 +344,9 @@ main(int argc, char** argv)
sord_node_free(world, uri_id);
sord_node_free(world, blank_id);
sord_node_free(world, lit_id);
+ sord_node_free(world, uri_id2);
+ sord_node_free(world, blank_id2);
+ sord_node_free(world, lit_id2);
sord_node_free(world, uri_id3);
sord_node_free(world, blank_id3);
sord_node_free(world, lit_id3);
diff --git a/src/syntax.c b/src/syntax.c
index c5c0791..19cbec9 100644
--- a/src/syntax.c
+++ b/src/syntax.c
@@ -171,6 +171,10 @@ event_statement(void* handle,
}
sord_add(state->sord, tup);
+ sord_node_free(state->world, tup[0]);
+ sord_node_free(state->world, tup[1]);
+ sord_node_free(state->world, tup[2]);
+ sord_node_free(state->world, tup[3]);
return true;
}