[tracker] tracker-store: Avoid copying of arrays at class-signal emit



commit 3d8e3fe4cc824ac2e776d2a8ad1f9528dd5a15ea
Author: Philip Van Hoof <philip codeminded be>
Date:   Wed Aug 18 15:02:51 2010 +0200

    tracker-store: Avoid copying of arrays at class-signal emit

 src/tracker-store/tracker-events.c    |  140 +++++++++++++++++++++------------
 src/tracker-store/tracker-events.h    |   60 ++++++++-------
 src/tracker-store/tracker-resources.c |  138 +++++++++-----------------------
 3 files changed, 160 insertions(+), 178 deletions(-)
---
diff --git a/src/tracker-store/tracker-events.c b/src/tracker-store/tracker-events.c
index 61d5eda..99aff8d 100644
--- a/src/tracker-store/tracker-events.c
+++ b/src/tracker-store/tracker-events.c
@@ -44,82 +44,118 @@ typedef struct {
 
 static EventsPrivate *private;
 
-static void
-get_from_array (gint    class_id,
-                GArray *class_ids,
-                GArray *sub_pred_ids,
-                GArray *object_ids_in,
-                GArray *subject_ids,
-                GArray *pred_ids,
-                GArray *object_ids)
+void
+tracker_events_foreach_insert_of (TrackerClass        *class,
+                                  TrackerEventsForeach foreach,
+                                  gpointer             user_data)
 {
 	guint i;
+	gint class_id;
+
+	g_return_if_fail (private != NULL);
+	g_return_if_fail (class != NULL);
+	g_return_if_fail (foreach != NULL);
 
-	g_array_set_size (subject_ids, 0);
-	g_array_set_size (pred_ids, 0);
-	g_array_set_size (object_ids, 0);
+	class_id = tracker_class_get_id (class);
 
-	for (i = 0; i < class_ids->len; i++) {
+	for (i = 0; i < private->inserts.class_ids->len; i++) {
 		gint class_id_v;
 
-		class_id_v = g_array_index (class_ids, gint, i);
+		class_id_v = g_array_index (private->inserts.class_ids, gint, i);
 
 		if (class_id_v == class_id) {
 			gint subject_id, pred_id, object_id;
 			gint64 sub_pred_id;
 
-			sub_pred_id = g_array_index (sub_pred_ids, gint64, i);
-
+			sub_pred_id = g_array_index (private->inserts.sub_pred_ids, gint64, i);
 			pred_id = sub_pred_id & 0xffffffff;
 			subject_id = sub_pred_id >> 32;
+			object_id = g_array_index (private->inserts.object_ids, gint, i);
 
-			object_id = g_array_index (object_ids_in, gint, i);
-
-			g_array_append_val (subject_ids, subject_id);
-			g_array_append_val (pred_ids, pred_id);
-			g_array_append_val (object_ids, object_id);
+			foreach (subject_id, pred_id, object_id, user_data);
 		}
 	}
 }
 
 void
-tracker_events_get_inserts (gint    class_id,
-                            GArray *subject_ids,
-                            GArray *pred_ids,
-                            GArray *object_ids)
+tracker_events_foreach_delete_of (TrackerClass        *class,
+                                  TrackerEventsForeach foreach,
+                                  gpointer             user_data)
 {
+	guint i;
+	gint class_id;
+
 	g_return_if_fail (private != NULL);
-	g_return_if_fail (subject_ids != NULL);
-	g_return_if_fail (pred_ids != NULL);
-	g_return_if_fail (object_ids != NULL);
-
-	get_from_array (class_id,
-	                private->inserts.class_ids,
-	                private->inserts.sub_pred_ids,
-	                private->inserts.object_ids,
-	                subject_ids,
-	                pred_ids,
-	                object_ids);
+	g_return_if_fail (class != NULL);
+	g_return_if_fail (foreach != NULL);
+
+	class_id = tracker_class_get_id (class);
+
+	for (i = 0; i < private->deletes.class_ids->len; i++) {
+		gint class_id_v;
+
+		class_id_v = g_array_index (private->deletes.class_ids, gint, i);
+
+		if (class_id_v == class_id) {
+			gint subject_id, pred_id, object_id;
+			gint64 sub_pred_id;
+
+			sub_pred_id = g_array_index (private->deletes.sub_pred_ids, gint64, i);
+			pred_id = sub_pred_id & 0xffffffff;
+			subject_id = sub_pred_id >> 32;
+			object_id = g_array_index (private->deletes.object_ids, gint, i);
+
+			foreach (subject_id, pred_id, object_id, user_data);
+		}
+	}
 }
 
-void
-tracker_events_get_deletes (gint    class_id,
-                            GArray *subject_ids,
-                            GArray *pred_ids,
-                            GArray *object_ids)
+gboolean
+tracker_events_class_has_deletes (TrackerClass *class)
 {
-	g_return_if_fail (private != NULL);
-	g_return_if_fail (subject_ids != NULL);
-	g_return_if_fail (pred_ids != NULL);
-	g_return_if_fail (object_ids != NULL);
-
-	get_from_array (class_id,
-	                private->deletes.class_ids,
-	                private->deletes.sub_pred_ids,
-	                private->deletes.object_ids,
-	                subject_ids,
-	                pred_ids,
-	                object_ids);
+	guint i;
+	gint class_id;
+
+	g_return_val_if_fail (private != NULL, FALSE);
+	g_return_val_if_fail (class != NULL, FALSE);
+
+	class_id = tracker_class_get_id (class);
+
+	for (i = 0; i < private->deletes.class_ids->len; i++) {
+		gint class_id_v;
+
+		class_id_v = g_array_index (private->deletes.class_ids, gint, i);
+
+		if (class_id_v == class_id) {
+			return TRUE;
+		}
+	}
+
+	return FALSE;
+}
+
+gboolean
+tracker_events_class_has_inserts (TrackerClass *class)
+{
+	guint i;
+	gint class_id;
+
+	g_return_val_if_fail (private != NULL, FALSE);
+	g_return_val_if_fail (class != NULL, FALSE);
+
+	class_id = tracker_class_get_id (class);
+
+	for (i = 0; i < private->inserts.class_ids->len; i++) {
+		gint class_id_v;
+
+		class_id_v = g_array_index (private->inserts.class_ids, gint, i);
+
+		if (class_id_v == class_id) {
+			return TRUE;
+		}
+	}
+
+	return FALSE;
 }
 
 static gboolean
diff --git a/src/tracker-store/tracker-events.h b/src/tracker-store/tracker-events.h
index 49f2999..bc3b085 100644
--- a/src/tracker-store/tracker-events.h
+++ b/src/tracker-store/tracker-events.h
@@ -28,35 +28,39 @@
 
 G_BEGIN_DECLS
 
-typedef GStrv (*TrackerNotifyClassGetter) (void);
+typedef GStrv (*TrackerNotifyClassGetter)   (void);
+typedef void  (*TrackerEventsForeach)       (gint                      subject_id,
+                                             gint                      pred_id,
+                                             gint                      object_id,
+                                             gpointer                  user_data);
 
-void       tracker_events_init         (TrackerNotifyClassGetter  callback);
-void       tracker_events_shutdown     (void);
-void       tracker_events_add_insert   (gint                      graph_id,
-                                        gint                      subject_id,
-                                        const gchar              *subject,
-                                        gint                      pred_id,
-                                        gint                      object_id,
-                                        const gchar              *object,
-                                        GPtrArray                *rdf_types);
-void       tracker_events_add_delete   (gint                      graph_id,
-                                        gint                      subject_id,
-                                        const gchar              *subject,
-                                        gint                      pred_id,
-                                        gint                      object_id,
-                                        const gchar              *object,
-                                        GPtrArray                *rdf_types);
-void       tracker_events_get_inserts  (gint                      class_id,
-                                        GArray                   *subject_ids,
-                                        GArray                   *pred_ids,
-                                        GArray                   *object_ids);
-void       tracker_events_get_deletes  (gint                      class_id,
-                                        GArray                   *subject_ids,
-                                        GArray                   *pred_ids,
-                                        GArray                   *object_ids);
-void       tracker_events_classes_iter (GHashTableIter           *iter);
-void       tracker_events_reset        (void);
-void       tracker_events_freeze       (void);
+void       tracker_events_init              (TrackerNotifyClassGetter  callback);
+void       tracker_events_shutdown          (void);
+void       tracker_events_add_insert        (gint                      graph_id,
+                                             gint                      subject_id,
+                                             const gchar              *subject,
+                                             gint                      pred_id,
+                                             gint                      object_id,
+                                             const gchar              *object,
+                                             GPtrArray                *rdf_types);
+void       tracker_events_add_delete        (gint                      graph_id,
+                                             gint                      subject_id,
+                                             const gchar              *subject,
+                                             gint                      pred_id,
+                                             gint                      object_id,
+                                             const gchar              *object,
+                                             GPtrArray                *rdf_types);
+void       tracker_events_foreach_delete_of (TrackerClass            *class,
+                                             TrackerEventsForeach     foreach,
+                                             gpointer                 user_data);
+void       tracker_events_foreach_insert_of (TrackerClass            *class,
+                                             TrackerEventsForeach     foreach,
+                                             gpointer                 user_data);
+gboolean   tracker_events_class_has_deletes (TrackerClass            *class);
+gboolean   tracker_events_class_has_inserts (TrackerClass            *class);
+void       tracker_events_classes_iter      (GHashTableIter           *iter);
+void       tracker_events_reset             (void);
+void       tracker_events_freeze            (void);
 
 G_END_DECLS
 
diff --git a/src/tracker-store/tracker-resources.c b/src/tracker-store/tracker-resources.c
index 56d1e78..6d47fb0 100644
--- a/src/tracker-store/tracker-resources.c
+++ b/src/tracker-store/tracker-resources.c
@@ -95,16 +95,7 @@ typedef struct {
 	gpointer user_data;
 } InThreadPtr;
 
-typedef struct {
-	GArray *subject_ids;
-	GArray *pred_ids;
-	GArray *object_ids;
-} TrackerIds;
-
-static TrackerIds inserts_ids = { NULL, NULL, NULL };
-static TrackerIds deletes_ids = { NULL, NULL, NULL };
 static void tracker_resources_finalize (GObject *object);
-
 static guint signals[LAST_SIGNAL] = { 0 };
 
 static void
@@ -539,76 +530,61 @@ tracker_resources_batch_commit (TrackerResources         *self,
 }
 
 static void
-emit_class_signal (TrackerResources *self,
-                   TrackerClass     *class,
-                   TrackerIds       *deletes,
-                   TrackerIds       *inserts)
+foreach_add_to_iter (gint subject_id,
+                     gint pred_id,
+                     gint object_id,
+                     gpointer user_data)
 {
-	TrackerResourcesPrivate *priv;
-	DBusMessageIter iter, deletes_iter, inserts_iter;
-	DBusMessage *message;
-	const gchar *class_uri;
-	guint i;
-
-	priv = TRACKER_RESOURCES_GET_PRIVATE (self);
-
-	message = dbus_message_new_signal (TRACKER_RESOURCES_PATH,
-	                                   TRACKER_RESOURCES_INTERFACE,
-	                                   "ClassSignal");
-
-	class_uri = tracker_class_get_uri (class);
-
-	dbus_message_iter_init_append (message, &iter);
-	dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &class_uri);
+	DBusMessageIter *array_iter = user_data;
+	DBusMessageIter struct_iter;
+
+	dbus_message_iter_open_container (array_iter, DBUS_TYPE_STRUCT, NULL, &struct_iter);
+	dbus_message_iter_append_basic (&struct_iter, DBUS_TYPE_INT32, &subject_id);
+	dbus_message_iter_append_basic (&struct_iter, DBUS_TYPE_INT32, &pred_id);
+	dbus_message_iter_append_basic (&struct_iter, DBUS_TYPE_INT32, &object_id);
+	dbus_message_iter_close_container (array_iter, &struct_iter);
+}
 
-	dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY, 
-	                                  "(iii)", &deletes_iter);
+static void
+emit_class_signal (TrackerResources *self,
+                   TrackerClass     *class)
+{
+	if (tracker_events_class_has_inserts (class) || tracker_events_class_has_deletes (class)) {
+		TrackerResourcesPrivate *priv;
+		DBusMessageIter iter, deletes_iter, inserts_iter;
+		DBusMessage *message;
+		const gchar *class_uri;
 
-	for (i = 0; i < deletes->subject_ids->len; i++) {
-		DBusMessageIter struct_iter;
-		gint subject_id, pred_id, object_id;
+		priv = TRACKER_RESOURCES_GET_PRIVATE (self);
 
-		subject_id = g_array_index (deletes->subject_ids, gint, i);
-		pred_id = g_array_index (deletes->pred_ids, gint, i);
-		object_id = g_array_index (deletes->object_ids, gint, i);
+		message = dbus_message_new_signal (TRACKER_RESOURCES_PATH,
+		                                   TRACKER_RESOURCES_INTERFACE,
+		                                   "ClassSignal");
 
-		dbus_message_iter_open_container (&deletes_iter, DBUS_TYPE_STRUCT, NULL, &struct_iter);
+		class_uri = tracker_class_get_uri (class);
 
-		dbus_message_iter_append_basic (&struct_iter, DBUS_TYPE_INT32, &subject_id);
-		dbus_message_iter_append_basic (&struct_iter, DBUS_TYPE_INT32, &pred_id);
-		dbus_message_iter_append_basic (&struct_iter, DBUS_TYPE_INT32, &object_id);
+		dbus_message_iter_init_append (message, &iter);
+		dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &class_uri);
 
-		dbus_message_iter_close_container (&deletes_iter, &struct_iter);
-	}
+		dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY,
+		                                  "(iii)", &deletes_iter);
 
-	dbus_message_iter_close_container (&iter, &deletes_iter);
+		tracker_events_foreach_delete_of (class, foreach_add_to_iter, &deletes_iter);
 
+		dbus_message_iter_close_container (&iter, &deletes_iter);
 
-	dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY, 
-	                                  "(iii)", &inserts_iter);
 
-	for (i = 0; i < inserts->subject_ids->len; i++) {
-		DBusMessageIter struct_iter;
-		gint subject_id, pred_id, object_id;
+		dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY,
+		                                  "(iii)", &inserts_iter);
 
-		subject_id = g_array_index (inserts->subject_ids, gint, i);
-		pred_id = g_array_index (inserts->pred_ids, gint, i);
-		object_id = g_array_index (inserts->object_ids, gint, i);
+		tracker_events_foreach_insert_of (class, foreach_add_to_iter, &inserts_iter);
 
-		dbus_message_iter_open_container (&inserts_iter, DBUS_TYPE_STRUCT, NULL, &struct_iter);
+		dbus_message_iter_close_container (&iter, &inserts_iter);
 
-		dbus_message_iter_append_basic (&struct_iter, DBUS_TYPE_INT32, &subject_id);
-		dbus_message_iter_append_basic (&struct_iter, DBUS_TYPE_INT32, &pred_id);
-		dbus_message_iter_append_basic (&struct_iter, DBUS_TYPE_INT32, &object_id);
+		dbus_connection_send (priv->connection, message, NULL);
 
-		dbus_message_iter_close_container (&inserts_iter, &struct_iter);
+		dbus_message_unref (message);
 	}
-
-	dbus_message_iter_close_container (&iter, &inserts_iter);
-
-	dbus_connection_send (priv->connection, message, NULL);
-
-	dbus_message_unref (message);
 }
 
 static void
@@ -623,45 +599,11 @@ on_statements_committed (gpointer user_data)
 	priv = TRACKER_RESOURCES_GET_PRIVATE (resources);
 
 	/* Class signal feature */
-
-	if (inserts_ids.subject_ids == NULL) {
-		inserts_ids.subject_ids = g_array_new (FALSE, FALSE, sizeof (gint));
-		inserts_ids.pred_ids = g_array_new (FALSE, FALSE, sizeof (gint));
-		inserts_ids.object_ids = g_array_new (FALSE, FALSE, sizeof (gint));
-	}
-
-	if (deletes_ids.subject_ids == NULL) {
-		deletes_ids.subject_ids = g_array_new (FALSE, FALSE, sizeof (gint));
-		deletes_ids.pred_ids = g_array_new (FALSE, FALSE, sizeof (gint));
-		deletes_ids.object_ids = g_array_new (FALSE, FALSE, sizeof (gint));
-	}
-
 	tracker_events_classes_iter (&iter);
 
 	while (g_hash_table_iter_next (&iter, &key, &value)) {
 		TrackerClass *class = key;
-
-		g_array_set_size (deletes_ids.subject_ids, 0);
-		g_array_set_size (deletes_ids.pred_ids, 0);
-		g_array_set_size (deletes_ids.object_ids, 0);
-
-		tracker_events_get_deletes (tracker_class_get_id (class),
-		                            deletes_ids.subject_ids,
-		                            deletes_ids.pred_ids,
-		                            deletes_ids.object_ids);
-
-		g_array_set_size (inserts_ids.subject_ids, 0);
-		g_array_set_size (inserts_ids.pred_ids, 0);
-		g_array_set_size (inserts_ids.object_ids, 0);
-
-		tracker_events_get_inserts (tracker_class_get_id (class),
-		                            inserts_ids.subject_ids,
-		                            inserts_ids.pred_ids,
-		                            inserts_ids.object_ids);
-
-		if (inserts_ids.subject_ids->len > 0 || deletes_ids.subject_ids->len > 0) {
-			emit_class_signal (user_data, class, &deletes_ids, &inserts_ids);
-		}
+		emit_class_signal (user_data, class);
 	}
 
 	tracker_events_reset ();



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