[tracker/wip/carlosg/sparql1.1: 102/201] libtracker-data: Attempt to reuse variables for sparql literals



commit 0a448b4f2ebde35a095ff43ac4d990a2769265f0
Author: Carlos Garnacho <carlosg gnome org>
Date:   Thu Jun 6 02:18:02 2019 +0200

    libtracker-data: Attempt to reuse variables for sparql literals
    
    Use the same SQL variable if the same literal is used in multiple
    places of the sparql query.

 src/libtracker-data/tracker-sparql-types.c |  7 +++++++
 src/libtracker-data/tracker-sparql.c       | 10 +++++++++-
 2 files changed, 16 insertions(+), 1 deletion(-)
---
diff --git a/src/libtracker-data/tracker-sparql-types.c b/src/libtracker-data/tracker-sparql-types.c
index 15f1df3e7..6ac613640 100644
--- a/src/libtracker-data/tracker-sparql-types.c
+++ b/src/libtracker-data/tracker-sparql-types.c
@@ -775,12 +775,19 @@ void
 tracker_select_context_add_literal_binding (TrackerSelectContext  *context,
                                             TrackerLiteralBinding *binding)
 {
+       gint i;
+
        /* Literal bindings are reserved to the root context */
        g_assert (TRACKER_CONTEXT (context)->parent == NULL);
 
        if (!context->literal_bindings)
                context->literal_bindings = g_ptr_array_new_with_free_func (g_object_unref);
 
+       for (i = 0; i < context->literal_bindings->len; i++) {
+               if (binding == g_ptr_array_index (context->literal_bindings, i))
+                       return;
+       }
+
        g_ptr_array_add (context->literal_bindings, g_object_ref (binding));
 }
 
diff --git a/src/libtracker-data/tracker-sparql.c b/src/libtracker-data/tracker-sparql.c
index dfa44caa8..55fd4e14e 100644
--- a/src/libtracker-data/tracker-sparql.c
+++ b/src/libtracker-data/tracker-sparql.c
@@ -114,6 +114,7 @@ struct _TrackerSparql
 
        GPtrArray *var_names;
        GArray *var_types;
+       GHashTable *cached_bindings;
 
        GVariantBuilder *blank_nodes;
        GHashTable *solution_var_map;
@@ -163,6 +164,7 @@ tracker_sparql_finalize (GObject *object)
        g_object_unref (sparql->data_manager);
        g_hash_table_destroy (sparql->prefix_map);
        g_hash_table_destroy (sparql->parameters);
+       g_hash_table_destroy (sparql->cached_bindings);
 
        if (sparql->sql)
                tracker_string_builder_free (sparql->sql);
@@ -729,6 +731,10 @@ _convert_terminal (TrackerSparql *sparql)
 
        rule = tracker_parser_node_get_rule (sparql->current_state.prev_node);
 
+       binding = g_hash_table_lookup (sparql->cached_bindings, str);
+       if (binding)
+               return binding;
+
        if (tracker_grammar_rule_is_a (rule, RULE_TYPE_TERMINAL, TERMINAL_TYPE_PARAMETERIZED_VAR)) {
                binding = tracker_parameter_binding_new (str, NULL);
        } else {
@@ -736,7 +742,7 @@ _convert_terminal (TrackerSparql *sparql)
                tracker_binding_set_data_type (binding, sparql->current_state.expression_type);
        }
 
-       g_free (str);
+       g_hash_table_insert (sparql->cached_bindings, str, g_object_ref (binding));
 
        return binding;
 }
@@ -6925,6 +6931,8 @@ tracker_sparql_init (TrackerSparql *sparql)
 {
        sparql->prefix_map = g_hash_table_new_full (g_str_hash, g_str_equal,
                                                    g_free, g_free);
+       sparql->cached_bindings = g_hash_table_new_full (g_str_hash, g_str_equal,
+                                                        g_free, g_object_unref);
        sparql->parameters = g_hash_table_new (g_str_hash, g_str_equal);
        sparql->var_names = g_ptr_array_new_with_free_func (g_free);
        sparql->var_types = g_array_new (FALSE, FALSE, sizeof (TrackerPropertyType));


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]