aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2018-10-28 14:15:28 +0100
committerDavid Robillard <d@drobilla.net>2022-01-13 23:03:58 -0500
commit66b145eee13fc1d65edbd7b126791da29ea377bd (patch)
treed643f37567ed90a4827fa0fe2a5fe514c5e553dd
parent4cfc8dc3521480672938a74813ca8bf19eaee964 (diff)
downloadserd-66b145eee13fc1d65edbd7b126791da29ea377bd.tar.gz
serd-66b145eee13fc1d65edbd7b126791da29ea377bd.tar.bz2
serd-66b145eee13fc1d65edbd7b126791da29ea377bd.zip
Cache commonly used nodes in the world
-rw-r--r--include/serd/serd.h11
-rw-r--r--src/world.c26
-rw-r--r--src/world.h16
-rw-r--r--src/writer.c17
-rw-r--r--test/test_world.c12
5 files changed, 69 insertions, 13 deletions
diff --git a/include/serd/serd.h b/include/serd/serd.h
index bf346a99..0120c73b 100644
--- a/include/serd/serd.h
+++ b/include/serd/serd.h
@@ -1160,6 +1160,17 @@ void
serd_world_free(SerdWorld* SERD_NULLABLE world);
/**
+ Return the nodes cache in `world`.
+
+ The returned cache is owned by the world and contains various nodes used
+ frequently by the implementation. For convenience, it may be used to store
+ additional nodes which will be freed when the world is freed.
+*/
+SERD_PURE_API
+SerdNodes* SERD_NONNULL
+serd_world_nodes(SerdWorld* SERD_NONNULL world);
+
+/**
Return a unique blank node.
The returned node is valid only until the next time serd_world_get_blank()
diff --git a/src/world.c b/src/world.c
index 4230448a..0887cfe1 100644
--- a/src/world.c
+++ b/src/world.c
@@ -19,6 +19,7 @@
#include "caret.h"
#include "node.h"
#include "serd_config.h"
+#include "serd_internal.h"
#include "system.h"
#if defined(USE_POSIX_FADVISE)
@@ -90,8 +91,26 @@ SerdWorld*
serd_world_new(void)
{
SerdWorld* world = (SerdWorld*)calloc(1, sizeof(SerdWorld));
+ SerdNodes* nodes = serd_nodes_new();
+
+ const SerdStringView rdf_first = SERD_STRING(NS_RDF "first");
+ const SerdStringView rdf_nil = SERD_STRING(NS_RDF "nil");
+ const SerdStringView rdf_rest = SERD_STRING(NS_RDF "rest");
+ const SerdStringView rdf_type = SERD_STRING(NS_RDF "type");
+ const SerdStringView xsd_boolean = SERD_STRING(NS_XSD "boolean");
+ const SerdStringView xsd_decimal = SERD_STRING(NS_XSD "decimal");
+ const SerdStringView xsd_integer = SERD_STRING(NS_XSD "integer");
+
+ world->rdf_first = serd_nodes_uri(nodes, rdf_first);
+ world->rdf_nil = serd_nodes_uri(nodes, rdf_nil);
+ world->rdf_rest = serd_nodes_uri(nodes, rdf_rest);
+ world->rdf_type = serd_nodes_uri(nodes, rdf_type);
+ world->xsd_boolean = serd_nodes_uri(nodes, xsd_boolean);
+ world->xsd_decimal = serd_nodes_uri(nodes, xsd_decimal);
+ world->xsd_integer = serd_nodes_uri(nodes, xsd_integer);
world->blank_node = serd_new_blank(SERD_STRING("b00000000000"));
+ world->nodes = nodes;
return world;
}
@@ -101,10 +120,17 @@ serd_world_free(SerdWorld* const world)
{
if (world) {
serd_node_free(world->blank_node);
+ serd_nodes_free(world->nodes);
free(world);
}
}
+SerdNodes*
+serd_world_nodes(SerdWorld* const world)
+{
+ return world->nodes;
+}
+
const SerdNode*
serd_world_get_blank(SerdWorld* const world)
{
diff --git a/src/world.h b/src/world.h
index 99f0c92d..44e21166 100644
--- a/src/world.h
+++ b/src/world.h
@@ -23,10 +23,18 @@
#include <stdio.h>
struct SerdWorldImpl {
- SerdErrorFunc error_func;
- void* error_handle;
- uint32_t next_blank_id;
- SerdNode* blank_node;
+ SerdNodes* nodes;
+ SerdErrorFunc error_func;
+ void* error_handle;
+ SerdNode* blank_node;
+ const SerdNode* rdf_first;
+ const SerdNode* rdf_nil;
+ const SerdNode* rdf_rest;
+ const SerdNode* rdf_type;
+ const SerdNode* xsd_boolean;
+ const SerdNode* xsd_decimal;
+ const SerdNode* xsd_integer;
+ uint32_t next_blank_id;
};
/// Open a file configured for fast sequential reading
diff --git a/src/writer.c b/src/writer.c
index eaea9f3c..4e628cc2 100644
--- a/src/writer.c
+++ b/src/writer.c
@@ -505,15 +505,13 @@ write_literal(SerdWriter* const writer,
const char* node_str = serd_node_string(node);
const char* type_uri = datatype ? serd_node_string(datatype) : NULL;
if (supports_abbrev(writer) && type_uri) {
- if (!strncmp(type_uri, NS_XSD, sizeof(NS_XSD) - 1) &&
- (!strcmp(type_uri + sizeof(NS_XSD) - 1, "boolean") ||
- !strcmp(type_uri + sizeof(NS_XSD) - 1, "integer"))) {
+ if (serd_node_equals(datatype, writer->world->xsd_boolean) ||
+ serd_node_equals(datatype, writer->world->xsd_integer)) {
sink(node_str, node->length, writer);
return true;
}
- if (!strncmp(type_uri, NS_XSD, sizeof(NS_XSD) - 1) &&
- !strcmp(type_uri + sizeof(NS_XSD) - 1, "decimal") &&
+ if (serd_node_equals(datatype, writer->world->xsd_decimal) &&
strchr(node_str, '.') && node_str[node->length - 1] != '.') {
/* xsd:decimal literals without trailing digits, e.g. "5.", can
not be written bare in Turtle. We could add a 0 which is
@@ -569,11 +567,12 @@ write_uri_node(SerdWriter* const writer,
const char* node_str = serd_node_string(node);
const bool has_scheme = serd_uri_string_has_scheme(node_str);
if (supports_abbrev(writer)) {
- if (field == SERD_PREDICATE && !strcmp(node_str, NS_RDF "type")) {
+ if (field == SERD_PREDICATE &&
+ serd_node_equals(node, writer->world->rdf_type)) {
return sink("a", 1, writer) == 1;
}
- if (!strcmp(node_str, NS_RDF "nil")) {
+ if (serd_node_equals(node, writer->world->rdf_nil)) {
return sink("()", 2, writer) == 2;
}
@@ -739,13 +738,13 @@ write_list_obj(SerdWriter* const writer,
const SerdNode* const predicate,
const SerdNode* const object)
{
- if (!strcmp(serd_node_string(object), NS_RDF "nil")) {
+ if (serd_node_equals(object, writer->world->rdf_nil)) {
--writer->indent;
write_sep(writer, SEP_LIST_END);
return true;
}
- if (!strcmp(serd_node_string(predicate), NS_RDF "first")) {
+ if (serd_node_equals(predicate, writer->world->rdf_first)) {
write_sep(writer, SEP_LIST_SEP);
write_node(writer, object, SERD_OBJECT, flags);
}
diff --git a/test/test_world.c b/test/test_world.c
index a7728037..8045d1bf 100644
--- a/test/test_world.c
+++ b/test/test_world.c
@@ -38,10 +38,22 @@ test_get_blank(void)
serd_world_free(world);
}
+static void
+test_nodes(void)
+{
+ SerdWorld* const world = serd_world_new();
+ SerdNodes* const nodes = serd_world_nodes(world);
+
+ assert(serd_nodes_size(nodes) > 0u);
+
+ serd_world_free(world);
+}
+
int
main(void)
{
test_get_blank();
+ test_nodes();
return 0;
}