From f878de8597b639253e0a7c9de6d8349c34857806 Mon Sep 17 00:00:00 2001 From: David Robillard Date: Mon, 7 Mar 2011 20:10:55 +0000 Subject: Sane reference counting semantics. git-svn-id: http://svn.drobilla.net/sord/trunk@51 3d64ff67-21c5-427c-a301-fe4f08042e5a --- sord/sord.h | 2 +- src/sord.c | 34 +++++++++++++++++++++++++++------- src/sord_test.c | 48 +++++++++++++++++++++++++++++++++++------------- src/syntax.c | 4 ++++ 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; } -- cgit v1.2.1