From eb7888cdb158fff7523af417a8984f48ae50c585 Mon Sep 17 00:00:00 2001 From: djcb Date: Sat, 23 Jul 2016 21:30:06 +0300 Subject: [PATCH] mu4e: support mu indexing performance options Add two variables mu4e-index-cleanup and mu4e-index-lazy-check, which correspond to mu index option --lazy-check and --nocleanup. Extend the mu server protocol a bit to handle this. The defaults keep things behaving as they done before. --- mu/mu-cmd-server.c | 57 +++++++++++++++++++++++++++------------------- mu4e/mu4e-proc.el | 6 +++-- mu4e/mu4e-utils.el | 5 +++- mu4e/mu4e-vars.el | 21 +++++++++++++++++ 4 files changed, 62 insertions(+), 27 deletions(-) diff --git a/mu/mu-cmd-server.c b/mu/mu-cmd-server.c index 61b9c5fb..a71b7369 100644 --- a/mu/mu-cmd-server.c +++ b/mu/mu-cmd-server.c @@ -63,24 +63,24 @@ static gboolean MU_TERMINATE; static void sig_handler (int sig) { - MU_TERMINATE = TRUE; + MU_TERMINATE = TRUE; } static void install_sig_handler (void) { - struct sigaction action; - int i, sigs[] = { SIGINT, SIGHUP, SIGTERM, SIGPIPE }; + struct sigaction action; + int i, sigs[] = { SIGINT, SIGHUP, SIGTERM, SIGPIPE }; - MU_TERMINATE = FALSE; + MU_TERMINATE = FALSE; - action.sa_handler = sig_handler; - sigemptyset(&action.sa_mask); - action.sa_flags = SA_RESETHAND; + action.sa_handler = sig_handler; + sigemptyset(&action.sa_mask); + action.sa_flags = SA_RESETHAND; - for (i = 0; i != G_N_ELEMENTS(sigs); ++i) - if (sigaction (sigs[i], &action, NULL) != 0) - g_critical ("set sigaction for %d failed: %s", + for (i = 0; i != G_N_ELEMENTS(sigs); ++i) + if (sigaction (sigs[i], &action, NULL) != 0) + g_critical ("set sigaction for %d failed: %s", sigs[i], strerror (errno));; } /************************************************************************/ @@ -235,7 +235,8 @@ get_string_from_args (GHashTable *args, const char *param, gboolean optional, } static gboolean -get_bool_from_args (GHashTable *args, const char *param, gboolean optional, GError **err) +get_bool_from_args (GHashTable *args, const char *param, gboolean optional, + GError **err) { const char *val; @@ -719,7 +720,7 @@ print_sexps (MuMsgIter *iter, unsigned maxnum) static MuError save_part (MuMsg *msg, unsigned docid, unsigned index, - MuMsgOptions opts, GHashTable *args, GError **err) + MuMsgOptions opts, GHashTable *args, GError **err) { gboolean rv; const gchar *path; @@ -745,7 +746,7 @@ save_part (MuMsg *msg, unsigned docid, unsigned index, static MuError open_part (MuMsg *msg, unsigned docid, unsigned index, - MuMsgOptions opts, GError **err) + MuMsgOptions opts, GError **err) { char *targetpath; gboolean rv; @@ -780,7 +781,7 @@ leave: static MuError temp_part (MuMsg *msg, unsigned docid, unsigned index, - MuMsgOptions opts, GHashTable *args, GError **err) + MuMsgOptions opts, GHashTable *args, GError **err) { const char *what, *param; char *path; @@ -1068,13 +1069,14 @@ get_checked_path (const char *path) static MuError -index_and_cleanup (MuIndex *index, const char *path, GError **err) +index_and_maybe_cleanup (MuIndex *index, const char *path, + gboolean cleanup, gboolean lazy_check, GError **err) { MuError rv; MuIndexStats stats, stats2; mu_index_stats_clear (&stats); - rv = mu_index_run (index, path, FALSE, &stats, + rv = mu_index_run (index, path, FALSE, lazy_check, &stats, index_msg_cb, NULL, NULL); if (rv != MU_OK && rv != MU_STOP) { @@ -1083,10 +1085,13 @@ index_and_cleanup (MuIndex *index, const char *path, GError **err) } mu_index_stats_clear (&stats2); - rv = mu_index_cleanup (index, &stats2, NULL, NULL, err); - if (rv != MU_OK && rv != MU_STOP) { - mu_util_g_set_error (err, MU_ERROR_INTERNAL, "cleanup failed"); - return rv; + if (cleanup) { + rv = mu_index_cleanup (index, &stats2, NULL, NULL, err); + if (rv != MU_OK && rv != MU_STOP) { + mu_util_g_set_error (err, MU_ERROR_INTERNAL, + "cleanup failed"); + return rv; + } } print_expr ("(:info index :status complete " @@ -1103,9 +1108,10 @@ index_and_cleanup (MuIndex *index, const char *path, GError **err) static MuError cmd_index (ServerContext *ctx, GHashTable *args, GError **err) { - MuIndex *index; - const char *argpath; - char *path; + MuIndex *index; + const char *argpath; + char *path; + gboolean cleanup, lazy_check; index = NULL; @@ -1119,7 +1125,10 @@ cmd_index (ServerContext *ctx, GHashTable *args, GError **err) if (!(index = mu_index_new (ctx->store, err))) goto leave; - index_and_cleanup (index, path, err); + cleanup = get_bool_from_args (args, "cleanup", TRUE, NULL); + lazy_check = get_bool_from_args (args, "lazy-check", TRUE, NULL); + + index_and_maybe_cleanup (index, path, cleanup, lazy_check, err); leave: g_free (path); diff --git a/mu4e/mu4e-proc.el b/mu4e/mu4e-proc.el index a2c4069f..d6d90e1b 100644 --- a/mu4e/mu4e-proc.el +++ b/mu4e/mu4e-proc.el @@ -27,6 +27,7 @@ (require 'mu4e-utils) (require 'mu4e-meta) + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; internal vars @@ -400,14 +401,15 @@ or (:error ) sexp, which are handled my `mu4e-update-func' and idparam (or flagstr "") (or path "") (format "newname:%s" rename)))) -(defun mu4e~proc-index (path my-addresses) +(defun mu4e~proc-index (path my-addresses cleanup lazy-check) "Update the message database for filesystem PATH, which should point to some maildir directory structure. MY-ADDRESSES is a list of 'my' email addresses (see `mu4e-user-mail-address-list')." (let ((path (mu4e~proc-escape path)) (addrs (when my-addresses (mapconcat 'identity my-addresses ",")))) (if addrs - (mu4e~proc-send-command "cmd:index path:%s my-addresses:%s" path addrs) + (mu4e~proc-send-command "cmd:index path:%s my-addresses:%s cleanup:%s lazy-check:%s" + path addrs (if cleanup "true" : "false") (if lazy-check "true")) (mu4e~proc-send-command "cmd:index path:%s" path)))) (defun mu4e~proc-add (path maildir) diff --git a/mu4e/mu4e-utils.el b/mu4e/mu4e-utils.el index 4a278d75..7e5fd3a1 100644 --- a/mu4e/mu4e-utils.el +++ b/mu4e/mu4e-utils.el @@ -911,7 +911,10 @@ Also scrolls to the final line, and update the progress throbber." (interactive) (unless mu4e-maildir (mu4e-error "`mu4e-maildir' is not defined")) - (mu4e~proc-index mu4e-maildir mu4e-user-mail-address-list)) + (mu4e~proc-index mu4e-maildir + mu4e-user-mail-address-list + mu4e-index-cleanup + mu4e-index-lazy-check)) (defvar mu4e~update-buffer nil "Internal, store the buffer of the update process when diff --git a/mu4e/mu4e-vars.el b/mu4e/mu4e-vars.el index 69b2a922..ac8545f5 100644 --- a/mu4e/mu4e-vars.el +++ b/mu4e/mu4e-vars.el @@ -90,6 +90,27 @@ background." :group 'mu4e :safe 'booleanp) +(defcustom mu4e-index-cleanup t + "Whether to run a cleanup face after indexing -- that is, see +if the is a message in the filesystem for each file in the +message store. Having this option as `t' ensures that no +non-existing mesages are shown but can also be quite slow with +large message stores." + :type 'boolean + :group 'mu4e + :safe 'booleanp) + +(defcustom mu4e-index-lazy-check nil + "Whether to run do a 'lazy check' for deciding whether to +indexing a message. When this is set to `t', mu only uses the +directory timestamps to decide on whether it needs to check the +messages beneath it, which would miss messages that are modified +outside mu. On the other hand, it's significantly faster." + :type 'boolean + :group 'mu4e + :safe 'booleanp) + + (defcustom mu4e-update-interval nil "Number of seconds between automatic calls to retrieve mail and update the database. If nil, don't update automatically. Note,