tracker r2340 - in trunk: . src/trackerd
- From: mr svn gnome org
- To: svn-commits-list gnome org
- Subject: tracker r2340 - in trunk: . src/trackerd
- Date: Thu, 9 Oct 2008 10:49:30 +0000 (UTC)
Author: mr
Date: Thu Oct 9 10:49:30 2008
New Revision: 2340
URL: http://svn.gnome.org/viewvc/tracker?rev=2340&view=rev
Log:
* src/trackerd/tracker-monitor.c: Added an event cache so we don't
send 2 events for a cp command to the indexer - this is an
efficiency improvement. Now we just send CREATED to the indexer
instead of CREATED & UPDATED. This fixes NB#88769.
Modified:
trunk/ChangeLog
trunk/src/trackerd/tracker-monitor.c
Modified: trunk/src/trackerd/tracker-monitor.c
==============================================================================
--- trunk/src/trackerd/tracker-monitor.c (original)
+++ trunk/src/trackerd/tracker-monitor.c Thu Oct 9 10:49:30 2008
@@ -91,13 +91,19 @@
#ifdef USE_LIBINOTIFY
GHashTable *event_pairs;
- GHashTable *event_time_by_cookie;
- GHashTable *event_type_by_cookie;
+ guint event_pairs_timeout_id;
- guint event_check_timeout_id;
+ GHashTable *cached_events;
+ guint cached_events_timeout_id;
#endif /* USE_LIBINOTIFY */
};
+typedef struct {
+ GFile *file;
+ GTimeVal time;
+ guint32 event_type;
+} EventPairData;
+
enum {
ITEM_CREATED,
ITEM_UPDATED,
@@ -111,18 +117,24 @@
PROP_ENABLED
};
-static void tracker_monitor_finalize (GObject *object);
-static void tracker_monitor_set_property (GObject *object,
- guint prop_id,
+static void tracker_monitor_finalize (GObject *object);
+static void tracker_monitor_set_property (GObject *object,
+ guint prop_id,
const GValue *value,
- GParamSpec *pspec);
-static void tracker_monitor_get_property (GObject *object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec);
-static gboolean black_list_check_items_cb (gpointer data);
-static void black_list_print_all (TrackerMonitor *monitor);
-static guint get_inotify_limit (void);
+ GParamSpec *pspec);
+static void tracker_monitor_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec);
+static EventPairData *event_pair_data_new (GFile *file,
+ GTimeVal t,
+ guint event_type);
+
+static void event_pair_data_free (gpointer data);
+static gboolean black_list_check_items_cb (gpointer data);
+static void black_list_print_all (TrackerMonitor *monitor);
+static guint get_inotify_limit (void);
+
#ifdef USE_LIBINOTIFY
static INotifyHandle *libinotify_monitor_directory (TrackerMonitor *monitor,
@@ -254,17 +266,12 @@
g_hash_table_new_full (g_direct_hash,
g_direct_equal,
NULL,
- g_object_unref);
- priv->event_time_by_cookie =
- g_hash_table_new_full (g_direct_hash,
- g_direct_equal,
- NULL,
- NULL);
- priv->event_type_by_cookie =
- g_hash_table_new_full (g_direct_hash,
- g_direct_equal,
+ event_pair_data_free);
+ priv->cached_events =
+ g_hash_table_new_full (g_file_hash,
+ (GEqualFunc) g_file_equal,
NULL,
- NULL);
+ event_pair_data_free);
#endif /* USE_LIBINOTIFY */
all_modules = tracker_module_config_get_modules ();
@@ -391,12 +398,15 @@
g_hash_table_unref (priv->black_list_count);
#ifdef USE_LIBINOTIFY
- if (priv->event_check_timeout_id) {
- g_source_remove (priv->event_check_timeout_id);
+ if (priv->cached_events_timeout_id) {
+ g_source_remove (priv->cached_events_timeout_id);
}
- g_hash_table_unref (priv->event_type_by_cookie);
- g_hash_table_unref (priv->event_time_by_cookie);
+ if (priv->event_pairs_timeout_id) {
+ g_source_remove (priv->event_pairs_timeout_id);
+ }
+
+ g_hash_table_unref (priv->cached_events);
g_hash_table_unref (priv->event_pairs);
#endif /* USE_LIBINOTIFY */
@@ -448,6 +458,32 @@
}
}
+static EventPairData *
+event_pair_data_new (GFile *file,
+ GTimeVal t,
+ guint event_type)
+{
+ EventPairData *event;
+
+ event = g_new0 (EventPairData, 1);
+
+ event->file = g_object_ref (file);
+ event->time = t;
+ event->event_type = event_type;
+
+ return event;
+}
+
+static void
+event_pair_data_free (gpointer data)
+{
+ EventPairData *event;
+
+ event = data;
+
+ g_object_unref (event->file);
+}
+
static guint
get_inotify_limit (void)
{
@@ -842,10 +878,10 @@
}
static gboolean
-libinotify_event_check_timeout_cb (gpointer data)
+libinotify_event_pairs_timeout_cb (gpointer data)
{
TrackerMonitor *monitor;
- GTimeVal t;
+ GTimeVal now;
GHashTableIter iter;
gpointer key, value;
@@ -853,25 +889,25 @@
g_debug ("Checking for event pairs which have timed out...");
- g_get_current_time (&t);
+ g_get_current_time (&now);
- g_hash_table_iter_init (&iter, monitor->private->event_time_by_cookie);
+ g_hash_table_iter_init (&iter, monitor->private->event_pairs);
while (g_hash_table_iter_next (&iter, &key, &value)) {
- glong seconds;
- glong seconds_then;
- guint32 event_type;
- GFile *file;
- const gchar *module_name;
- gboolean is_directory;
- gpointer p;
+ EventPairData *event;
+ glong seconds;
+ glong seconds_then;
+ const gchar *module_name;
+ gboolean is_directory;
- seconds_then = GPOINTER_TO_SIZE (value);
+ event = value;
- seconds = t.tv_sec;
+ seconds_then = event->time.tv_sec;
+
+ seconds = now.tv_sec;
seconds -= seconds_then;
g_debug ("Comparing now:%ld to then:%ld, diff:%ld",
- t.tv_sec,
+ now.tv_sec,
seconds_then,
seconds);
@@ -879,24 +915,20 @@
continue;
}
- file = g_hash_table_lookup (monitor->private->event_pairs, key);
- p = g_hash_table_lookup (monitor->private->event_type_by_cookie, key);
- event_type = GPOINTER_TO_UINT (p);
-
/* We didn't receive an event pair for this
* cookie, so we just generate the CREATE or
* DELETE event for the file we know about.
*/
g_debug ("Event:%d with cookie:%d has timed out (%ld seconds have elapsed)",
- event_type,
+ event->event_type,
GPOINTER_TO_UINT (key),
seconds);
module_name = get_module_name_from_gfile (monitor,
- file,
+ event->file,
&is_directory);
- switch (event_type) {
+ switch (event->event_type) {
case IN_MOVED_FROM:
case IN_DELETE:
case IN_DELETE_SELF:
@@ -906,7 +938,7 @@
g_signal_emit (monitor,
signals[ITEM_DELETED], 0,
module_name,
- file,
+ event->file,
is_directory);
break;
@@ -918,23 +950,114 @@
g_signal_emit (monitor,
signals[ITEM_CREATED], 0,
module_name,
- file,
+ event->file,
is_directory);
break;
}
/* Clean up */
g_hash_table_remove (monitor->private->event_pairs, key);
- g_hash_table_remove (monitor->private->event_time_by_cookie, key);
- g_hash_table_remove (monitor->private->event_type_by_cookie, key);
/* Reset the iter, so we start from the top */
- g_hash_table_iter_init (&iter, monitor->private->event_time_by_cookie);
+ g_hash_table_iter_init (&iter, monitor->private->event_pairs);
}
- if (g_hash_table_size (monitor->private->event_time_by_cookie) < 1) {
+ if (g_hash_table_size (monitor->private->event_pairs) < 1) {
g_debug ("No more events to pair, removing timeout");
- monitor->private->event_check_timeout_id = 0;
+ monitor->private->event_pairs_timeout_id = 0;
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static gboolean
+libinotify_cached_events_timeout_cb (gpointer data)
+{
+ TrackerMonitor *monitor;
+ GTimeVal now;
+ GHashTableIter iter;
+ gpointer key, value;
+
+ monitor = data;
+
+ g_debug ("Checking for cached events that have timed out...");
+
+ g_get_current_time (&now);
+
+ g_hash_table_iter_init (&iter, monitor->private->cached_events);
+ while (g_hash_table_iter_next (&iter, &key, &value)) {
+ EventPairData *event;
+ glong seconds;
+ glong seconds_then;
+ const gchar *module_name;
+ gboolean is_directory;
+
+ event = value;
+
+ seconds_then = event->time.tv_sec;
+
+ seconds = now.tv_sec;
+ seconds -= seconds_then;
+
+ g_debug ("Comparing now:%ld to then:%ld, diff:%ld",
+ now.tv_sec,
+ seconds_then,
+ seconds);
+
+ if (seconds < 2) {
+ continue;
+ }
+
+ /* We didn't receive an event pair for this
+ * cookie, so we just generate the CREATE or
+ * DELETE event for the file we know about.
+ */
+ g_debug ("Cached event:%d has timed out (%ld seconds have elapsed)",
+ event->event_type,
+ seconds);
+
+ module_name = get_module_name_from_gfile (monitor,
+ event->file,
+ &is_directory);
+
+ switch (event->event_type) {
+ case IN_MOVED_FROM:
+ case IN_DELETE:
+ case IN_DELETE_SELF:
+ /* So we knew the source, but not the
+ * target location for the event.
+ */
+ g_signal_emit (monitor,
+ signals[ITEM_DELETED], 0,
+ module_name,
+ event->file,
+ is_directory);
+ break;
+
+ case IN_CREATE:
+ case IN_MOVED_TO:
+ /* So we new the target, but not the
+ * source location for the event.
+ */
+ g_signal_emit (monitor,
+ signals[ITEM_CREATED], 0,
+ module_name,
+ event->file,
+ is_directory);
+ break;
+ }
+
+ /* Clean up */
+ g_hash_table_remove (monitor->private->cached_events, key);
+
+ /* Reset the iter, so we start from the top */
+ g_hash_table_iter_init (&iter, monitor->private->cached_events);
+ }
+
+ if (g_hash_table_size (monitor->private->cached_events) < 1) {
+ g_debug ("No more cached events, removing timeout");
+ monitor->private->cached_events_timeout_id = 0;
return FALSE;
}
@@ -1037,6 +1160,9 @@
g_free (event_type_str);
if (!black_list_file_check (monitor, file)) {
+ EventPairData *data = NULL;
+ GTimeVal now;
+
if (monitor->private->unpause_timeout_id != 0) {
g_source_remove (monitor->private->unpause_timeout_id);
} else {
@@ -1059,37 +1185,29 @@
/* First check if we already have a file in
* the event pairs hash table.
*/
- other_file = g_hash_table_lookup (monitor->private->event_pairs,
- GINT_TO_POINTER (cookie));
- if (!other_file) {
- GTimeVal t;
+ data = g_hash_table_lookup (monitor->private->event_pairs,
+ GUINT_TO_POINTER (cookie));
- g_get_current_time (&t);
+ if (!data) {
+ g_get_current_time (&now);
+ data = event_pair_data_new (file, now, event_type);
+
g_hash_table_insert (monitor->private->event_pairs,
GUINT_TO_POINTER (cookie),
- g_object_ref (file));
- g_hash_table_insert (monitor->private->event_time_by_cookie,
- GUINT_TO_POINTER (cookie),
- GSIZE_TO_POINTER (t.tv_sec));
- g_hash_table_insert (monitor->private->event_type_by_cookie,
- GUINT_TO_POINTER (cookie),
- GUINT_TO_POINTER (event_type));
+ data);
} else {
- gchar *other_path;
-
- other_path = g_file_get_path (other_file);
- g_free (other_path);
+ other_file = data->file;
}
/* Add a check for old cookies we didn't
* receive the follow up pair event for.
*/
- if (!monitor->private->event_check_timeout_id) {
+ if (!monitor->private->event_pairs_timeout_id) {
g_debug ("Setting up event pair timeout check");
- monitor->private->event_check_timeout_id =
+ monitor->private->event_pairs_timeout_id =
g_timeout_add_seconds (2,
- libinotify_event_check_timeout_cb,
+ libinotify_event_pairs_timeout_cb,
monitor);
}
}
@@ -1103,6 +1221,16 @@
case IN_CLOSE_WRITE:
case IN_ATTRIB:
+ if (g_hash_table_lookup (monitor->private->cached_events, file)) {
+ /* We already have an even we will
+ * signal when we timeout. So don't
+ * propagate this event.
+ *
+ * See IN_CREATE.
+ */
+ break;
+ }
+
g_signal_emit (monitor,
signals[ITEM_UPDATED], 0,
module_name,
@@ -1128,15 +1256,34 @@
is_directory);
g_hash_table_remove (monitor->private->event_pairs,
GUINT_TO_POINTER (cookie));
- g_hash_table_remove (monitor->private->event_time_by_cookie,
- GUINT_TO_POINTER (cookie));
- g_hash_table_remove (monitor->private->event_type_by_cookie,
- GUINT_TO_POINTER (cookie));
}
break;
case IN_CREATE:
+ /* Here we just wait with CREATE events and
+ * if we get MODIFY after, we drop the MODIFY
+ * and just emit CREATE because otherwise we
+ * send twice as much traffic to the indexer.
+ */
+ g_get_current_time (&now);
+ data = event_pair_data_new (file, now, event_type);
+
+ g_hash_table_insert (monitor->private->cached_events,
+ data->file,
+ data);
+
+ if (!monitor->private->cached_events_timeout_id) {
+ g_debug ("Setting up cached events timeout check");
+
+ monitor->private->cached_events_timeout_id =
+ g_timeout_add_seconds (2,
+ libinotify_cached_events_timeout_cb,
+ monitor);
+ }
+
+ break;
+
case IN_MOVED_TO:
/* FIXME: What if we don't monitor the other
* location?
@@ -1156,10 +1303,6 @@
is_directory);
g_hash_table_remove (monitor->private->event_pairs,
GUINT_TO_POINTER (cookie));
- g_hash_table_remove (monitor->private->event_time_by_cookie,
- GUINT_TO_POINTER (cookie));
- g_hash_table_remove (monitor->private->event_type_by_cookie,
- GUINT_TO_POINTER (cookie));
}
break;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]