From 66b145eee13fc1d65edbd7b126791da29ea377bd Mon Sep 17 00:00:00 2001 From: David Robillard Date: Sun, 28 Oct 2018 14:15:28 +0100 Subject: Cache commonly used nodes in the world --- include/serd/serd.h | 11 +++++++++++ src/world.c | 26 ++++++++++++++++++++++++++ src/world.h | 16 ++++++++++++---- src/writer.c | 17 ++++++++--------- test/test_world.c | 12 ++++++++++++ 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 @@ -1159,6 +1159,17 @@ SERD_API 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. 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 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; } -- cgit v1.2.1