[PATCH] emacs: call "notmuch tag" only once when archiving a thread

Jani Nikula jani at nikula.org
Tue Jan 3 10:29:06 PST 2012


Optimize thread archiving by combining all the -inbox tagging operations to
a single "notmuch tag" call. Also skip redisplay of tag changes in current
buffer, as it is immediately killed by the archiving functions.

For threads in the order of tens or a hundred inbox tagged messages, this
gives a noticeable speedup.

On the downside, IIRC Xapian does not perform very well if the query (in
this case a lot of message-ids OR'd together) is very big. It is unknown to
me at which point this approach would become slower than the original one
by one tagging approach, if ever.

Also, this introduces a limitation to the number of messages that can be
archived at the same time (through ARG_MAX limiting the command line). At
least on Linux this seems more like a theoretical limitation than a real
one.

Signed-off-by: Jani Nikula <jani at nikula.org>

---

On my Linux machines, 'getconf ARG_MAX' gives 2097152, leading me to
believe that notmuch-show would choke on the thread that would be limited
by this anyway...
---
 emacs/notmuch-show.el |   23 ++++++++++++++++++++---
 1 files changed, 20 insertions(+), 3 deletions(-)

diff --git a/emacs/notmuch-show.el b/emacs/notmuch-show.el
index 5502efd..b9ea839 100644
--- a/emacs/notmuch-show.el
+++ b/emacs/notmuch-show.el
@@ -1414,11 +1414,28 @@ argument, hide all of the messages."
   (interactive)
   (backward-button 1))
 
+(defun notmuch-show-thread-remove-tag (&rest toremove)
+  "Remove TOREMOVE tags from the current set of messages.
+
+Note: This function does not call `notmuch-show-set-tags' on the
+messages to redisplay the changed tags. This is meant to be
+called by `notmuch-show-archive-thread-internal' which kills the
+buffer afterwards."
+  (goto-char (point-min))
+  (let ((message-ids))
+    (loop do
+	  (let* ((current-tags (notmuch-show-get-tags))
+		 (new-tags (notmuch-show-del-tags-worker current-tags toremove)))
+	    (unless (equal current-tags new-tags)
+	      (add-to-list 'message-ids (notmuch-show-get-message-id))))
+	  until (not (notmuch-show-goto-message-next)))
+    (when message-ids
+      (apply 'notmuch-tag (mapconcat 'identity message-ids " OR ")
+	     (mapcar (lambda (s) (concat "-" s)) toremove)))))
+
 (defun notmuch-show-archive-thread-internal (show-next)
   ;; Remove the tag from the current set of messages.
-  (goto-char (point-min))
-  (loop do (notmuch-show-remove-tag "inbox")
-	until (not (notmuch-show-goto-message-next)))
+  (notmuch-show-thread-remove-tag "inbox")
   ;; Move to the next item in the search results, if any.
   (let ((parent-buffer notmuch-show-parent-buffer))
     (notmuch-kill-this-buffer)
-- 
1.7.5.4



More information about the notmuch mailing list