[tracker/signals: 3/3] tracker-store: Use hash tables to check for event duplicates



commit b1bf6c352302e14ee2255af8534c62f8e7895bba
Author: Jürg Billeter <j bitron ch>
Date:   Tue Jun 29 17:18:07 2010 +0200

    tracker-store: Use hash tables to check for event duplicates

 src/tracker-store/tracker-resource-class.c |  111 ++++++++++-----------------
 1 files changed, 41 insertions(+), 70 deletions(-)
---
diff --git a/src/tracker-store/tracker-resource-class.c b/src/tracker-store/tracker-resource-class.c
index 56b9fc1..9f3f308 100644
--- a/src/tracker-store/tracker-resource-class.c
+++ b/src/tracker-store/tracker-resource-class.c
@@ -41,7 +41,7 @@
 typedef struct {
 	gchar *rdf_class;
 	gchar *dbus_path;
-	GPtrArray *adds, *dels;
+	GHashTable *adds_table, *ups_table, *dels_table;
 	GArray *ups;
 	GStringChunk *changed_strings;
 	DBusConnection *connection;
@@ -124,18 +124,19 @@ tracker_resource_class_init (TrackerResourceClass *object)
 
 static void
 emit_strings (TrackerResourceClass *object,
-              const gchar *signal_name,
-              GPtrArray *array)
+              const gchar          *signal_name,
+              GHashTable           *table)
 {
 	TrackerResourceClassPrivate *priv;
 
 	priv = TRACKER_RESOURCE_CLASS_GET_PRIVATE (object);
 
-	if (array->len > 0) {
+	if (g_hash_table_size (table) > 0) {
+		GHashTableIter table_iter;
+		gpointer key, value;
 		DBusMessageIter iter;
 		DBusMessageIter strv_iter;
 		DBusMessage *message;
-		guint i;
 
 		message = dbus_message_new_signal (priv->dbus_path,
 		                                   TRACKER_RESOURCES_CLASS_INTERFACE,
@@ -146,8 +147,9 @@ emit_strings (TrackerResourceClass *object,
 		dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY, 
 		                                  DBUS_TYPE_STRING_AS_STRING, &strv_iter);
 
-		for (i = 0; i < array->len; i++) {
-			dbus_message_iter_append_basic (&strv_iter, DBUS_TYPE_STRING, &array->pdata [i]);
+		g_hash_table_iter_init (&table_iter, table);
+		while (g_hash_table_iter_next (&table_iter, &key, &value)) {
+			dbus_message_iter_append_basic (&strv_iter, DBUS_TYPE_STRING, &key);
 		}
 
 		dbus_message_iter_close_container (&iter, &strv_iter);
@@ -224,22 +226,24 @@ tracker_resource_class_emit_events (TrackerResourceClass  *object)
 
 	priv = TRACKER_RESOURCE_CLASS_GET_PRIVATE (object);
 
-	if (priv->adds) {
-		emit_strings (object, "SubjectsAdded", priv->adds);
-		g_ptr_array_free (priv->adds, TRUE);
-		priv->adds = NULL;
+	if (priv->adds_table) {
+		emit_strings (object, "SubjectsAdded", priv->adds_table);
+		g_hash_table_unref (priv->adds_table);
+		priv->adds_table = NULL;
 	}
 
 	if (priv->ups) {
 		emit_changed_strings (object, priv->ups);
 		free_changed_array (priv->ups);
+		g_hash_table_unref (priv->ups_table);
 		priv->ups = NULL;
+		priv->ups_table = NULL;
 	}
 
-	if (priv->dels) {
-		emit_strings (object, "SubjectsRemoved", priv->dels);
-		g_ptr_array_free (priv->dels, TRUE);
-		priv->dels = NULL;
+	if (priv->dels_table) {
+		emit_strings (object, "SubjectsRemoved", priv->dels_table);
+		g_hash_table_unref (priv->dels_table);
+		priv->dels_table = NULL;
 	}
 
 	if (priv->changed_strings) {
@@ -297,50 +301,6 @@ tracker_resource_class_get_rdf_class (TrackerResourceClass  *object)
 	return priv->rdf_class;
 }
 
-static gboolean
-has_already (GPtrArray *array, const gchar *uri)
-{
-	guint i;
-
-	if (!array) {
-		return FALSE;
-	}
-
-	for (i = 0; i < array->len; i++) {
-		const gchar *a_uri = g_ptr_array_index (array, i);
-
-		/* This works because of how we use the GStringChunk */
-		if (a_uri == uri) {
-			return TRUE;
-		}
-	}
-
-	return FALSE;
-}
-
-static gboolean
-has_already_updated (GArray          *array,
-                     const gchar     *uri,
-                     TrackerProperty *predicate)
-{
-	guint i;
-
-	if (!array) {
-		return FALSE;
-	}
-
-	for (i = 0; i < array->len; i++) {
-		ChangedItem *item = &g_array_index (array, ChangedItem, i);
-
-		/* This works for uri because of how we use the GStringChunk */
-		if (item->predicate == predicate && item->uri == uri) {
-			return TRUE;
-		}
-	}
-
-	return FALSE;
-}
-
 void
 tracker_resource_class_add_event (TrackerResourceClass  *object,
                                   const gchar           *uri,
@@ -349,6 +309,7 @@ tracker_resource_class_add_event (TrackerResourceClass  *object,
 {
 	TrackerResourceClassPrivate *priv;
 	gchar *n_uri;
+	gpointer hash_key;
 
 	priv = TRACKER_RESOURCE_CLASS_GET_PRIVATE (object);
 
@@ -362,35 +323,45 @@ tracker_resource_class_add_event (TrackerResourceClass  *object,
 
 		n_uri = g_string_chunk_insert_const (priv->changed_strings, uri);
 
-		if (!has_already (priv->adds, n_uri)) {
-			if (!priv->adds)
-				priv->adds = g_ptr_array_new ();
-			g_ptr_array_add (priv->adds, n_uri);
+		if (!priv->adds_table) {
+			priv->adds_table = g_hash_table_new (NULL, NULL);
+		}
+
+		if (!g_hash_table_lookup (priv->adds_table, n_uri)) {
+			g_hash_table_insert (priv->adds_table, n_uri, GINT_TO_POINTER (TRUE));
 		}
 		break;
 	case TRACKER_DBUS_EVENTS_TYPE_UPDATE:
 
 		n_uri = g_string_chunk_insert_const (priv->changed_strings, uri);
 
-		if (!has_already_updated (priv->ups, n_uri, predicate)) {
+		if (!priv->ups) {
+			priv->ups = g_array_new (FALSE, TRUE, sizeof (ChangedItem));
+			priv->ups_table = g_hash_table_new (NULL, NULL);
+		}
+
+		hash_key = (gpointer) ((gsize) n_uri ^ (gsize) predicate);
+
+		if (!g_hash_table_lookup (priv->ups_table, hash_key)) {
 			ChangedItem item;
 
 			item.uri = n_uri;
 			item.predicate = g_object_ref (predicate);
 
-			if (!priv->ups)
-				priv->ups = g_array_new (FALSE, TRUE, sizeof (ChangedItem));
 			g_array_append_val (priv->ups, item);
+			g_hash_table_insert (priv->ups_table, hash_key, GINT_TO_POINTER (TRUE));
 		}
 		break;
 	case TRACKER_DBUS_EVENTS_TYPE_DELETE:
 
 		n_uri = g_string_chunk_insert_const (priv->changed_strings, uri);
 
-		if (!has_already (priv->dels, n_uri)) {
-			if (!priv->dels)
-				priv->dels = g_ptr_array_new ();
-			g_ptr_array_add (priv->dels, n_uri);
+		if (!priv->dels_table) {
+			priv->dels_table = g_hash_table_new (NULL, NULL);
+		}
+
+		if (!g_hash_table_lookup (priv->dels_table, n_uri)) {
+			g_hash_table_insert (priv->dels_table, n_uri, GINT_TO_POINTER (TRUE));
 		}
 		break;
 	default:



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