[tracker/tracker-0.6] Speed up stats calculation



commit d52d5e3aa70a677b95a693cebebdb09a559ad5e5
Author: Ivan Frade <ivan frade nokia com>
Date:   Wed Jun 17 13:59:36 2009 +0300

    Speed up stats calculation
    
    Calculate the stats of top categories adding the results of the subcategories,
    instead of using a very expensive DB query.
    
    Added a new list in tracker-ontology to keep the list of "top categories".

 src/libtracker-common/tracker-ontology.c |   22 +++++++++++-
 src/libtracker-common/tracker-ontology.h |    1 +
 src/trackerd/tracker-daemon.c            |   54 ++++++++++++++++++++++++-----
 3 files changed, 66 insertions(+), 11 deletions(-)
---
diff --git a/src/libtracker-common/tracker-ontology.c b/src/libtracker-common/tracker-ontology.c
index 18029f8..10d68da 100644
--- a/src/libtracker-common/tracker-ontology.c
+++ b/src/libtracker-common/tracker-ontology.c
@@ -50,7 +50,7 @@ static GHashTable *service_names;
 static GHashTable *mimes_to_service_ids;
 
 /* List of ServiceMimePrefixes */
-static GSList	  *service_mime_prefixes;
+static GSList	  *service_mime_prefixes = NULL;
 
 /* Field descriptions */
 static GHashTable *field_names;
@@ -61,6 +61,9 @@ static gpointer    field_type_enum_class;
 /* Category - subcategory ids cache */
 static GHashTable *subcategories_cache;
 
+/* List of top services in the hierarchy */ 
+static GSList *top_services = NULL;
+
 static void
 ontology_mime_prefix_foreach (gpointer data,
 			      gpointer user_data)
@@ -199,6 +202,11 @@ tracker_ontology_shutdown (void)
 		service_mime_prefixes = NULL;
 	}
 
+	if (top_services) {
+		g_slist_free (top_services);
+		top_services = NULL;
+	}
+
 	g_type_class_unref (field_type_enum_class);
 	field_type_enum_class = NULL;
 
@@ -228,6 +236,11 @@ tracker_ontology_service_add (TrackerService *service,
 			     g_strdup_printf ("%d", id),
 			     g_object_ref (service));
 
+	if (tracker_service_get_parent (service) == NULL ||
+	    !g_strcmp0 (tracker_service_get_parent (service), " ")) {
+		top_services = g_slist_prepend (top_services, service);
+	}
+
 	for (l = mimes; l && l->data; l = l->next) {
 		g_hash_table_insert (mimes_to_service_ids,
 				     l->data,
@@ -515,6 +528,13 @@ tracker_ontology_get_subcategory_ids (const gchar *service_str)
 	return subcategories;
 }
 
+
+GSList *        
+tracker_ontology_get_top_services (void)
+{
+	return top_services;
+}
+
 /*
  * Service data
  */
diff --git a/src/libtracker-common/tracker-ontology.h b/src/libtracker-common/tracker-ontology.h
index 17cf62b..59d6063 100644
--- a/src/libtracker-common/tracker-ontology.h
+++ b/src/libtracker-common/tracker-ontology.h
@@ -53,6 +53,7 @@ gint		tracker_ontology_get_service_parent_id_by_id	(gint		 id);
 GSList *	tracker_ontology_get_service_names_registered	(void);
 GSList *	tracker_ontology_get_field_names_registered	(const gchar	*service_str);
 GArray *        tracker_ontology_get_subcategory_ids            (const gchar    *service_str);
+GSList *        tracker_ontology_get_top_services               (void);
 
 /* Service data */
 gboolean	tracker_ontology_service_is_valid		(const gchar	*service_str);
diff --git a/src/trackerd/tracker-daemon.c b/src/trackerd/tracker-daemon.c
index ed8373a..03d7557 100644
--- a/src/trackerd/tracker-daemon.c
+++ b/src/trackerd/tracker-daemon.c
@@ -454,7 +454,7 @@ stats_cache_get_latest (void)
 	/* Populate with real stats */
 	for (i = 0; services_to_fetch[i]; i++) {		
 		TrackerDBInterface *iface;
-		GPtrArray          *stats, *parent_stats;
+		GPtrArray          *stats; 
 
 		iface = tracker_db_manager_get_db_interface_by_service (services_to_fetch[i]);
 
@@ -469,18 +469,52 @@ stats_cache_get_latest (void)
 			g_object_unref (result_set);
 		}
 
-		result_set = tracker_data_manager_exec_proc (iface, "GetStatsForParents", 0);
-		parent_stats = tracker_dbus_query_result_to_ptr_array (result_set);
+		g_ptr_array_foreach (stats, stats_cache_filter_dups_func, values);
+		tracker_dbus_results_ptr_array_free (&stats);
+	}
 
-		if (result_set) {
-			g_object_unref (result_set);
+	/*
+	 * For each of the top services, add the items of their subservices 
+	 *  (calculated in the previous GetStats)
+	 */
+	GSList *top_services = NULL;
+	GSList *tops = NULL;
+
+	top_services = tracker_ontology_get_top_services ();
+
+	for (tops = top_services; tops != NULL; tops = tops->next) {
+		const gchar *top_name = NULL;
+		GArray *subcategories = NULL;
+		gint subcategories_items = 0;
+
+		top_name = tracker_service_get_name (tops->data);
+
+		if (!top_name) continue;
+
+		subcategories = tracker_ontology_get_subcategory_ids (top_name);
+
+		for (i = 0; i < subcategories->len; i++) {
+			const gchar *subclass;
+			gpointer     amount;
+			gint         id;
+
+			id = g_array_index (subcategories, gint, i);
+			subclass = tracker_ontology_get_service_by_id (id);
+			amount = g_hash_table_lookup (values, subclass);
+			if (amount == NULL) continue;
+			
+			subcategories_items += GPOINTER_TO_INT (amount);
 		}
-		
-		g_ptr_array_foreach (stats, stats_cache_filter_dups_func, values);
-		g_ptr_array_foreach (parent_stats, stats_cache_filter_dups_func, values);
 
-		tracker_dbus_results_ptr_array_free (&parent_stats);
-		tracker_dbus_results_ptr_array_free (&stats);
+		if (g_hash_table_lookup (values, tops->data)) {
+			g_hash_table_replace (values, 
+					      g_strdup (top_name), 
+					      GINT_TO_POINTER (subcategories_items));
+		} else {
+			g_hash_table_insert (values, 
+					     g_strdup (top_name), 
+					     GINT_TO_POINTER (subcategories_items));
+		}
 	}
 
 	return values;



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