From 58f0ae7566c4a229787ee0ceef3cbf9504070c3f Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Wed, 1 Jun 2011 13:40:19 -0400 Subject: 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 c458cc7648..2f9cc9d9f0 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 fa6df8576e..ccbcbb10fe 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 c8e7babf5d..20c420a4f4 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); -- cgit v1.2.3