[tracker] Fixes: NB#109891, If deleting last music track or last video...
- From: Jürg Billeter <juergbi src gnome org>
- To: svn-commits-list gnome org
- Subject: [tracker] Fixes: NB#109891, If deleting last music track or last video...
- Date: Fri, 24 Apr 2009 08:04:39 -0400 (EDT)
commit 9b435f36c4625fc5133bcc6cc865c8416e507986
Author: Martyn Russell <martyn imendio com>
Date: Thu Apr 16 19:46:56 2009 +0100
Fixes: NB#109891, If deleting last music track or last video...
The cache expires now after 3 minutes instead of 1 minute which was
too short. We now use GetServices every time to fix the case where 0
items for a service type doesn't show up in the
SERVICE_STATISTICS_UPDATED signal.
---
src/trackerd/tracker-daemon.c | 249 ++++++++++++++++++++++-------------------
1 files changed, 133 insertions(+), 116 deletions(-)
diff --git a/src/trackerd/tracker-daemon.c b/src/trackerd/tracker-daemon.c
index 7a9ba7c..c1b9819 100644
--- a/src/trackerd/tracker-daemon.c
+++ b/src/trackerd/tracker-daemon.c
@@ -44,8 +44,8 @@
#define TRACKER_TYPE_G_STRV_ARRAY (dbus_g_type_get_collection ("GPtrArray", G_TYPE_STRV))
-/* Seconds */
-#define STATS_CACHE_LIFETIME 60
+/* In seconds (3 minutes for now) */
+#define STATS_CACHE_LIFETIME 180
typedef struct {
TrackerConfig *config;
@@ -65,9 +65,10 @@ enum {
LAST_SIGNAL
};
-static void tracker_daemon_finalize (GObject *object);
-static gboolean stats_cache_timeout (gpointer user_data);
-static void stats_cache_update (TrackerDaemon *object);
+static void tracker_daemon_finalize (GObject *object);
+static gboolean stats_cache_timeout (gpointer user_data);
+static GHashTable *stats_cache_get_latest (void);
+static void stats_cache_update (TrackerDaemon *object);
static guint signals[LAST_SIGNAL] = {0};
@@ -225,16 +226,9 @@ tracker_daemon_init (TrackerDaemon *object)
iface = tracker_db_manager_get_db_interface ();
- /* Prepare cache */
- priv->stats_cache = g_hash_table_new_full (g_str_hash,
- g_str_equal,
- g_free,
- NULL);
+ /* Do first time stats lookup */
+ priv->stats_cache = stats_cache_get_latest ();
- /* First time update */
- stats_cache_update (object);
-
- /* Future updates */
priv->stats_cache_timeout_id =
g_timeout_add_seconds (STATS_CACHE_LIFETIME,
stats_cache_timeout,
@@ -368,39 +362,97 @@ db_get_stats (void)
}
static void
-stats_cache_update (TrackerDaemon *object)
+stats_cache_filter_dups_func (gpointer data,
+ gpointer user_data)
{
- TrackerDaemonPrivate *priv;
- TrackerDBResultSet *result_set;
- GPtrArray *values;
- guint i;
+ GHashTable *values;
+ GStrv strv;
+ gpointer p;
+ gint count;
+
+ /* FIXME: There is a really shit bug here that needs
+ * fixing. If a file has "Files" as its main category
+ * and not its *parent* category, then we end up with
+ * 2 "Files" listings. This sounds like a bug with
+ * the indexer's insert mechanisms. So far this seems
+ * to only happen for removable media files
+ *
+ * For now, we will concatenate values to sort out the
+ * duplicates:
+ */
+ strv = data;
+ values = user_data;
- priv = TRACKER_DAEMON_GET_PRIVATE (object);
+ count = atoi (strv[1]);
+
+ p = g_hash_table_lookup (values, strv[0]);
+
+ if (G_UNLIKELY (p)) {
+ count += GPOINTER_TO_INT (p);
+ }
+
+ g_hash_table_replace (values,
+ g_strdup (strv[0]),
+ GINT_TO_POINTER (count));
+}
+
+static GHashTable *
+stats_cache_get_latest (void)
+{
+ TrackerDBResultSet *result_set;
+ GHashTable *values;
+ GPtrArray *stats;
+
+ /* Set up empty list of services because SQL queries won't give us 0 items. */
+ g_message ("Requesting statistics from database for an accurate signal");
+
+ values = g_hash_table_new_full (g_str_hash,
+ g_str_equal,
+ g_free,
+ NULL);
result_set = db_get_stats ();
- values = tracker_dbus_query_result_to_ptr_array (result_set);
+ stats = tracker_dbus_query_result_to_ptr_array (result_set);
if (result_set) {
g_object_unref (result_set);
}
- /* Update local cache */
- for (i = 0; i < values->len; i++) {
- gchar **p;
- const gchar *service_type = NULL;
- gint new_count;
+ g_ptr_array_foreach (stats, stats_cache_filter_dups_func, values);
- p = g_ptr_array_index (values, i);
- service_type = p[0];
- new_count = atoi (p[1]);
+ g_ptr_array_free (stats, TRUE);
+
+ return values;
+}
+
+static void
+stats_cache_update (TrackerDaemon *object)
+{
+ TrackerDaemonPrivate *priv;
+ GHashTable *values;
+ GHashTableIter iter;
+ gpointer key, value;
+
+ priv = TRACKER_DAEMON_GET_PRIVATE (object);
+
+ /* Get latest */
+ values = stats_cache_get_latest ();
+
+ /* Update local cache */
+ g_hash_table_iter_init (&iter, values);
+ while (g_hash_table_iter_next (&iter, &key, &value)) {
+ const gchar *service_type;
+ gint new_count;
+
+ service_type = key;
+ new_count = GPOINTER_TO_INT (value);
g_hash_table_replace (priv->stats_cache,
g_strdup (service_type),
GINT_TO_POINTER (new_count));
}
- g_ptr_array_foreach (values, (GFunc) g_strfreev, NULL);
- g_ptr_array_free (values, TRUE);
+ g_hash_table_unref (values);
}
static gboolean
@@ -451,9 +503,9 @@ tracker_daemon_get_stats (TrackerDaemon *object,
g_hash_table_iter_init (&iter, priv->stats_cache);
while (g_hash_table_iter_next (&iter, &key, &value)) {
- GStrv strv;
- const gchar *service_type;
- gint count;
+ GStrv strv;
+ const gchar *service_type;
+ gint count;
service_type = key;
count = GPOINTER_TO_INT (value);
@@ -701,116 +753,81 @@ tracker_daemon_signal_statistics (void)
{
GObject *daemon;
TrackerDaemonPrivate *priv;
- TrackerDBResultSet *result_set;
+ GHashTable *stats;
+ GHashTableIter iter;
+ gpointer key, value;
GPtrArray *values;
- gint i;
daemon = tracker_dbus_get_object (TRACKER_TYPE_DAEMON);
priv = TRACKER_DAEMON_GET_PRIVATE (daemon);
- g_message ("Requesting statistics from database for an accurate signal");
-
- result_set = db_get_stats ();
- values = tracker_dbus_query_result_to_ptr_array (result_set);
-
- if (result_set) {
- g_object_unref (result_set);
- }
+ /* Get latest */
+ stats = stats_cache_get_latest ();
/* There are 3 situations here:
* - 1. No new stats
* Action: Do nothing
- * - 2. No previous stats
- * Action: Emit all new stats
- * - 3. New stats and old stats
+ * - 2. New stats and old stats
* Action: Check what has changed and emit new stats
*/
g_message ("Checking for statistics changes and signalling clients...");
/* Situation #1 */
- if (!values || values->len < 1) {
+ if (g_hash_table_size (stats) < 1) {
+ g_hash_table_unref (stats);
g_message (" No new statistics, doing nothing");
return;
}
- if (g_hash_table_size (priv->stats_cache) < 1) {
- /* Situation #2 */
- g_message (" No previous statistics");
-
- for (i = 0; i < values->len; i++) {
- const gchar **p;
- const gchar *service_type = NULL;
- gint new_count;
-
- p = g_ptr_array_index (values, i);
+ /* Situation #2 */
+ values = g_ptr_array_new ();
- service_type = p[0];
- new_count = atoi (p[1]);
+ g_hash_table_iter_init (&iter, stats);
+ while (g_hash_table_iter_next (&iter, &key, &value)) {
+ const gchar *service_type;
+ gpointer data;
+ gint old_count, new_count;
+
+ service_type = key;
+ new_count = GPOINTER_TO_INT (value);
- if (!service_type) {
- continue;
- }
+ data = g_hash_table_lookup (priv->stats_cache, service_type);
+ old_count = GPOINTER_TO_INT (data);
+
+ if (old_count != new_count) {
+ GStrv strv;
- g_message (" Adding '%s' with count:%d",
+ g_message (" Updating '%s' with new count:%d, old count:%d, diff:%d",
service_type,
- new_count);
- g_hash_table_insert (priv->stats_cache,
- g_strdup (service_type),
- GINT_TO_POINTER (new_count));
+ new_count,
+ old_count,
+ new_count - old_count);
+
+ g_hash_table_replace (priv->stats_cache,
+ g_strdup (service_type),
+ GINT_TO_POINTER (new_count));
+
+ strv = g_new (gchar*, 3);
+ strv[0] = g_strdup (service_type);
+ strv[1] = g_strdup_printf ("%d", new_count);
+ strv[2] = NULL;
+
+ g_ptr_array_add (values, strv);
}
+ }
+
+ g_hash_table_unref (stats);
- /* Emit signal */
+ if (values->len > 0) {
+ /* Make sure we sort the results first */
+ g_ptr_array_sort (values, stats_cache_sort_func);
+
g_signal_emit (daemon, signals[SERVICE_STATISTICS_UPDATED], 0, values);
} else {
- /* Situation #3 */
- for (i = 0; i < values->len; i++) {
- gchar **p;
- const gchar *service_type = NULL;
- gpointer data;
- gint old_count, new_count;
-
- p = g_ptr_array_index (values, i);
- service_type = p[0];
- new_count = atoi (p[1]);
-
- if (!service_type) {
- continue;
- }
-
- data = g_hash_table_lookup (priv->stats_cache, service_type);
- old_count = GPOINTER_TO_INT (data);
-
- if (old_count != new_count) {
- g_message (" Updating '%s' with new count:%d, old count:%d, diff:%d",
- service_type,
- new_count,
- old_count,
- new_count - old_count);
-
- g_hash_table_replace (priv->stats_cache,
- g_strdup (service_type),
- GINT_TO_POINTER (new_count));
- } else {
- /* Remove from values since the value is the same */
- g_strfreev (p);
- g_ptr_array_remove (values, p);
-
- /* Decrement i since we are about to
- * increment it and we just removed
- * an item. Otherwise we miss items.
- */
- i--;
- }
- }
-
- if (values->len > 0) {
- g_signal_emit (daemon, signals[SERVICE_STATISTICS_UPDATED], 0, values);
- } else {
- g_message (" No changes in the statistics");
- }
+ g_message (" No changes in the statistics");
}
-
+
g_ptr_array_foreach (values, (GFunc) g_strfreev, NULL);
g_ptr_array_free (values, TRUE);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]