summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/sord.c85
-rw-r--r--src/sord_internal.h22
2 files changed, 63 insertions, 44 deletions
diff --git a/src/sord.c b/src/sord.c
index 819aab1..9510d50 100644
--- a/src/sord.c
+++ b/src/sord.c
@@ -148,11 +148,9 @@ 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->lang, sizeof(node->lang));
hash = zix_digest_add(hash, &node->node.type, sizeof(node->node.type));
- if (node->datatype) {
- hash = zix_digest_add(
- hash, node->datatype->node.buf, node->datatype->node.n_bytes);
+ if (node->node.type == SERD_LITERAL) {
+ hash = zix_digest_add(hash, &node->meta.lit, sizeof(node->meta.lit));
}
return hash;
}
@@ -164,9 +162,12 @@ sord_node_hash_equal(const void* a, const void* b)
const SordNode* b_node = (const SordNode*)b;
return (a_node == b_node)
|| ((a_node->node.type == b_node->node.type) &&
- (a_node->datatype == b_node->datatype) &&
- serd_node_equals(&a_node->node, &b_node->node) &&
- !strncmp(a_node->lang, b_node->lang, sizeof(a_node->lang)));
+ (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)));
}
static void
@@ -201,7 +202,9 @@ static void
free_node_entry(const void* value, void* user_data)
{
const SordNode* node = (const SordNode*)value;
- sord_node_free((SordWorld*)user_data, node->datatype);
+ if (node->node.type == SERD_LITERAL) {
+ sord_node_free((SordWorld*)user_data, node->meta.lit.datatype);
+ }
free((uint8_t*)node->node.buf);
}
@@ -242,15 +245,15 @@ sord_node_compare(const SordNode* a, const SordNode* b)
(const char*)sord_node_get_string(b));
if (cmp == 0) {
// Note: Can't use sord_node_compare here since it does wildcards
- if (!a->datatype || !b->datatype) {
- cmp = a->datatype - b->datatype;
+ if (!a->meta.lit.datatype || !b->meta.lit.datatype) {
+ cmp = a->meta.lit.datatype - b->meta.lit.datatype;
} else {
- cmp = strcmp((const char*)a->datatype->node.buf,
- (const char*)b->datatype->node.buf);
+ cmp = strcmp((const char*)a->meta.lit.datatype->node.buf,
+ (const char*)b->meta.lit.datatype->node.buf);
}
}
if (cmp == 0) {
- cmp = strcmp(a->lang, b->lang);
+ cmp = strcmp(a->meta.lit.lang, b->meta.lit.lang);
}
default:
break;
@@ -659,17 +662,15 @@ sord_node_free_internal(SordWorld* world, SordNode* node)
{
assert(node->refs == 0);
- // Cache members to free since removing from hash will free the node
- SordNode* const datatype = node->datatype;
- 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");
}
- // Free members
- sord_node_free(world, datatype);
+ // Free buffer
free((uint8_t*)buf);
}
@@ -679,8 +680,8 @@ sord_add_quad_ref(SordModel* sord, const SordNode* node, SordQuadIndex i)
if (node) {
assert(node->refs > 0);
++((SordNode*)node)->refs;
- if (i == SORD_OBJECT) {
- ++((SordNode*)node)->refs_as_obj;
+ if (node->node.type != SERD_LITERAL && i == SORD_OBJECT) {
+ ++((SordNode*)node)->meta.res.refs_as_obj;
}
}
}
@@ -693,9 +694,9 @@ sord_drop_quad_ref(SordModel* sord, const SordNode* node, SordQuadIndex i)
}
assert(node->refs > 0);
- if (i == SORD_OBJECT) {
- assert(node->refs_as_obj > 0);
- --((SordNode*)node)->refs_as_obj;
+ 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(sord), (SordNode*)node);
@@ -904,28 +905,31 @@ sord_node_get_type(const SordNode* node)
}
const uint8_t*
-sord_node_get_string(const SordNode* ref)
+sord_node_get_string(const SordNode* node)
{
- return ref->node.buf;
+ return node->node.buf;
}
const uint8_t*
-sord_node_get_string_counted(const SordNode* ref, size_t* len)
+sord_node_get_string_counted(const SordNode* node, size_t* len)
{
- *len = ref->node.n_chars;
- return ref->node.buf;
+ *len = node->node.n_chars;
+ return node->node.buf;
}
const char*
-sord_node_get_language(const SordNode* ref)
+sord_node_get_language(const SordNode* node)
{
- return ref->lang[0] ? ref->lang : NULL;
+ 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* ref)
+sord_node_get_datatype(const SordNode* node)
{
- return ref->datatype;
+ return (node->node.type == SERD_LITERAL) ? node->meta.lit.datatype : NULL;
}
SerdNodeFlags
@@ -937,7 +941,7 @@ sord_node_get_flags(const SordNode* node)
bool
sord_node_is_inline_object(const SordNode* node)
{
- return (node->node.type == SERD_BLANK) && (node->refs_as_obj == 1);
+ return (node->node.type == SERD_BLANK) && (node->meta.res.refs_as_obj == 1);
}
static SordNode*
@@ -954,7 +958,9 @@ sord_insert_node(SordWorld* world, const SordNode* key, bool copy)
if (copy) {
node->node.buf = sord_strndup(node->node.buf, node->node.n_bytes);
}
- node->datatype = sord_node_copy(node->datatype);
+ if (node->node.type == SERD_LITERAL) {
+ node->meta.lit.datatype = sord_node_copy(node->meta.lit.datatype);
+ }
return node;
default:
assert(!node);
@@ -981,7 +987,7 @@ sord_new_uri_counted(SordWorld* world, const uint8_t* str,
}
const SordNode key = {
- NULL, 1, 0, "", { str, n_bytes, n_chars, 0, SERD_URI }
+ { str, n_bytes, n_chars, 0, SERD_URI }, 1, { { 0 } }
};
return sord_insert_node(world, &key, copy);
@@ -1018,7 +1024,7 @@ sord_new_blank_counted(SordWorld* world, const uint8_t* str,
size_t n_bytes, size_t n_chars)
{
const SordNode key = {
- NULL, 1, 0, "", { str, n_bytes, n_chars, 0, SERD_BLANK }
+ { str, n_bytes, n_chars, 0, SERD_BLANK }, 1, { { 0 } }
};
return sord_insert_node(world, &key, true);
@@ -1041,11 +1047,12 @@ sord_new_literal_counted(SordWorld* world,
const char* lang)
{
SordNode key = {
- datatype, 1, 0, "", { str, n_bytes, n_chars, flags, SERD_LITERAL }
+ { str, n_bytes, n_chars, flags, SERD_LITERAL }, 1, { { 0 } }
};
- memset(key.lang, 0, sizeof(key.lang));
+ key.meta.lit.datatype = datatype;
+ memset(key.meta.lit.lang, 0, sizeof(key.meta.lit.lang));
if (lang) {
- strncpy(key.lang, lang, sizeof(key.lang));
+ strncpy(key.meta.lit.lang, lang, sizeof(key.meta.lit.lang));
}
return sord_insert_node(world, &key, true);
diff --git a/src/sord_internal.h b/src/sord_internal.h
index 03050db..16d6ef2 100644
--- a/src/sord_internal.h
+++ b/src/sord_internal.h
@@ -22,13 +22,25 @@
#include "sord/sord.h"
+/** Resource node metadata */
+typedef struct {
+ size_t refs_as_obj; ///< References as a quad object
+} SordResourceMetadata;
+
+/** Literal node metadata */
+typedef struct {
+ SordNode* datatype; ///< Optional literal data type URI
+ char lang[16]; ///< Optional language tag
+} SordLiteralMetadata;
+
/** Node */
struct SordNodeImpl {
- SordNode* datatype; ///< Literal data type (ID of a URI node, or 0)
- size_t refs; ///< Reference count (# of containing quads)
- size_t refs_as_obj; ///< References as a quad object
- char lang[16]; ///< Language tag
- SerdNode node; ///< Serd node
+ SerdNode node; ///< Serd node
+ size_t refs; ///< Reference count (# of containing quads)
+ union {
+ SordResourceMetadata res;
+ SordLiteralMetadata lit;
+ } meta;
};
#endif /* SORD_SORD_INTERNAL_H */