[evolution-data-server] Bug #720676 - [IMAPX] Do more searching server-side (take ][)
- From: Milan Crha <mcrha src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution-data-server] Bug #720676 - [IMAPX] Do more searching server-side (take ][)
- Date: Mon, 3 Feb 2014 14:33:54 +0000 (UTC)
commit 54b89c76803463c8c9d81091ec622f790eb22bcd
Author: Milan Crha <mcrha redhat com>
Date: Mon Feb 3 15:31:30 2014 +0100
Bug #720676 - [IMAPX] Do more searching server-side (take ][)
The first patch caused server-side searching also for cases where all
data were available locally, which made searching slower. This tests
first if everything in match-all is available locally, and if so, then
it uses local search, rather than the server side.
camel/providers/imapx/camel-imapx-search.c | 100 +++++++++++++++++++++++++++-
1 files changed, 98 insertions(+), 2 deletions(-)
---
diff --git a/camel/providers/imapx/camel-imapx-search.c b/camel/providers/imapx/camel-imapx-search.c
index 0afc644..64d3d44 100644
--- a/camel/providers/imapx/camel-imapx-search.c
+++ b/camel/providers/imapx/camel-imapx-search.c
@@ -28,6 +28,7 @@
struct _CamelIMAPXSearchPrivate {
GWeakRef server;
+ gint *local_data_search; /* not NULL, if testing whether all used headers are all locally available */
};
enum {
@@ -194,14 +195,48 @@ imapx_search_match_all (CamelSExp *sexp,
CamelSExpTerm **argv,
CamelFolderSearch *search)
{
+ CamelIMAPXSearch *imapx_search = CAMEL_IMAPX_SEARCH (search);
CamelIMAPXServer *server;
CamelSExpResult *result;
+ GPtrArray *summary;
+ gint local_data_search = 0, *prev_local_data_search, ii;
if (argc != 1)
return imapx_search_result_match_none (sexp, search);
server = camel_imapx_search_ref_server (CAMEL_IMAPX_SEARCH (search));
- if (!server || search->current) {
+ if (!server || search->current || !search->summary) {
+ g_clear_object (&server);
+
+ /* Chain up to parent's method. */
+ return CAMEL_FOLDER_SEARCH_CLASS (camel_imapx_search_parent_class)->
+ match_all (sexp, argc, argv, search);
+ }
+
+ /* First try to see whether all used headers are available locally - if
+ they are, then do not use server-side filtering at all. */
+ prev_local_data_search = imapx_search->priv->local_data_search;
+ imapx_search->priv->local_data_search = &local_data_search;
+
+ summary = search->summary_set ? search->summary_set : search->summary;
+
+ if (!CAMEL_IS_VEE_FOLDER (search->folder)) {
+ camel_folder_summary_prepare_fetch_all (search->folder->summary, NULL);
+ }
+
+ for (ii = 0; ii < summary->len; ii++) {
+ search->current = camel_folder_summary_get (search->folder->summary, summary->pdata[ii]);
+ if (search->current) {
+ result = camel_sexp_term_eval (sexp, argv[0]);
+ camel_sexp_result_free (sexp, result);
+ camel_message_info_unref (search->current);
+ search->current = NULL;
+ break;
+ }
+ }
+ imapx_search->priv->local_data_search = prev_local_data_search;
+
+ if (local_data_search >= 0) {
g_clear_object (&server);
/* Chain up to parent's method. */
@@ -227,11 +262,18 @@ imapx_search_body_contains (CamelSExp *sexp,
CamelSExpResult **argv,
CamelFolderSearch *search)
{
+ CamelIMAPXSearch *imapx_search = CAMEL_IMAPX_SEARCH (search);
CamelIMAPXServer *server;
CamelSExpResult *result;
GString *criteria;
gint ii, jj;
+ /* Always do body-search server-side */
+ if (imapx_search->priv->local_data_search) {
+ *imapx_search->priv->local_data_search = -1;
+ return imapx_search_result_match_none (sexp, search);
+ }
+
/* Match everything if argv = [""] */
if (argc == 1 && argv[0]->value.string[0] == '\0')
return imapx_search_result_match_all (sexp, search);
@@ -299,12 +341,22 @@ imapx_search_body_contains (CamelSExp *sexp,
return result;
}
+static gboolean
+imapx_search_is_header_from_summary (const gchar *header_name)
+{
+ return g_ascii_strcasecmp (header_name, "From") == 0 ||
+ g_ascii_strcasecmp (header_name, "To") == 0 ||
+ g_ascii_strcasecmp (header_name, "CC") == 0 ||
+ g_ascii_strcasecmp (header_name, "Subject") == 0;
+}
+
static CamelSExpResult *
imapx_search_header_contains (CamelSExp *sexp,
gint argc,
CamelSExpResult **argv,
CamelFolderSearch *search)
{
+ CamelIMAPXSearch *imapx_search = CAMEL_IMAPX_SEARCH (search);
CamelIMAPXServer *server;
CamelSExpResult *result;
const gchar *headername, *command = NULL;
@@ -317,6 +369,23 @@ imapx_search_header_contains (CamelSExp *sexp,
search->summary->len == 0)
return imapx_search_result_match_none (sexp, search);
+ headername = argv[0]->value.string;
+
+ if (imapx_search_is_header_from_summary (headername)) {
+ if (imapx_search->priv->local_data_search) {
+ if (*imapx_search->priv->local_data_search >= 0)
+ *imapx_search->priv->local_data_search =
(*imapx_search->priv->local_data_search) + 1;
+ return imapx_search_result_match_all (sexp, search);
+ }
+
+ /* Chain up to parent's method. */
+ return CAMEL_FOLDER_SEARCH_CLASS (camel_imapx_search_parent_class)->
+ header_contains (sexp, argc, argv, search);
+ } else if (imapx_search->priv->local_data_search) {
+ *imapx_search->priv->local_data_search = -1;
+ return imapx_search_result_match_none (sexp, search);
+ }
+
server = camel_imapx_search_ref_server (CAMEL_IMAPX_SEARCH (search));
/* This will be NULL if we're offline. Search from cache. */
@@ -338,7 +407,6 @@ imapx_search_header_contains (CamelSExp *sexp,
g_string_append_printf (criteria, "UID %s", uid);
}
- headername = argv[0]->value.string;
if (g_ascii_strcasecmp (headername, "From") == 0)
command = "FROM";
else if (g_ascii_strcasecmp (headername, "To") == 0)
@@ -399,6 +467,7 @@ imapx_search_header_exists (CamelSExp *sexp,
CamelSExpResult **argv,
CamelFolderSearch *search)
{
+ CamelIMAPXSearch *imapx_search = CAMEL_IMAPX_SEARCH (search);
CamelIMAPXServer *server;
CamelSExpResult *result;
GString *criteria;
@@ -408,6 +477,32 @@ imapx_search_header_exists (CamelSExp *sexp,
if (argc == 0 || search->summary->len == 0)
return imapx_search_result_match_none (sexp, search);
+ /* Check if asking for locally stored headers only */
+ for (ii = 0; ii < argc; ii++) {
+ if (argv[ii]->type != CAMEL_SEXP_RES_STRING)
+ continue;
+
+ if (!imapx_search_is_header_from_summary (argv[ii]->value.string))
+ break;
+ }
+
+ /* All headers are from summary */
+ if (ii == argc) {
+ if (imapx_search->priv->local_data_search) {
+ if (*imapx_search->priv->local_data_search >= 0)
+ *imapx_search->priv->local_data_search =
(*imapx_search->priv->local_data_search) + 1;
+
+ return imapx_search_result_match_all (sexp, search);
+ }
+
+ /* Chain up to parent's method. */
+ return CAMEL_FOLDER_SEARCH_CLASS (camel_imapx_search_parent_class)->
+ header_exists (sexp, argc, argv, search);
+ } else if (imapx_search->priv->local_data_search) {
+ *imapx_search->priv->local_data_search = -1;
+ return imapx_search_result_match_none (sexp, search);
+ }
+
server = camel_imapx_search_ref_server (CAMEL_IMAPX_SEARCH (search));
/* This will be NULL if we're offline. Search from cache. */
@@ -486,6 +581,7 @@ static void
camel_imapx_search_init (CamelIMAPXSearch *search)
{
search->priv = CAMEL_IMAPX_SEARCH_GET_PRIVATE (search);
+ search->priv->local_data_search = NULL;
}
/**
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]