[tracker/sparql-var: 2/2] SPARQL: Do not use pointers as keys in hash tables



commit 963829a747c3ae090be3b44babc27259d285381b
Author: Jürg Billeter <j bitron ch>
Date:   Fri Oct 8 12:40:15 2010 +0200

    SPARQL: Do not use pointers as keys in hash tables
    
    This avoids random variations in the generated SQL and will improve the
    efficiency of the SQL statement cache.
    
    Fixes NB#197097.

 src/libtracker-data/tracker-sparql-pattern.vala |    6 ++--
 src/libtracker-data/tracker-sparql-query.vala   |   30 ++++++++++++++--------
 2 files changed, 22 insertions(+), 14 deletions(-)
---
diff --git a/src/libtracker-data/tracker-sparql-pattern.vala b/src/libtracker-data/tracker-sparql-pattern.vala
index 4c41dde..051e1e2 100644
--- a/src/libtracker-data/tracker-sparql-pattern.vala
+++ b/src/libtracker-data/tracker-sparql-pattern.vala
@@ -229,7 +229,7 @@ class Tracker.Sparql.Pattern : Object {
 			table_map = new HashTable<string,DataTable>.full (str_hash, str_equal, g_free, g_object_unref);
 
 			variables = new List<Variable> ();
-			var_bindings = new HashTable<Variable,VariableBindingList>.full (direct_hash, direct_equal, g_object_unref, g_object_unref);
+			var_bindings = new HashTable<Variable,VariableBindingList>.full (Variable.hash, Variable.equal, g_object_unref, g_object_unref);
 
 			bindings = new List<LiteralBinding> ();
 		}
@@ -873,7 +873,7 @@ class Tracker.Sparql.Pattern : Object {
 
 			// only export selected variables
 			context.var_set = context.select_var_set;
-			context.select_var_set = new HashTable<Variable,int>.full (direct_hash, direct_equal, g_object_unref, null);
+			context.select_var_set = new HashTable<Variable,int>.full (Variable.hash, Variable.equal, g_object_unref, null);
 
 			expect (SparqlTokenType.CLOSE_BRACE);
 
@@ -1093,7 +1093,7 @@ class Tracker.Sparql.Pattern : Object {
 
 	void translate_group_or_union_graph_pattern (StringBuilder sql) throws Sparql.Error {
 		Variable[] all_vars = { };
-		HashTable<Variable,int> all_var_set = new HashTable<Variable,int>.full (direct_hash, direct_equal, g_object_unref, null);
+		HashTable<Variable,int> all_var_set = new HashTable<Variable,int>.full (Variable.hash, Variable.equal, g_object_unref, null);
 
 		Context[] contexts = { };
 		long[] offsets = { };
diff --git a/src/libtracker-data/tracker-sparql-query.vala b/src/libtracker-data/tracker-sparql-query.vala
index 31bb05d..4afb939 100644
--- a/src/libtracker-data/tracker-sparql-query.vala
+++ b/src/libtracker-data/tracker-sparql-query.vala
@@ -73,19 +73,29 @@ namespace Tracker.Sparql {
 
 	class Variable : Object {
 		public string name { get; private set; }
+		public int index { get; private set; }
 		public string sql_expression { get; private set; }
 		public VariableBinding binding;
 		string sql_identifier;
 
-		public Variable (string name, string sql_identifier) {
+		public Variable (string name, int index) {
 			this.name = name;
-			this.sql_identifier = sql_identifier;
+			this.index = index;
+			this.sql_identifier = "%d_u".printf (index);
 			this.sql_expression = "\"%s\"".printf (sql_identifier);
 		}
 
 		public string get_extra_sql_expression (string suffix) {
 			return "\"%s:%s\"".printf (sql_identifier, suffix);
 		}
+
+		public static bool equal (Variable a, Variable b) {
+			return a.index == b.index;
+		}
+
+		public static uint hash (Variable variable) {
+			return (uint) variable.index;
+		}
 	}
 
 	class Context {
@@ -108,12 +118,12 @@ namespace Tracker.Sparql {
 		public Context (Query query, Context? parent_context = null) {
 			this.query = query;
 			this.parent_context = parent_context;
-			this.var_set = new HashTable<Variable,int>.full (direct_hash, direct_equal, g_object_unref, null);
+			this.var_set = new HashTable<Variable,int>.full (Variable.hash, Variable.equal, g_object_unref, null);
 
 			if (parent_context == null) {
-				select_var_set = new HashTable<Variable,int>.full (direct_hash, direct_equal, g_object_unref, null);
+				select_var_set = new HashTable<Variable,int>.full (Variable.hash, Variable.equal, g_object_unref, null);
 				var_map = new HashTable<string,Variable>.full (str_hash, str_equal, g_free, g_object_unref);
-				predicate_variable_map = new HashTable<Variable,PredicateVariable>.full (direct_hash, direct_equal, g_object_unref, g_object_unref);
+				predicate_variable_map = new HashTable<Variable,PredicateVariable>.full (Variable.hash, Variable.equal, g_object_unref, g_object_unref);
 			} else {
 				select_var_set = parent_context.select_var_set;
 				var_map = parent_context.var_map;
@@ -124,20 +134,18 @@ namespace Tracker.Sparql {
 		public Context.subquery (Query query, Context parent_context) {
 			this.query = query;
 			this.parent_context = parent_context;
-			this.var_set = new HashTable<Variable,int>.full (direct_hash, direct_equal, g_object_unref, null);
+			this.var_set = new HashTable<Variable,int>.full (Variable.hash, Variable.equal, g_object_unref, null);
 
-			select_var_set = new HashTable<Variable,int>.full (direct_hash, direct_equal, g_object_unref, null);
+			select_var_set = new HashTable<Variable,int>.full (Variable.hash, Variable.equal, g_object_unref, null);
 			var_map = parent_context.var_map;
-			predicate_variable_map = new HashTable<Variable,PredicateVariable>.full (direct_hash, direct_equal, g_object_unref, g_object_unref);
+			predicate_variable_map = new HashTable<Variable,PredicateVariable>.full (Variable.hash, Variable.equal, g_object_unref, g_object_unref);
 			scalar_subquery = true;
 		}
 
 		internal unowned Variable get_variable (string name) {
 			unowned Variable result = this.var_map.lookup (name);
 			if (result == null) {
-				string sql_identifier = "%d_u".printf (++query.last_var_index);
-
-				var variable = new Variable (name, sql_identifier);
+				var variable = new Variable (name, ++query.last_var_index);
 				this.var_map.insert (name, variable);
 
 				result = variable;



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