diff options
author | Sam Thursfield <sam@afuera.me.uk> | 2020-10-12 16:13:12 +0000 |
---|---|---|
committer | Sam Thursfield <sam@afuera.me.uk> | 2020-10-12 16:13:12 +0000 |
commit | c5057ab3d09540da0590f916ca661b665214a9eb (patch) | |
tree | 3f0f176dc39d1137fe783c484e873a81518c8cf7 | |
parent | d9b268f76ac5f3266bf0b5b11fd8c03a4935299e (diff) | |
parent | 2b9b3118549bc3251a5c340cc1d471af513fdc88 (diff) | |
download | tracker-c5057ab3d09540da0590f916ca661b665214a9eb.tar.gz |
Merge branch 'wip/carlosg/iterative-update' into 'master'
libtracker-data: Process Update rule iteratively
Closes tracker-miners#91
See merge request GNOME/tracker!327
-rw-r--r-- | src/libtracker-data/tracker-sparql.c | 45 |
1 files changed, 30 insertions, 15 deletions
diff --git a/src/libtracker-data/tracker-sparql.c b/src/libtracker-data/tracker-sparql.c index 7beedd0a0..06c4bb45c 100644 --- a/src/libtracker-data/tracker-sparql.c +++ b/src/libtracker-data/tracker-sparql.c @@ -2540,32 +2540,47 @@ static gboolean translate_Update (TrackerSparql *sparql, GError **error) { + gboolean cont = TRUE; + /* Update ::= Prologue ( Update1 ( ';' Update )? )? * * TRACKER EXTENSION: * ';' separator is made optional. + * + * Note: Even though the rule is defined recursively, we + * process it iteratively here. This is in order to avoid + * making maximum update buffer depend on stack size. */ - _call_rule (sparql, NAMED_RULE_Prologue, error); + while (cont) { + _call_rule (sparql, NAMED_RULE_Prologue, error); - if (!sparql->current_state->blank_node_map) { - sparql->current_state->blank_node_map = - g_hash_table_new_full (g_str_hash, g_str_equal, - g_free, g_free); - } + if (!sparql->current_state->blank_node_map) { + sparql->current_state->blank_node_map = + g_hash_table_new_full (g_str_hash, g_str_equal, + g_free, g_free); + } - if (_check_in_rule (sparql, NAMED_RULE_Update1)) { - if (sparql->blank_nodes) - g_variant_builder_open (sparql->blank_nodes, G_VARIANT_TYPE ("aa{ss}")); + if (_check_in_rule (sparql, NAMED_RULE_Update1)) { + if (sparql->blank_nodes) + g_variant_builder_open (sparql->blank_nodes, G_VARIANT_TYPE ("aa{ss}")); - _call_rule (sparql, NAMED_RULE_Update1, error); + _call_rule (sparql, NAMED_RULE_Update1, error); - if (sparql->blank_nodes) - g_variant_builder_close (sparql->blank_nodes); + if (sparql->blank_nodes) + g_variant_builder_close (sparql->blank_nodes); - _optional (sparql, RULE_TYPE_LITERAL, LITERAL_SEMICOLON); + _optional (sparql, RULE_TYPE_LITERAL, LITERAL_SEMICOLON); - if (_check_in_rule (sparql, NAMED_RULE_Update)) - _call_rule (sparql, NAMED_RULE_Update, error); + if (_check_in_rule (sparql, NAMED_RULE_Update)) { + /* Handle the rule inline in the next iteration */ + tracker_sparql_iter_next (sparql); + cont = TRUE; + } else { + cont = FALSE; + } + } else { + cont = FALSE; + } } return TRUE; |