[evolution] EMVFolderRule: Track folder URIs in a GQueue instead of GList.



commit a81d49be2f6e6a9cf08734ae8b5a47ef46723e80
Author: Matthew Barnes <mbarnes redhat com>
Date:   Wed Jun 1 13:40:19 2011 -0400

    EMVFolderRule: Track folder URIs in a GQueue instead of GList.
    
    Makes the logic a little cleaner.  Do this also in mail-vfolder.c.

 mail/em-vfolder-rule.c |  106 ++++++++++++++++++++++++------------------------
 mail/em-vfolder-rule.h |    2 +-
 mail/mail-vfolder.c    |   84 +++++++++++++++++++------------------
 3 files changed, 97 insertions(+), 95 deletions(-)
---
diff --git a/mail/em-vfolder-rule.c b/mail/em-vfolder-rule.c
index c458cc7..2f9cc9d 100644
--- a/mail/em-vfolder-rule.c
+++ b/mail/em-vfolder-rule.c
@@ -145,9 +145,10 @@ static void
 vfolder_rule_finalize (GObject *object)
 {
 	EMVFolderRule *rule = EM_VFOLDER_RULE (object);
+	gchar *uri;
 
-	g_list_foreach (rule->sources, (GFunc) g_free, NULL);
-	g_list_free (rule->sources);
+	while ((uri = g_queue_pop_head (&rule->sources)) != NULL)
+		g_free (uri);
 
 	/* Chain up to parent's finalize() method. */
 	G_OBJECT_CLASS (em_vfolder_rule_parent_class)->finalize (object);
@@ -221,7 +222,7 @@ em_vfolder_rule_add_source (EMVFolderRule *rule,
 	g_return_if_fail (EM_IS_VFOLDER_RULE (rule));
 	g_return_if_fail (uri);
 
-	rule->sources = g_list_append (rule->sources, g_strdup (uri));
+	g_queue_push_tail (&rule->sources, g_strdup (uri));
 
 	e_filter_rule_emit_changed (E_FILTER_RULE (rule));
 }
@@ -230,20 +231,16 @@ const gchar *
 em_vfolder_rule_find_source (EMVFolderRule *rule,
                              const gchar *uri)
 {
-	GList *l;
+	GList *link;
 
 	g_return_val_if_fail (EM_IS_VFOLDER_RULE (rule), NULL);
 
 	/* only does a simple string or address comparison, should
 	   probably do a decoded url comparison */
-	l = rule->sources;
-	while (l) {
-		if (l->data == uri || !strcmp (l->data, uri))
-			return l->data;
-		l = l->next;
-	}
+	link = g_queue_find_custom (
+		&rule->sources, uri, (GCompareFunc) strcmp);
 
-	return NULL;
+	return (link != NULL) ? link->data : NULL;
 }
 
 void
@@ -255,8 +252,8 @@ em_vfolder_rule_remove_source (EMVFolderRule *rule,
 	g_return_if_fail (EM_IS_VFOLDER_RULE (rule));
 
 	found =(gchar *) em_vfolder_rule_find_source (rule, uri);
-	if (found) {
-		rule->sources = g_list_remove (rule->sources, found);
+	if (found != NULL) {
+		g_queue_remove (&rule->sources, found);
 		g_free (found);
 		e_filter_rule_emit_changed (E_FILTER_RULE (rule));
 	}
@@ -266,22 +263,19 @@ const gchar *
 em_vfolder_rule_next_source (EMVFolderRule *rule,
                              const gchar *last)
 {
-	GList *node;
+	GList *link;
 
 	if (last == NULL) {
-		node = rule->sources;
+		link = g_queue_peek_head_link (&rule->sources);
 	} else {
-		node = g_list_find (rule->sources, (gchar *) last);
-		if (node == NULL)
-			node = rule->sources;
+		link = g_queue_find (&rule->sources, last);
+		if (link == NULL)
+			link = g_queue_peek_head_link (&rule->sources);
 		else
-			node = g_list_next (node);
+			link = g_list_next (link);
 	}
 
-	if (node)
-		return (const gchar *) node->data;
-
-	return NULL;
+	return (link != NULL) ? link->data : NULL;
 }
 
 static gint
@@ -299,7 +293,7 @@ validate (EFilterRule *fr, EAlert **alert)
 	/* We have to have at least one source set in the "specific" case.
 	   Do not translate this string! */
 	if (((EMVFolderRule *) fr)->with == EM_VFOLDER_RULE_WITH_SPECIFIC &&
-		((EMVFolderRule *) fr)->sources == NULL) {
+		g_queue_is_empty (&((EMVFolderRule *) fr)->sources)) {
 		if (alert)
 			*alert = e_alert_new ("mail:vfolder-no-source", NULL);
 		return 0;
@@ -309,26 +303,35 @@ validate (EFilterRule *fr, EAlert **alert)
 }
 
 static gint
-list_eq (GList *al, GList *bl)
+queue_eq (GQueue *queue_a, GQueue *queue_b)
 {
+	GList *link_a;
+	GList *link_b;
 	gint truth = TRUE;
 
-	while (truth && al && bl) {
-		gchar *a = al->data, *b = bl->data;
+	link_a = g_queue_peek_head_link (queue_a);
+	link_b = g_queue_peek_head_link (queue_b);
+
+	while (truth && link_a != NULL && link_b != NULL) {
+		gchar *uri_a = link_a->data;
+		gchar *uri_b = link_b->data;
+
+		truth = (strcmp (uri_a, uri_b)== 0);
 
-		truth = strcmp (a, b)== 0;
-		al = al->next;
-		bl = bl->next;
+		link_a = g_list_next (link_a);
+		link_b = g_list_next (link_b);
 	}
 
-	return truth && al == NULL && bl == NULL;
+	return truth && link_a == NULL && link_b == NULL;
 }
 
 static gint
 vfolder_eq (EFilterRule *fr, EFilterRule *cm)
 {
 	return E_FILTER_RULE_CLASS (em_vfolder_rule_parent_class)->eq (fr, cm)
-		&& list_eq (((EMVFolderRule *) fr)->sources, ((EMVFolderRule *) cm)->sources);
+		&& queue_eq (
+			&((EMVFolderRule *) fr)->sources,
+			&((EMVFolderRule *) cm)->sources);
 }
 
 static xmlNodePtr
@@ -336,7 +339,7 @@ xml_encode (EFilterRule *fr)
 {
 	EMVFolderRule *vr =(EMVFolderRule *) fr;
 	xmlNodePtr node, set, work;
-	GList *l;
+	GList *head, *link;
 
 	node = E_FILTER_RULE_CLASS (em_vfolder_rule_parent_class)->xml_encode (fr);
 	g_return_val_if_fail (node != NULL, NULL);
@@ -345,12 +348,14 @@ xml_encode (EFilterRule *fr)
 	set = xmlNewNode(NULL, (const guchar *)"sources");
 	xmlAddChild (node, set);
 	xmlSetProp(set, (const guchar *)"with", (guchar *)with_names[vr->with]);
-	l = vr->sources;
-	while (l) {
-		work = xmlNewNode(NULL, (const guchar *)"folder");
-		xmlSetProp(work, (const guchar *)"uri", (guchar *)l->data);
+
+	head = g_queue_peek_head_link (&vr->sources);
+	for (link = head; link != NULL; link = g_list_next (link)) {
+		const gchar *uri = link->data;
+
+		work = xmlNewNode (NULL, (const guchar *) "folder");
+		xmlSetProp (work, (const guchar *) "uri", (guchar *) uri);
 		xmlAddChild (set, work);
-		l = l->next;
 	}
 
 	return node;
@@ -404,7 +409,7 @@ xml_decode (EFilterRule *fr, xmlNodePtr node, struct _ERuleContext *f)
 				if (!strcmp((gchar *)work->name, "folder")) {
 					tmp = (gchar *)xmlGetProp(work, (const guchar *)"uri");
 					if (tmp) {
-						vr->sources = g_list_append (vr->sources, g_strdup (tmp));
+						g_queue_push_tail (&vr->sources, g_strdup (tmp));
 						xmlFree (tmp);
 					}
 				}
@@ -420,23 +425,19 @@ static void
 rule_copy (EFilterRule *dest, EFilterRule *src)
 {
 	EMVFolderRule *vdest, *vsrc;
-	GList *node;
+	GList *head, *link;
+	gchar *uri;
 
 	vdest =(EMVFolderRule *) dest;
 	vsrc =(EMVFolderRule *) src;
 
-	if (vdest->sources) {
-		g_list_foreach (vdest->sources, (GFunc) g_free, NULL);
-		g_list_free (vdest->sources);
-		vdest->sources = NULL;
-	}
-
-	node = vsrc->sources;
-	while (node) {
-		gchar *uri = node->data;
+	while ((uri = g_queue_pop_head (&vdest->sources)) != NULL)
+		g_free (uri);
 
-		vdest->sources = g_list_append (vdest->sources, g_strdup (uri));
-		node = node->next;
+	head = g_queue_peek_head_link (&vsrc->sources);
+	for (link = head; link != NULL; link = g_list_next (link)) {
+		const gchar *uri = link->data;
+		g_queue_push_tail (&vdest->sources, g_strdup (uri));
 	}
 
 	vdest->with = vsrc->with;
@@ -569,8 +570,7 @@ vfr_folder_response (EMFolderSelector *selector,
 		GtkTreeSelection *selection;
 		GtkTreeIter iter;
 
-		data->vr->sources = g_list_append (
-			data->vr->sources, g_strdup (uri));
+		g_queue_push_tail (&data->vr->sources, g_strdup (uri));
 
 		gtk_list_store_append (data->model, &iter);
 		urinice = format_source (uri);
diff --git a/mail/em-vfolder-rule.h b/mail/em-vfolder-rule.h
index fa6df85..ccbcbb1 100644
--- a/mail/em-vfolder-rule.h
+++ b/mail/em-vfolder-rule.h
@@ -67,7 +67,7 @@ struct _EMVFolderRule {
 	EMVFolderRulePrivate *priv;
 
 	em_vfolder_rule_with_t with;
-	GList *sources;		/* uri's of the source folders */
+	GQueue sources;		/* uri's of the source folders */
 };
 
 struct _EMVFolderRuleClass {
diff --git a/mail/mail-vfolder.c b/mail/mail-vfolder.c
index c8e7bab..20c420a 100644
--- a/mail/mail-vfolder.c
+++ b/mail/mail-vfolder.c
@@ -60,8 +60,12 @@ CamelStore *vfolder_store; /* the 1 static vfolder store */
 /* lock for accessing shared resources (below) */
 G_LOCK_DEFINE_STATIC (vfolder);
 
-static GList *source_folders_remote;	/* list of source folder uri's - remote ones */
-static GList *source_folders_local;	/* list of source folder uri's - local ones */
+/* list of source folder uri's - remote ones */
+static GQueue source_folders_remote = G_QUEUE_INIT;
+
+/* list of source folder uri's - local ones */
+static GQueue source_folders_local = G_QUEUE_INIT;
+
 static GHashTable *vfolder_hash;
 /* This is a slightly hacky solution to shutting down, we poll this variable in various
    loops, and just quit processing if it is set. */
@@ -328,16 +332,21 @@ vfolder_adduri (EMailSession *session,
 /* ********************************************************************** */
 
 static GList *
-mv_find_folder (GList *l, EMailSession *session, const gchar *uri)
+mv_find_folder (GQueue *queue,
+                EMailSession *session,
+                const gchar *uri)
 {
 	CamelSession *camel_session = CAMEL_SESSION (session);
+	GList *head, *link;
 
-	while (l) {
-		if (e_mail_folder_uri_equal (camel_session, l->data, uri))
+	head = g_queue_peek_head_link (queue);
+
+	for (link = head; link != NULL; link = g_list_next (link)) {
+		if (e_mail_folder_uri_equal (camel_session, link->data, uri))
 			break;
-		l = l->next;
 	}
-	return l;
+
+	return link;
 }
 
 static gint
@@ -444,6 +453,7 @@ mail_vfolder_add_folder (EMailBackend *backend,
 	CamelVeeFolder *vf;
 	CamelProvider *provider;
 	GList *folders = NULL, *link;
+	GQueue *queue;
 	gint remote;
 	gint is_ignore;
 	gchar *uri;
@@ -452,6 +462,7 @@ mail_vfolder_add_folder (EMailBackend *backend,
 
 	provider = camel_service_get_provider (CAMEL_SERVICE (store));
 	remote = (provider->flags & CAMEL_PROVIDER_IS_REMOTE) != 0;
+	queue = remote ? &source_folders_remote : &source_folders_local;
 
 	if (folder_is_spethal (store, folder_name))
 		return;
@@ -468,30 +479,15 @@ mail_vfolder_add_folder (EMailBackend *backend,
 	if (CAMEL_IS_VEE_STORE (store)) {
 		is_ignore = TRUE;
 	} else if (remove) {
-		if (remote) {
-			if ((link = mv_find_folder (source_folders_remote, session, uri)) != NULL) {
-				g_free (link->data);
-				source_folders_remote = g_list_remove_link (
-					source_folders_remote, link);
-			}
-		} else {
-			if ((link = mv_find_folder (source_folders_local, session, uri)) != NULL) {
-				g_free (link->data);
-				source_folders_local = g_list_remove_link (
-					source_folders_local, link);
-			}
+		link = mv_find_folder (queue, session, uri);
+		if (link != NULL) {
+			g_free (link->data);
+			g_queue_delete_link (queue, link);
 		}
 	} else if (!is_ignore) {
 		/* we ignore drafts/sent/outbox here */
-		if (remote) {
-			if (mv_find_folder (source_folders_remote, session, uri) == NULL)
-				source_folders_remote = g_list_prepend (
-					source_folders_remote, g_strdup (uri));
-		} else {
-			if (mv_find_folder (source_folders_local, session, uri) == NULL)
-				source_folders_local = g_list_prepend (
-					source_folders_local, g_strdup (uri));
-		}
+		if (mv_find_folder (queue, session, uri) == NULL)
+			g_queue_push_tail (queue, g_strdup (uri));
 	}
 
 	if (context == NULL)
@@ -572,6 +568,7 @@ mail_vfolder_delete_folder (EMailBackend *backend,
 	const gchar *source;
 	CamelVeeFolder *vf;
 	GString *changed;
+	GQueue *queue;
 	guint changed_count;
 	gchar *uri;
 	GList *link;
@@ -639,14 +636,18 @@ mail_vfolder_delete_folder (EMailBackend *backend,
 	}
 
 done:
-	if ((link = mv_find_folder (source_folders_remote, session, uri)) != NULL) {
+	queue = &source_folders_remote;
+	link = mv_find_folder (queue, session, uri);
+	if (link != NULL) {
 		g_free (link->data);
-		source_folders_remote = g_list_remove_link (source_folders_remote, link);
+		g_queue_delete_link (queue, link);
 	}
 
-	if ((link = mv_find_folder (source_folders_local, session, uri)) != NULL) {
+	queue = &source_folders_local;
+	link = mv_find_folder (queue, session, uri);
+	if (link != NULL) {
 		g_free (link->data);
-		source_folders_local = g_list_remove_link (source_folders_local, link);
+		g_queue_delete_link (queue, link);
 	}
 
 	G_UNLOCK (vfolder);
@@ -761,13 +762,13 @@ mail_vfolder_rename_folder (CamelStore *store,
 GList *
 mail_vfolder_get_sources_local (void)
 {
-	return source_folders_local;
+	return g_queue_peek_head_link (&source_folders_local);
 }
 
 GList *
 mail_vfolder_get_sources_remote (void)
 {
-	return source_folders_remote;
+	return g_queue_peek_head_link (&source_folders_remote);
 }
 
 /* ********************************************************************** */
@@ -776,7 +777,7 @@ static void context_rule_added (ERuleContext *ctx, EFilterRule *rule);
 
 static void
 rule_add_sources (EMailSession *session,
-                  GList *l,
+                  GQueue *queue,
                   GList **sources_folderp,
                   GList **sources_urip)
 {
@@ -784,11 +785,13 @@ rule_add_sources (EMailSession *session,
 	GList *sources_uri = *sources_urip;
 	MailFolderCache *folder_cache;
 	CamelFolder *newfolder;
+	GList *head, *link;
 
 	folder_cache = e_mail_session_get_folder_cache (session);
 
-	while (l) {
-		const gchar *uri = l->data;
+	head = g_queue_peek_head_link (queue);
+	for (link = head; link != NULL; link = g_list_next (link)) {
+		const gchar *uri = link->data;
 
 		if (mail_folder_cache_get_folder_from_uri (
 			folder_cache, uri, &newfolder)) {
@@ -799,7 +802,6 @@ rule_add_sources (EMailSession *session,
 				sources_uri = g_list_append (
 					sources_uri, g_strdup (uri));
 		}
-		l = l->next;
 	}
 
 	*sources_folderp = sources_folder;
@@ -849,7 +851,7 @@ rule_changed (EFilterRule *rule, CamelFolder *folder)
 
 	/* find any (currently available) folders, and add them to the ones to open */
 	rule_add_sources (
-		session, ((EMVFolderRule *) rule)->sources,
+		session, &((EMVFolderRule *) rule)->sources,
 		&sources_folder, &sources_uri);
 
 	G_LOCK (vfolder);
@@ -858,14 +860,14 @@ rule_changed (EFilterRule *rule, CamelFolder *folder)
 			((EMVFolderRule *) rule)->with ==
 			EM_VFOLDER_RULE_WITH_LOCAL_REMOTE_ACTIVE)
 		rule_add_sources (
-			session, source_folders_local,
+			session, &source_folders_local,
 			&sources_folder, &sources_uri);
 	if (((EMVFolderRule *) rule)->with ==
 			EM_VFOLDER_RULE_WITH_REMOTE_ACTIVE ||
 			((EMVFolderRule *) rule)->with ==
 			EM_VFOLDER_RULE_WITH_LOCAL_REMOTE_ACTIVE)
 		rule_add_sources (
-			session, source_folders_remote,
+			session, &source_folders_remote,
 			&sources_folder, &sources_uri);
 	G_UNLOCK (vfolder);
 



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