[tracker/signal-enhancements: 2/2] tracker-store: Thaw and Freeze GraphUpdated signals on SparqlBatchUpdate



commit 3f6a33c5afdc0c78eb0d63589df65bc15ac563b6
Author: Philip Van Hoof <philip codeminded be>
Date:   Wed Dec 15 16:21:16 2010 +0100

    tracker-store: Thaw and Freeze GraphUpdated signals on SparqlBatchUpdate

 src/tracker-store/tracker-resources.c              |   44 ++++--
 tests/functional-tests/ipc/.gitignore              |    2 +
 tests/functional-tests/ipc/Makefile.am             |   15 ++
 .../ipc/test-class-signal-performance-batch.vala   |  158 ++++++++++++++++++++
 4 files changed, 202 insertions(+), 17 deletions(-)
---
diff --git a/src/tracker-store/tracker-resources.c b/src/tracker-store/tracker-resources.c
index 8533563..ca427df 100644
--- a/src/tracker-store/tracker-resources.c
+++ b/src/tracker-store/tracker-resources.c
@@ -85,7 +85,7 @@ enum {
 typedef struct {
 	DBusConnection *connection;
 	guint signal_timeout;
-	gboolean freeze_emission;
+	gboolean freeze_emission, signal_configured;
 	gpointer signal_user_data;
 } TrackerResourcesPrivate;
 
@@ -392,26 +392,36 @@ update_callback (GError *error, gpointer user_data)
 static void
 freeze_signal_emission (TrackerResourcesPrivate *priv)
 {
-	g_source_remove (priv->signal_timeout);
-	priv->signal_timeout =  0;
+	if (priv->signal_timeout != 0) {
+		g_source_remove (priv->signal_timeout);
+		priv->signal_timeout =  0;
+	}
 	priv->freeze_emission = TRUE;
 }
 
 static void
-thaw_signal_emission (TrackerResourcesPrivate *priv,
-                      gboolean                 restart,
-                      gboolean                 with_user_data,
-                      gpointer                 user_data)
-{
-	if (restart && priv->signal_timeout == 0) {
-		if (with_user_data) {
-			priv->signal_user_data = user_data;
-		}
+thaw_signal_emission (TrackerResourcesPrivate *priv, gboolean restart)
+{
+	priv->freeze_emission = FALSE;
+	if (restart && priv->signal_configured) {
 		priv->signal_timeout = g_timeout_add_seconds (TRACKER_SIGNALS_SECONDS_PER_EMIT,
 		                                              on_emit_signals,
 		                                              priv->signal_user_data);
 	}
-	priv->freeze_emission = FALSE;
+}
+
+static void
+configure_signal_emission (TrackerResourcesPrivate *priv,
+                           gpointer                 user_data)
+{
+	if (priv->signal_timeout == 0) {
+		priv->signal_user_data = user_data;
+		priv->signal_configured = TRUE;
+		if (!priv->freeze_emission) {
+			/* Function shares the exact same code, accidentally */
+			thaw_signal_emission (priv, TRUE);
+		}
+	}
 }
 
 static void
@@ -422,7 +432,7 @@ update_batch_callback (GError *error, gpointer user_data)
 	if (tracker_store_get_queue_size_for_priority (TRACKER_STORE_PRIORITY_LOW) == 0) {
 		TrackerResourcesPrivate *priv = TRACKER_RESOURCES_GET_PRIVATE (info->self);
 
-		thaw_signal_emission (priv, TRUE, FALSE, NULL);
+		thaw_signal_emission (priv, TRUE);
 	}
 
 	g_object_unref (info->self);
@@ -472,7 +482,7 @@ tracker_resources_sparql_update (TrackerResources        *self,
 
 	priv = TRACKER_RESOURCES_GET_PRIVATE (self);
 
-	thaw_signal_emission (priv, FALSE, FALSE, NULL);
+	thaw_signal_emission (priv, FALSE);
 
 	tracker_store_sparql_update (update, TRACKER_STORE_PRIORITY_HIGH,
 	                             update_callback, sender,
@@ -530,7 +540,7 @@ tracker_resources_sparql_update_blank (TrackerResources       *self,
 
 	priv = TRACKER_RESOURCES_GET_PRIVATE (self);
 
-	thaw_signal_emission (priv, FALSE, FALSE, NULL);
+	thaw_signal_emission (priv, FALSE);
 
 	tracker_store_sparql_update_blank (update, TRACKER_STORE_PRIORITY_HIGH,
 	                                   update_blank_callback, sender,
@@ -590,7 +600,7 @@ tracker_resources_batch_sparql_update (TrackerResources          *self,
 
 	sender = dbus_g_method_get_sender (context);
 
-	if (!priv->freeze_emission && priv->signal_timeout != 0) {
+	if (!priv->freeze_emission) {
 		freeze_signal_emission (priv);
 	}
 
@@ -738,7 +748,7 @@ on_statements_committed (gpointer user_data)
 		tracker_class_transact_events (class);
 	}
 
-	thaw_signal_emission (priv, !priv->freeze_emission, TRUE, user_data);
+	configure_signal_emission (priv, user_data);
 
 	/* Writeback feature */
 	tracker_writeback_transact ();
diff --git a/tests/functional-tests/ipc/.gitignore b/tests/functional-tests/ipc/.gitignore
index 35c2d22..1ba754f 100644
--- a/tests/functional-tests/ipc/.gitignore
+++ b/tests/functional-tests/ipc/.gitignore
@@ -1,6 +1,8 @@
 test-update-array-performance
 test-class-signal-performance
 test-class-signal-performance.c
+test-class-signal-performance-batch
+test-class-signal-performance-batch.c
 test-class-signal
 test-class-signal.c
 test-shared-query.c
diff --git a/tests/functional-tests/ipc/Makefile.am b/tests/functional-tests/ipc/Makefile.am
index 6459837..8987fed 100644
--- a/tests/functional-tests/ipc/Makefile.am
+++ b/tests/functional-tests/ipc/Makefile.am
@@ -7,6 +7,7 @@ include $(top_srcdir)/Makefile.decl
 #   test-busy-handling
 #   test-class-signal
 #   test-class-signal-performance
+#   test-class-signal-performance-batch
 #
 noinst_PROGRAMS =                                      \
 	test-busy-handling                             \
@@ -16,6 +17,7 @@ noinst_PROGRAMS =                                      \
 	test-bus-update                                \
 	test-class-signal                              \
 	test-class-signal-performance                  \
+	test-class-signal-performance-batch            \
 	test-update-array-performance
 
 AM_VALAFLAGS =                                         \
@@ -93,3 +95,16 @@ test_class_signal_performance_VALAFLAGS =              \
 test_class_signal_performance_LDADD =                  \
 	$(LDADD)                                       \
 	$(TRACKER_DBUS_LIBS)
+
+test_class_signal_performance_batch_SOURCES =          \
+	test-class-signal-performance-batch.vala
+test_class_signal_performance_batch_CFLAGS =           \
+	$(AM_CPPFLAGS)                                 \
+	$(TRACKER_DBUS_CFLAGS)
+test_class_signal_performance_batch_VALAFLAGS =        \
+	--pkg dbus-glib-1                              \
+	$(AM_VALAFLAGS)
+test_class_signal_performance_batch_LDADD =            \
+	$(LDADD)                                       \
+	$(TRACKER_DBUS_LIBS)
+
diff --git a/tests/functional-tests/ipc/test-class-signal-performance-batch.vala b/tests/functional-tests/ipc/test-class-signal-performance-batch.vala
new file mode 100644
index 0000000..df0681f
--- /dev/null
+++ b/tests/functional-tests/ipc/test-class-signal-performance-batch.vala
@@ -0,0 +1,158 @@
+/*
+ * Copyright (C) 2008, Nokia <ivan frade nokia com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA  02110-1301, USA.
+ */
+
+using Tracker;
+using Tracker.Sparql;
+
+const int max_signals = 1000;
+// const int max_signals = 10000;
+const string title_data = "title";
+
+// Always start this test AFTER DOING tracker-control -r. The test IS NOT
+// deleting existing resources, so you CAN'T RUN IT TWICE unless you clear
+// the database before starting it the second time.
+
+// Testreport of Aug 25, 2010 by Philip
+// ------------------------------------
+// On Aug 25 the difference between using tracker-store on master and the
+// tracker-store of class-signal, and then letting this wait until all 10000
+// (in case of max_signals = 10000) insert queries' signals arrived (you'll
+// have in total 20002 events in the signals in both tracker-store versions)
+// was: 20s for class-signals (new class signal) and 23s for master (old class
+// signals). Measured using this performance test.
+//
+// Memory usage of class-signal (new class signal)'s tracker-store:
+// Low: VmRSS: 8860 Kb -- Max: VmRSS: 14116 kB
+//
+// Memory usage of master (old class signal)'s tracker-store:
+// Low: VmRSS: 8868 Kb -- Max: VmRSS: 14060 kB
+
+
+struct Event {
+	int graph_id;
+	int subject_id;
+	int pred_id;
+	int object_id;
+}
+
+[DBus (name = "org.freedesktop.Tracker1.Resources")]
+private interface Resources : GLib.Object {
+	[DBus (name = "GraphUpdated")]
+	public signal void graph_updated (string class_name, Event[] deletes, Event[] inserts);
+
+	[DBus (name = "BatchSparqlUpdate")]
+	public abstract async void batch_sparql_update_async (string query) throws Sparql.Error, DBus.Error;
+}
+
+[DBus (name = "org.freedesktop.Tracker1.Resources.Class")]
+private interface ResourcesClass : GLib.Object {
+	[DBus (name = "SubjectsAdded")]
+	public signal void subjects_added (string [] subjects);
+	[DBus (name = "SubjectsChanged")]
+	public signal void subjects_changed (string [] subjects, string [] preds);
+}
+
+public class TestApp {
+	static DBus.Connection dbus_connection;
+	static Resources resources_object;
+	static ResourcesClass class_object;
+	MainLoop loop;
+	bool initialized = false;
+	Sparql.Connection con;
+	int count = 0;
+	GLib.Timer t;
+
+	public TestApp ()
+	requires (!initialized) {
+		try {
+			con = Tracker.Sparql.Connection.get();
+			dbus_connection = DBus.Bus.get (DBus.BusType.SESSION);
+			resources_object = (Resources) dbus_connection.get_object ("org.freedesktop.Tracker1",
+			                                                           "/org/freedesktop/Tracker1/Resources",
+			                                                           "org.freedesktop.Tracker1.Resources");
+
+			class_object = (ResourcesClass) dbus_connection.get_object ("org.freedesktop.Tracker1",
+		                                                                "/org/freedesktop/Tracker1/Resources/Classes/nmm/MusicPiece",
+		                                                                "org.freedesktop.Tracker1.Resources.Class");
+
+			class_object.subjects_added.connect (on_subjects_added);
+			class_object.subjects_changed.connect (on_subjects_changed);
+
+			resources_object.graph_updated.connect (on_graph_updated_received);
+			t = new GLib.Timer ();
+			
+		} catch (GLib.Error e) {
+			warning ("Could not connect to D-Bus service: %s", e.message);
+			initialized = false;
+			return;
+		}
+		initialized = true;
+	}
+
+	private void on_subjects_changed (string [] subjects, string [] preds) {
+		foreach (string s in subjects)
+			count++;
+
+		//if (count == 20002)
+			print ("Old class signal count=%d time=%lf\n", count, t.elapsed ());
+	}
+
+	private void on_subjects_added (string [] subjects) {
+		foreach (string s in subjects)
+			count++;
+
+		//if (count == 20002)
+			print ("Old class signal count=%d time=%lf\n", count, t.elapsed ());
+	}
+
+	private void on_graph_updated_received (string class_name, Event[] deletes, Event[] inserts) {
+		foreach (Event insert in inserts)
+			count++;
+		//if (count == 20002)
+			print ("New class signal count=%d time=%lf\n", count, t.elapsed ());
+	}
+
+	private void insert_data () {
+		int i;
+
+		t.start();
+		for (i = 0; i <= max_signals; i++) {
+			string upqry = "INSERT { <%d> a nmm:MusicPiece ; nie:title '%s %d' }".printf(i, title_data, i);
+			resources_object.batch_sparql_update_async (upqry);
+		}
+	}
+
+	private bool in_mainloop () {
+		insert_data ();
+		return false;
+	}
+
+	public int run () {
+		loop = new MainLoop (null, false);
+		Idle.add (in_mainloop);
+		loop.run ();
+		return 0;
+	}
+}
+
+int main (string[] args) {
+	TestApp app = new TestApp ();
+
+	return app.run ();
+}



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