[balsa/58-filter-on-reception: 3/3] Various: Improve flag-only filtering
- From: Peter Bloomfield <peterb src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [balsa/58-filter-on-reception: 3/3] Various: Improve flag-only filtering
- Date: Mon, 23 Aug 2021 18:04:10 +0000 (UTC)
commit 307dca7feb7ebb1f6f49bd98d7007d01de50eea5
Author: Peter Bloomfield <PeterBloomfield bellsouth net>
Date: Fri Aug 20 15:44:06 2021 -0400
Various: Improve flag-only filtering
Make libbalsa_condition_is_flag_only() a clean test of the condition, with
no message matching. Introduce libbalsa_condition_try_flag_match()
which does message matching, with a return value that reports
whether the match is valid, but not necessarily whether the condition is
flag-only.
modified: libbalsa/filter.c
modified: libbalsa/filter.h
modified: libbalsa/mailbox.c
modified: libbalsa/mailbox_local.c
libbalsa/filter.c | 115 ++++++++++++++++++++++++++++++++++-------------
libbalsa/filter.h | 7 +--
libbalsa/mailbox.c | 22 ++++-----
libbalsa/mailbox_local.c | 5 +--
4 files changed, 99 insertions(+), 50 deletions(-)
---
diff --git a/libbalsa/filter.c b/libbalsa/filter.c
index 91ae2be81..7caa41eec 100644
--- a/libbalsa/filter.c
+++ b/libbalsa/filter.c
@@ -380,54 +380,107 @@ libbalsa_condition_can_match(LibBalsaCondition * cond,
}
}
-/* Check whether a condition looks only at flags; if it does, test
- * whether the given message's flags match it, and return the result in
- * *match; used by mailbox backends to decide when the full
- * LibBalsaMessage is needed. */
+/*
+ * libbalsa_condition_is_flag_only:
+ *
+ * Check whether a condition looks only at flags
+ */
gboolean
-libbalsa_condition_is_flag_only(LibBalsaCondition * cond,
- LibBalsaMailbox * mailbox,
- guint msgno,
- gboolean * match)
+libbalsa_condition_is_flag_only(LibBalsaCondition * cond)
{
gboolean retval;
- gboolean left_match, right_match;
+
+ g_return_val_if_fail(cond != NULL, FALSE);
switch (cond->type) {
case CONDITION_FLAG:
- if (match)
- *match =
- libbalsa_mailbox_msgno_has_flags(mailbox, msgno,
- cond->match.flags, 0);
retval = TRUE;
break;
+
+ case CONDITION_AND:
+ case CONDITION_OR:
+ retval = (libbalsa_condition_is_flag_only(cond->match.andor.left) &&
+ libbalsa_condition_is_flag_only(cond->match.andor.right));
+ break;
+
+ default:
+ retval = FALSE;
+ }
+
+ return retval;
+}
+
+/*
+ * libbalsa_condition_try_flag_match:
+ *
+ * Try to decide whether a message matches the given condition,
+ * using only the message flags.
+ *
+ * Returns TRUE if the result was returned in *match. Note that this does
+ * not necessarily mean that the condition is completely flag-only.
+ * A FALSE return means that the match could not be decided using only
+ * message flags. The full LibBalsaMessage will be needed to decide the
+ * match.
+ */
+gboolean
+libbalsa_condition_try_flag_match(LibBalsaCondition *cond,
+ LibBalsaMailbox *mailbox,
+ guint msgno,
+ gboolean *match)
+{
+ gboolean retval;
+ gboolean tmp_match;
+
+ g_return_val_if_fail(cond != NULL, FALSE);
+ g_return_val_if_fail(LIBBALSA_IS_MAILBOX(mailbox), FALSE);
+ g_return_val_if_fail(msgno > 0 && msgno <= libbalsa_mailbox_total_messages(mailbox), FALSE);
+ g_return_val_if_fail(match != NULL, FALSE);
+
+ switch (cond->type) {
+ case CONDITION_FLAG:
+ *match = libbalsa_mailbox_msgno_has_flags(mailbox, msgno, cond->match.flags, 0);
+ retval = TRUE;
+ break;
+
case CONDITION_AND:
retval =
- libbalsa_condition_is_flag_only(cond->match.andor.left,
- mailbox, msgno,
- match ? &left_match : NULL)
- && libbalsa_condition_is_flag_only(cond->match.andor.right,
- mailbox, msgno,
- match ? &right_match : NULL);
- if (retval && match)
- *match = left_match && right_match;
+ libbalsa_condition_try_flag_match(cond->match.andor.left, mailbox, msgno, &tmp_match);
+
+ if (retval) {
+ if (tmp_match) {
+ /* Left match succeeds, must check right condition */
+ retval =
+ libbalsa_condition_try_flag_match(cond->match.andor.right,
+ mailbox, msgno, &tmp_match);
+ }
+ if (retval)
+ *match = tmp_match;
+ }
+
break;
+
case CONDITION_OR:
retval =
- libbalsa_condition_is_flag_only(cond->match.andor.left,
- mailbox, msgno,
- match ? &left_match : NULL)
- && libbalsa_condition_is_flag_only(cond->match.andor.right,
- mailbox, msgno,
- match ? &right_match : NULL);
- if (retval && match)
- *match = left_match || right_match;
+ libbalsa_condition_try_flag_match(cond->match.andor.left, mailbox, msgno, &tmp_match);
+
+ if (retval) {
+ if (!tmp_match) {
+ /* Left match fails, must check right condition */
+ retval =
+ libbalsa_condition_try_flag_match(cond->match.andor.right,
+ mailbox, msgno, &tmp_match);
+ }
+ if (retval)
+ *match = tmp_match;
+ }
+
break;
+
default:
- return FALSE;
+ retval = FALSE;
}
- if (retval && match && cond->negate)
+ if (retval && cond->negate)
*match = !*match;
return retval;
diff --git a/libbalsa/filter.h b/libbalsa/filter.h
index 120e4931b..cbd8186d1 100644
--- a/libbalsa/filter.h
+++ b/libbalsa/filter.h
@@ -278,9 +278,10 @@ void filter_perror(const gchar * s);
/* Test */
gboolean libbalsa_condition_can_match(LibBalsaCondition * cond,
LibBalsaMessage * message);
-gboolean libbalsa_condition_is_flag_only(LibBalsaCondition * cond,
- LibBalsaMailbox * mailbox,
- guint msgno, gboolean * match);
+gboolean libbalsa_condition_is_flag_only(LibBalsaCondition * cond);
+gboolean libbalsa_condition_try_flag_match(LibBalsaCondition * cond,
+ LibBalsaMailbox * mailbox,
+ guint msgno, gboolean * match);
/* Compatibility */
LibBalsaCondition *libbalsa_condition_new_2_0(const gchar *
diff --git a/libbalsa/mailbox.c b/libbalsa/mailbox.c
index 9c13f774f..ad959795e 100644
--- a/libbalsa/mailbox.c
+++ b/libbalsa/mailbox.c
@@ -810,8 +810,8 @@ libbalsa_mailbox_changed(LibBalsaMailbox * mailbox)
/* libbalsa_mailbox_message_match:
* Tests if message with msgno matches the conditions cached in the
* search_iter: this is used
- by the search code. It is a "virtual method", indeed IMAP has a
- special way to implement it for speed/bandwidth reasons
+ * by the search code. It is a "virtual method", indeed IMAP has a
+ * special way to implement it for speed/bandwidth reasons
*/
static gboolean
@@ -822,13 +822,11 @@ lbm_message_match(LibBalsaMailbox *mailbox,
LibBalsaMailboxPrivate *priv = libbalsa_mailbox_get_instance_private(mailbox);
gboolean match;
- if (libbalsa_condition_is_flag_only(search_iter->condition,
- mailbox, msgno, &match))
- return match;
-
- priv->must_cache_message = TRUE;
- match = LIBBALSA_MAILBOX_GET_CLASS(mailbox)->message_match(mailbox, msgno, search_iter);
- priv->must_cache_message = FALSE;
+ if (!libbalsa_condition_try_flag_match(search_iter->condition, mailbox, msgno, &match)) {
+ priv->must_cache_message = TRUE;
+ match = LIBBALSA_MAILBOX_GET_CLASS(mailbox)->message_match(mailbox, msgno, search_iter);
+ priv->must_cache_message = FALSE;
+ }
return match;
}
@@ -913,8 +911,7 @@ lbm_run_filters_on_reception_idle_cb(LibBalsaMailbox * mailbox)
LibBalsaFilter *filter = lst->data;
if (filter->condition
- && !libbalsa_condition_is_flag_only(filter->condition, NULL, 0,
- NULL))
+ && !libbalsa_condition_is_flag_only(filter->condition))
++progress_count;
}
@@ -936,8 +933,7 @@ lbm_run_filters_on_reception_idle_cb(LibBalsaMailbox * mailbox)
if (filter->condition == NULL)
continue;
- use_progress = !libbalsa_condition_is_flag_only(filter->condition,
- NULL, 0, NULL);
+ use_progress = !libbalsa_condition_is_flag_only(filter->condition);
search_iter = libbalsa_mailbox_search_iter_new(filter->condition);
diff --git a/libbalsa/mailbox_local.c b/libbalsa/mailbox_local.c
index f16959bf1..6be46e760 100644
--- a/libbalsa/mailbox_local.c
+++ b/libbalsa/mailbox_local.c
@@ -366,8 +366,7 @@ libbalsa_mailbox_local_load_message(LibBalsaMailboxLocal * local,
view_filter = libbalsa_mailbox_get_view_filter(mailbox, FALSE);
if (view_filter == NULL)
match = TRUE;
- else if (!libbalsa_condition_is_flag_only(view_filter,
- mailbox, msgno, &match))
+ else if (!libbalsa_condition_try_flag_match(view_filter, mailbox, msgno, &match))
match = message_match_real(mailbox, msgno, view_filter);
if (match)
@@ -1290,7 +1289,7 @@ lbm_local_update_view_filter(LibBalsaMailbox * mailbox,
total = libbalsa_mailbox_total_messages(mailbox);
if (view_filter
- && !libbalsa_condition_is_flag_only(view_filter, NULL, 0, NULL)) {
+ && !libbalsa_condition_is_flag_only(view_filter)) {
gchar *text;
text = g_strdup_printf(_("Filtering %s"), libbalsa_mailbox_get_name(mailbox));
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]