summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2011-02-04 03:17:39 +0000
committerDavid Robillard <d@drobilla.net>2011-02-04 03:17:39 +0000
commit1cf3c5d35406e424f52903e37cb5b7b0877512e7 (patch)
treeb0a48d6390f644c079a7740b2b9c19e83f4f3311
parenta161fecabd48e7b42c313dcc0132c7c5378d9ca2 (diff)
downloadsord-1cf3c5d35406e424f52903e37cb5b7b0877512e7.tar.gz
sord-1cf3c5d35406e424f52903e37cb5b7b0877512e7.tar.bz2
sord-1cf3c5d35406e424f52903e37cb5b7b0877512e7.zip
Fix memory leaks.
git-svn-id: http://svn.drobilla.net/sord/trunk@18 3d64ff67-21c5-427c-a301-fe4f08042e5a
-rw-r--r--src/sord.c86
-rw-r--r--src/syntax.c12
2 files changed, 58 insertions, 40 deletions
diff --git a/src/sord.c b/src/sord.c
index d14cebb..3e98095 100644
--- a/src/sord.c
+++ b/src/sord.c
@@ -537,8 +537,9 @@ Sord
sord_new()
{
Sord sord = (Sord)malloc(sizeof(struct _Sord));
- sord->names = g_hash_table_new_full(g_str_hash, g_str_equal, 0, 0);
+ sord->names = g_hash_table_new_full(g_str_hash, g_str_equal, free, 0);
sord->literals = g_hash_table_new_full(sord_literal_hash, sord_literal_equal, 0, 0);
+
sord->user_data_free = NULL;
for (unsigned i = 0; i < NUM_ORDERS; ++i)
@@ -547,12 +548,51 @@ sord_new()
return sord;
}
+static void
+sord_add_tuple_ref(Sord sord, const SordID id)
+{
+ if (id) {
+ SordNode node = sord_node_load(sord, id);
+ ++node->refs;
+ }
+}
+
+static void
+sord_drop_node(Sord sord, SordID id)
+{
+ SordNode node = sord_node_load(sord, id);
+ free(node->buf);
+ free(node);
+}
+
+static void
+sord_drop_tuple_ref(Sord sord, const SordID id)
+{
+ if (id) {
+ SordNode node = sord_node_load(sord, id);
+ if (--node->refs == 0) {
+ sord_drop_node(sord, id);
+ }
+ }
+}
+
void
sord_free(Sord sord)
{
if (!sord)
return;
+ // Free nodes
+ SordTuple tup;
+ SordIter i = sord_begin(sord);
+ for (; !sord_iter_end(i); sord_iter_next(i)) {
+ sord_iter_get(i, tup);
+ for (int i = 0; i < TUP_LEN; ++i) {
+ sord_drop_tuple_ref(sord, tup[i]);
+ }
+ }
+ sord_iter_free(i);
+
g_hash_table_unref(sord->names);
g_hash_table_unref(sord->literals);
for (unsigned i = 0; i < NUM_ORDERS; ++i)
@@ -577,12 +617,12 @@ sord_set_option(Sord sord, const char* key, const char* value,
const bool value_is_true = !strcmp(value, "true") || !strcmp(value, "1") || !strcmp(value, "yes");
if (!strcmp(option, "index-all")) {
for (int i = 0; i < NUM_ORDERS; ++i) {
- sord->indices[i] = g_sequence_new(NULL);
+ sord->indices[i] = g_sequence_new(free);
}
} else if (!strncmp(option, "index-", 6) && value_is_true) {
for (int i = 0; i < NUM_ORDERS; ++i) {
if (!strcmp(option + 6, order_names[i])) {
- sord->indices[i] = g_sequence_new(NULL);
+ sord->indices[i] = g_sequence_new(free);
return;
}
}
@@ -605,12 +645,11 @@ sord_open(Sord sord)
}
if (no_indices) {
- // Use default indexing, avoids O(n) in all cases
- sord->indices[SPO] = g_sequence_new(NULL);
- sord->indices[OPS] = g_sequence_new(NULL);
- //sord->indices[PSO] = g_sequence_new(NULL);
- sord->indices[GSPO] = g_sequence_new(NULL); // XXX: default? do on demand?
- sord->indices[GOPS] = g_sequence_new(NULL); // XXX: default? do on demand?
+ // FIXME: make sord_new take a parameter so this is explicit
+ sord->indices[SPO] = g_sequence_new(free);
+ sord->indices[OPS] = g_sequence_new(free);
+ sord->indices[GSPO] = g_sequence_new(free);
+ sord->indices[GOPS] = g_sequence_new(free);
}
if (!sord->indices[DEFAULT_ORDER])
@@ -619,12 +658,6 @@ sord_open(Sord sord)
return true;
}
-static void
-sord_drop_node(Sord sord, SordID id)
-{
- // FIXME: leak?
-}
-
int
sord_num_tuples(Sord sord)
{
@@ -926,26 +959,6 @@ sord_get_literal(Sord sord, bool create, SordID type, const char* str, const cha
lang, lang ? strlen(lang) : 0);
}
-static void
-sord_add_tuple_ref(Sord sord, const SordID id)
-{
- if (id) {
- SordNode node = sord_node_load(sord, id);
- ++node->refs;
- }
-}
-
-static void
-sord_drop_tuple_ref(Sord sord, const SordID id)
-{
- if (id) {
- SordNode node = sord_node_load(sord, id);
- if (--node->refs == 0) {
- sord_drop_node(sord, id);
- }
- }
-}
-
static inline bool
sord_add_to_index(Sord sord, const SordTuple tup, SordOrder order)
{
@@ -960,7 +973,8 @@ sord_add_to_index(Sord sord, const SordTuple tup, SordOrder order)
return false; // Tuple already stored in this index
}
- // FIXME: memory leak?
+ // FIXME: would be nice to share tuples and just use a different comparator
+ // for each index (save significant space overhead per tuple)
SordID* key_copy = malloc(sizeof(SordTuple));
memcpy(key_copy, key, sizeof(SordTuple));
g_sequence_insert_before(cur, key_copy);
diff --git a/src/syntax.c b/src/syntax.c
index ac1a766..e7560c5 100644
--- a/src/syntax.c
+++ b/src/syntax.c
@@ -114,7 +114,9 @@ sord_node_from_serd_node(ReadState* state, const SerdNode* sn)
}
SerdURI ignored;
SerdNode abs_uri_node = serd_node_new_uri(&abs_uri, &ignored);
- return sord_get_uri(state->sord, true, (const char*)abs_uri_node.buf);
+ SordID ret = sord_get_uri(state->sord, true, (const char*)abs_uri_node.buf);
+ serd_node_free(&abs_uri_node);
+ return ret;
}
case SERD_CURIE: {
SerdChunk uri_prefix;
@@ -124,12 +126,14 @@ sord_node_from_serd_node(ReadState* state, const SerdNode* sn)
return NULL;
}
const size_t uri_len = uri_prefix.len + uri_suffix.len;
- char* buf = malloc(uri_len + 1);
+ char* buf = 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';
- return sord_get_uri_counted(state->sord, true,
- buf, uri_prefix.len + uri_suffix.len);
+ SordID ret = sord_get_uri_counted(state->sord, true,
+ buf, uri_prefix.len + uri_suffix.len);
+ free(buf);
+ return ret;
}
case SERD_BLANK_ID:
case SERD_ANON_BEGIN: