From 2e25fe1e64f487fd91ff6f636bf3249b761ffcdc Mon Sep 17 00:00:00 2001 From: David Robillard Date: Wed, 13 Jan 2021 19:34:11 +0100 Subject: Use a fixed-size reader stack This improves performance, and makes the reader more suitable for embedded or network-facing applications, at the cost of requiring the user to specify a maximum stack size. --- src/reader.c | 64 ++++++++++++++++++++++++++++-------------------------------- 1 file changed, 30 insertions(+), 34 deletions(-) (limited to 'src/reader.c') diff --git a/src/reader.c b/src/reader.c index ab9e54b5..1693ef64 100644 --- a/src/reader.c +++ b/src/reader.c @@ -42,9 +42,8 @@ r_err(SerdReader* reader, SerdStatus st, const char* fmt, ...) } void -set_blank_id(SerdReader* reader, Ref ref, size_t buf_size) +set_blank_id(SerdReader* reader, SerdNode* node, size_t buf_size) { - SerdNode* node = deref(reader, ref); char* buf = (char*)(node + 1); const char* prefix = reader->bprefix ? (const char*)reader->bprefix : ""; @@ -58,15 +57,18 @@ genid_size(SerdReader* reader) return reader->bprefix_len + 1 + 10 + 1; // + "b" + UINT32_MAX + \0 } -Ref +SerdNode* blank_id(SerdReader* reader) { - Ref ref = push_node_padded(reader, genid_size(reader), SERD_BLANK, "", 0); - set_blank_id(reader, ref, genid_size(reader)); + SerdNode* ref = + push_node_padded(reader, genid_size(reader), SERD_BLANK, "", 0); + if (ref) { + set_blank_id(reader, ref, genid_size(reader)); + } return ref; } -Ref +SerdNode* push_node_padded(SerdReader* reader, size_t maxlen, SerdNodeType type, @@ -76,6 +78,10 @@ push_node_padded(SerdReader* reader, void* mem = serd_stack_push_aligned( &reader->stack, sizeof(SerdNode) + maxlen + 1, sizeof(SerdNode)); + if (!mem) { + return NULL; + } + SerdNode* const node = (SerdNode*)mem; node->n_bytes = n_bytes; node->flags = 0; @@ -85,14 +91,15 @@ push_node_padded(SerdReader* reader, memcpy(buf, str, n_bytes + 1); #ifdef SERD_STACK_CHECK - reader->allocs = (Ref*)realloc(reader->allocs, - sizeof(reader->allocs) * (++reader->n_allocs)); - reader->allocs[reader->n_allocs - 1] = ((char*)mem - reader->stack.buf); + reader->allocs = (SerdNode**)realloc( + reader->allocs, sizeof(reader->allocs) * (++reader->n_allocs)); + reader->allocs[reader->n_allocs - 1] = + (SerdNode*)((char*)mem - reader->stack.buf); #endif - return (Ref)((char*)node - reader->stack.buf); + return node; } -Ref +SerdNode* push_node(SerdReader* reader, SerdNodeType type, const char* str, @@ -102,41 +109,30 @@ push_node(SerdReader* reader, } SerdNode* -deref(SerdReader* reader, const Ref ref) -{ - return ref ? (SerdNode*)(reader->stack.buf + ref) : NULL; -} - -Ref -pop_node(SerdReader* reader, Ref ref) +pop_node(SerdReader* reader, const SerdNode* node) { - if (ref && ref != reader->rdf_first && ref != reader->rdf_rest && - ref != reader->rdf_nil) { + if (node && node != reader->rdf_first && node != reader->rdf_rest && + node != reader->rdf_nil) { #ifdef SERD_STACK_CHECK - SERD_STACK_ASSERT_TOP(reader, ref); + SERD_STACK_ASSERT_TOP(reader, node); --reader->n_allocs; #endif - SerdNode* const node = deref(reader, ref); - char* const top = reader->stack.buf + reader->stack.size; + char* const top = reader->stack.buf + reader->stack.size; serd_stack_pop_aligned(&reader->stack, (size_t)(top - (char*)node)); } - return 0; + return NULL; } SerdStatus -emit_statement(SerdReader* reader, ReadContext ctx, Ref o) +emit_statement(SerdReader* reader, ReadContext ctx, SerdNode* o) { - SerdNode* graph = deref(reader, ctx.graph); + SerdNode* graph = ctx.graph; if (!graph && reader->default_graph) { graph = reader->default_graph; } - const SerdStatus st = serd_sink_write(reader->sink, - *ctx.flags, - deref(reader, ctx.subject), - deref(reader, ctx.predicate), - deref(reader, o), - graph); + const SerdStatus st = serd_sink_write( + reader->sink, *ctx.flags, ctx.subject, ctx.predicate, o, graph); *ctx.flags &= SERD_ANON_CONT | SERD_LIST_CONT; // Preserve only cont flags return st; @@ -163,13 +159,13 @@ serd_reader_read_document(SerdReader* reader) } SerdReader* -serd_reader_new(SerdSyntax syntax, const SerdSink* sink) +serd_reader_new(SerdSyntax syntax, const SerdSink* sink, size_t stack_size) { SerdReader* me = (SerdReader*)calloc(1, sizeof(SerdReader)); me->sink = sink; me->default_graph = NULL; - me->stack = serd_stack_new(SERD_PAGE_SIZE); + me->stack = serd_stack_new(stack_size); me->syntax = syntax; me->next_id = 1; me->strict = true; -- cgit v1.2.1