Commit 38964d1d authored by Milan Crha's avatar Milan Crha

I#821 - Slow message search

Closes #821
parent 44c489de
......@@ -38,19 +38,12 @@ filter_code_build_code (EFilterElement *element,
{
GList *l;
EFilterInput *fi = (EFilterInput *) element;
gboolean is_rawcode = fi->type && g_str_equal (fi->type, "rawcode");
if (!is_rawcode)
g_string_append (out, "(match-all ");
l = fi->values;
while (l) {
g_string_append (out, (gchar *) l->data);
l = g_list_next (l);
}
if (!is_rawcode)
g_string_append (out, ")");
}
/* and we have no value */
......
......@@ -831,6 +831,9 @@ filter_rule_build_code (EFilterRule *rule,
break;
}
if (rule->threading != E_FILTER_THREAD_NONE)
g_string_append (out, "(match-all ");
switch (rule->grouping) {
case E_FILTER_GROUP_ALL:
g_string_append (out, " (and\n ");
......@@ -846,7 +849,7 @@ filter_rule_build_code (EFilterRule *rule,
g_string_append (out, ")\n");
if (rule->threading != E_FILTER_THREAD_NONE)
g_string_append (out, ")\n");
g_string_append (out, "))\n");
}
static void
......
......@@ -235,7 +235,8 @@ vfolder_setup (CamelSession *session,
m = mail_msg_new (&vfolder_setup_info);
m->session = g_object_ref (session);
m->folder = g_object_ref (folder);
m->query = g_strdup (query);
/* Make sure the query is enclosed in "(match-all ...)", to traverse the folders' content */
m->query = (!query || g_str_has_prefix (query, "(match-all ") || strstr (query, "(match-threads ")) ? g_strdup (query) : g_strconcat ("(match-all ", query, ")", NULL);
m->sources_uri = sources_uri;
camel_folder_freeze (m->folder);
......
......@@ -80,7 +80,7 @@ mail_ffe_build_header_sexp (const gchar *word,
}
for (ii = 0; header_names[ii]; ii++) {
g_string_append_printf (sexp, "(match-all (header-%s \"%s\" %s))", compare_type, header_names[ii], encoded_word->str);
g_string_append_printf (sexp, "(header-%s \"%s\" %s)", compare_type, header_names[ii], encoded_word->str);
}
if (header_names[1])
......@@ -192,7 +192,7 @@ mail_ffe_exists (const gchar *word,
encoded_word = g_string_new ("");
camel_sexp_encode_string (encoded_word, word);
sexp = g_strdup_printf ("(match-all (header-exists %s))", encoded_word->str);
sexp = g_strdup_printf ("(header-exists %s)", encoded_word->str);
g_string_free (encoded_word, TRUE);
......@@ -213,7 +213,7 @@ mail_ffe_tag (const gchar *word,
encoded_word = g_string_new ("");
camel_sexp_encode_string (encoded_word, word);
sexp = g_strdup_printf ("(match-all (not (= (user-tag %s) \"\")))", encoded_word->str);
sexp = g_strdup_printf ("(not (= (user-tag %s) \"\"))", encoded_word->str);
g_string_free (encoded_word, TRUE);
......@@ -253,13 +253,13 @@ mail_ffe_flag (const gchar *word,
if (g_ascii_strcasecmp (flag, "Attachment") == 0)
flag = "Attachments";
sexp = g_strdup_printf ("(match-all (system-flag \"%s\"))", flag);
sexp = g_strdup_printf ("(system-flag \"%s\")", flag);
break;
}
}
if (!sexp)
sexp = g_strdup_printf ("(match-all (not (= (user-tag %s) \"\")))", encoded_word->str);
sexp = g_strdup_printf ("(not (= (user-tag %s) \"\"))", encoded_word->str);
g_string_free (encoded_word, TRUE);
......@@ -280,7 +280,7 @@ mail_ffe_label (const gchar *word,
encoded_word = g_string_new ("");
camel_sexp_encode_string (encoded_word, word);
sexp = g_strdup_printf ("(match-all (or ((= (user-tag \"label\") %s) (user-flag (+ \"$Label\" %s)) (user-flag %s)))",
sexp = g_strdup_printf ("(or (= (user-tag \"label\") %s) (user-flag (+ \"$Label\" %s)) (user-flag %s))",
encoded_word->str, encoded_word->str, encoded_word->str);
g_string_free (encoded_word, TRUE);
......@@ -309,7 +309,7 @@ mail_ffe_size (const gchar *word,
encoded_word = g_string_new ("");
camel_sexp_encode_string (encoded_word, word);
sexp = g_strdup_printf ("(match-all (%s (get-size) (cast-int %s)))", cmp, encoded_word->str);
sexp = g_strdup_printf ("(%s (get-size) (cast-int %s))", cmp, encoded_word->str);
g_string_free (encoded_word, TRUE);
......@@ -337,7 +337,7 @@ mail_ffe_score (const gchar *word,
encoded_word = g_string_new ("");
camel_sexp_encode_string (encoded_word, word);
sexp = g_strdup_printf ("(match-all (%s (cast-int (user-tag \"score\")) (cast-int %s)))", cmp, encoded_word->str);
sexp = g_strdup_printf ("(%s (cast-int (user-tag \"score\")) (cast-int %s))", cmp, encoded_word->str);
g_string_free (encoded_word, TRUE);
......@@ -442,14 +442,14 @@ mail_ffe_process_date (const gchar *get_date_fnc,
rel_days = g_ascii_strtoll (word, &endptr, 10);
if (rel_days != 0 && endptr && !*endptr) {
return g_strdup_printf ("(match-all (%s (compare-date (%s) (%s (get-current-date) %" G_GINT64_FORMAT ")) 0))", op, get_date_fnc,
return g_strdup_printf ("(%s (compare-date (%s) (%s (get-current-date) %" G_GINT64_FORMAT ")) 0)", op, get_date_fnc,
rel_days < 0 ? "+" : "-", (rel_days < 0 ? -1 : 1) * rel_days * 24 * 60 * 60);
}
if (!mail_ffe_decode_date_time (word, &tv))
return g_strdup_printf ("(match-all (%s (compare-date (%s) (get-current-date)) 0))", op, get_date_fnc);
return g_strdup_printf ("(%s (compare-date (%s) (get-current-date)) 0)", op, get_date_fnc);
return g_strdup_printf ("(match-all (%s (compare-date (%s) %" G_GINT64_FORMAT ") 0))", op, get_date_fnc, (gint64) tv.tv_sec);
return g_strdup_printf ("(%s (compare-date (%s) %" G_GINT64_FORMAT ") 0)", op, get_date_fnc, (gint64) tv.tv_sec);
}
static gchar *
......@@ -492,7 +492,7 @@ mail_ffe_attachment (const gchar *word,
is_neg = TRUE;
}
return g_strdup_printf ("(match-all %s(system-flag \"Attachments\")%s)", is_neg ? "(not " : "", is_neg ? ")" : "");
return g_strdup_printf ("%s(system-flag \"Attachments\")%s", is_neg ? "(not " : "", is_neg ? ")" : "");
}
static const EFreeFormExpSymbol mail_ffe_symbols[] = {
......
This diff is collapsed.
......@@ -6164,28 +6164,56 @@ message_list_regen_thread (GSimpleAsyncResult *simple,
if (hide_deleted && hide_junk) {
g_string_append_printf (
expr, "(match-all (and %s %s))",
expr, "(and %s %s)",
EXCLUDE_DELETED_MESSAGES_EXPR,
EXCLUDE_JUNK_MESSAGES_EXPR);
} else if (hide_deleted) {
g_string_append_printf (
expr, "(match-all %s)",
EXCLUDE_DELETED_MESSAGES_EXPR);
g_string_append (expr, EXCLUDE_DELETED_MESSAGES_EXPR);
} else if (hide_junk) {
g_string_append_printf (
expr, "(match-all %s)",
EXCLUDE_JUNK_MESSAGES_EXPR);
g_string_append (expr, EXCLUDE_JUNK_MESSAGES_EXPR);
}
/* The 'expr' should be enclosed in "(match-all ...)", thus the search traverses
folder content, but also try to not repeat it, to avoid unnecessary performance hits. */
if (regen_data->search != NULL) {
gboolean is_match_all = g_str_has_prefix (regen_data->search, "(match-all ");
gboolean is_match_threads = strstr (regen_data->search, "(match-threads ") != NULL;
if (expr->len == 0) {
g_string_assign (expr, regen_data->search);
} else {
g_string_prepend (expr, "(and ");
g_string_append_c (expr, ' ');
if (!is_match_all && !is_match_threads && expr->len) {
g_string_prepend (expr, "(match-all ");
g_string_append_c (expr, ')');
}
} else if (is_match_threads) {
/* The "match-threads" cannot be below "match-all". */
g_string_prepend (expr, "(and (match-all ");
g_string_append (expr, ") ");
g_string_append (expr, regen_data->search);
g_string_append_c (expr, ')');
} else {
g_string_prepend (expr, "(match-all (and ");
g_string_append_c (expr, ' ');
if (is_match_all) {
const gchar *stripped_search = regen_data->search + 11; /* strlen ("(match-all ") */
gint len = strlen (stripped_search);
if (len > 0 && stripped_search[len - 1] == ')') {
g_string_append_len (expr, stripped_search, len - 1);
} else {
g_string_append (expr, regen_data->search);
}
} else {
g_string_append (expr, regen_data->search);
}
g_string_append (expr, "))");
}
} else if (expr->len) {
g_string_prepend (expr, "(match-all ");
g_string_append_c (expr, ')');
}
/* Execute the search. */
......
This diff is collapsed.
This diff is collapsed.
......@@ -595,8 +595,12 @@ mail_shell_view_construct_filter_message_thread (EMailShellView *mail_shell_view
query = g_string_new ("");
if (with_query)
g_string_append_printf (query, "(and %s ", with_query);
if (with_query && *with_query) {
if (g_str_has_prefix (with_query, "(match-all ") || strstr (with_query, "(match-threads "))
g_string_append_printf (query, "(and %s ", with_query);
else
g_string_append_printf (query, "(and (match-all %s) ", with_query);
}
g_string_append (query, "(match-threads \"all\" (match-all (uid");
......@@ -611,7 +615,7 @@ mail_shell_view_construct_filter_message_thread (EMailShellView *mail_shell_view
g_string_append (query, ")))");
if (with_query)
if (with_query && *with_query)
g_string_append_c (query, ')');
return g_string_free (query, FALSE);
......@@ -748,6 +752,13 @@ filter:
/* Apply selected filter. */
if (query && *query && !g_str_has_prefix (query, "(match-all ") && !strstr (query, "(match-threads ")) {
/* Make sure the query is enclosed in "(match-all ...)", to traverse the folders' content */
temp = g_strconcat ("(match-all ", query, ")", NULL);
g_free (query);
query = temp;
}
combo_box = e_shell_searchbar_get_filter_combo_box (searchbar);
value = e_action_combo_box_get_current_value (combo_box);
......@@ -761,17 +772,22 @@ filter:
break;
case MAIL_FILTER_UNREAD_MESSAGES:
temp = g_strdup_printf (
"(and %s (match-all (not "
"(system-flag \"Seen\"))))", query);
if (query && *query) {
temp = g_strdup_printf ("(and %s (match-all (not (system-flag \"Seen\"))))", query);
} else {
temp = g_strdup ("(match-all (not (system-flag \"Seen\")))");
}
g_free (query);
query = temp;
break;
case MAIL_FILTER_NO_LABEL:
string = g_string_sized_new (1024);
g_string_append_printf (
string, "(and %s (and ", query);
if (query && *query)
g_string_append_printf (string, "(and %s (and ", query);
else
g_string_append (string, "(and ");
g_string_append (string, "(match-all ");
valid = gtk_tree_model_get_iter_first (
GTK_TREE_MODEL (label_store), &tree_iter);
while (valid) {
......@@ -781,10 +797,10 @@ filter:
if (g_str_has_prefix (use_tag, "$Label"))
use_tag += 6;
g_string_append_printf (
string, " (match-all (not (or "
string, " (not (or "
"(= (user-tag \"label\") \"%s\") "
"(user-flag \"$Label%s\") "
"(user-flag \"%s\"))))",
"(user-flag \"%s\")))",
use_tag, use_tag, use_tag);
g_free (tag);
......@@ -792,63 +808,71 @@ filter:
GTK_TREE_MODEL (label_store),
&tree_iter);
}
g_string_append_len (string, "))", 2);
if (query && *query)
g_string_append (string, ")))");
else
g_string_append (string, "))");
g_free (query);
query = g_string_free (string, FALSE);
break;
case MAIL_FILTER_READ_MESSAGES:
temp = g_strdup_printf (
"(and %s (match-all "
"(system-flag \"Seen\")))", query);
if (query && *query)
temp = g_strdup_printf ("(and %s (match-all (system-flag \"Seen\")))", query);
else
temp = g_strdup ("(match-all (system-flag \"Seen\"))");
g_free (query);
query = temp;
break;
case MAIL_FILTER_LAST_5_DAYS_MESSAGES:
case MAIL_FILTER_LAST_5_DAYS_MESSAGES: {
const gchar *date_ident;
if (em_utils_folder_is_sent (registry, folder))
temp = g_strdup_printf (
"(and %s (match-all "
"(> (get-sent-date) "
"(- (get-current-date) 432000))))",
query);
date_ident = "get-sent-date";
else
temp = g_strdup_printf (
"(and %s (match-all "
"(> (get-received-date) "
"(- (get-current-date) 432000))))",
query);
date_ident = "get-received-date";
if (query && *query)
temp = g_strdup_printf ("(and %s (match-all (> (%s) (- (get-current-date) 432000))))", query, date_ident);
else
temp = g_strdup_printf ("(match-all (> (%s) (- (get-current-date) 432000)))", date_ident);
g_free (query);
query = temp;
break;
} break;
case MAIL_FILTER_MESSAGES_WITH_ATTACHMENTS:
temp = g_strdup_printf (
"(and %s (match-all "
"(system-flag \"Attachments\")))", query);
if (query && *query)
temp = g_strdup_printf ("(and %s (match-all (system-flag \"Attachments\")))", query);
else
temp = g_strdup ("(match-all (system-flag \"Attachments\"))");
g_free (query);
query = temp;
break;
case MAIL_FILTER_MESSAGES_WITH_NOTES:
temp = g_strdup_printf (
"(and %s (match-all (user-flag \"$has_note\")))", query);
if (query && *query)
temp = g_strdup_printf ("(and %s (match-all (user-flag \"$has_note\")))", query);
else
temp = g_strdup ("(match-all (user-flag \"$has_note\"))");
g_free (query);
query = temp;
break;
case MAIL_FILTER_IMPORTANT_MESSAGES:
temp = g_strdup_printf (
"(and %s (match-all "
"(system-flag \"Flagged\")))", query);
if (query && *query)
temp = g_strdup_printf ("(and %s (match-all (system-flag \"Flagged\")))", query);
else
temp = g_strdup ("(match-all (system-flag \"Flagged\"))");
g_free (query);
query = temp;
break;
case MAIL_FILTER_MESSAGES_NOT_JUNK:
temp = g_strdup_printf (
"(and %s (match-all (not "
"(system-flag \"junk\"))))", query);
if (query && *query)
temp = g_strdup_printf ("(and %s (match-all (not (system-flag \"junk\"))))", query);
else
temp = g_strdup ("(match-all (not (system-flag \"junk\")))");
g_free (query);
query = temp;
break;
......@@ -875,12 +899,21 @@ filter:
use_tag = tag;
if (g_str_has_prefix (use_tag, "$Label"))
use_tag += 6;
temp = g_strdup_printf (
"(and %s (match-all (or "
"(= (user-tag \"label\") \"%s\") "
"(user-flag \"$Label%s\") "
"(user-flag \"%s\"))))",
query, use_tag, use_tag, use_tag);
if (query && *query) {
temp = g_strdup_printf (
"(and %s (match-all (or "
"(= (user-tag \"label\") \"%s\") "
"(user-flag \"$Label%s\") "
"(user-flag \"%s\"))))",
query, use_tag, use_tag, use_tag);
} else {
temp = g_strdup_printf (
"(match-all (or "
"(= (user-tag \"label\") \"%s\") "
"(user-flag \"$Label%s\") "
"(user-flag \"%s\")))",
use_tag, use_tag, use_tag);
}
g_free (tag);
g_free (query);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment