[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

ELMO new IMAP search



Some time back ago egh proposed a substancial improvement for
filtering IMAP folders with multiple filter conditions.

http://lists.airs.net/wl/archive/201008/msg00105.html

Currently WL issues a SEARCH command for each single filter condition,
collects the message sets and then filters the sets according to the
filter condition operators (i.e. AND or OR).

The proposed modification abandons this client side filtering in favor
of composing a single SEARCH command that encodes the filter
condition. Thus the server does the work of filtering and only returns
the filtered message set to the client.

I run with this modification since March 2011 and did not
experience any problem with any of the IMAP servers at hand:

- Dovecot 1.2
- Courier IMAP 4.x (4.8 I think, its my mail provider's server)
- GoogleMail
- Kerio 6.5

I'd really like to see this modification in CVS trunk.

I created the dedicated branch

elmo-imap4-new-search

in CVS with the necessary patches applied and would ask users of WL to
test if the modified IMAP search works well with their IMAP servers.

Especially I'd like to ask users who happen to be struck with MS
Exchange to check if Exchange implements IMAP enough to perform SEARCH
operations with filter conditions.

The attached diff shows the differences between egh's original
modifications and some changes I made before committing to CVS.

Best,
  -- David
--
OpenPGP... 0x99ADB83B5A4478E6
Jabber.... dmjena@jabber.org
Email..... dmaus@ictsoc.de
--- /home/dmaus/projects/wanderlust/git-egh/elmo/elmo-imap4.el	2011-07-17 17:57:08.000000000 +0200
+++ elmo-imap4.el	2011-07-17 18:17:15.000000000 +0200
@@ -2308,16 +2322,14 @@
 		     0)
 		numbers)))
      ((string= "first" search-key)
-      (let* ((numbers (or from-msgs (elmo-folder-list-messages folder)))
-	     (rest (nthcdr (string-to-number (elmo-filter-value filter) )
-			   numbers)))
-	(mapcar '(lambda (x) (delete x numbers)) rest)
-	numbers))
+      (let ((numbers (or from-msgs (elmo-folder-list-messages folder))))
+	(elmo-list-difference
+	 (nthcdr (string-to-number (elmo-filter-value filter)) numbers) numbers)))
      ((string= "flag" search-key)
       (list nil
 	    (if (eq (elmo-filter-type filter) 'unmatch) "not " "")
@@ -2348,7 +2360,7 @@
           (encode-mime-charset-string
            (elmo-filter-value filter) charset))))))))
 
-(defun elmo-imap4-search-mergeable? (a b)
+(defun elmo-imap4-search-mergeable-p (a b)
   "Return t if A and B are two mergeable IMAP searches.
 
 A is the result of a call to elmo-imap4-search-generate.
@@ -2389,7 +2401,7 @@
 A search is either a list of UIDs or a list of the form (CHARSET
 IMAP-SEARCH-COMMAND ...) which is to be evaluated at a future
 time."
-  (if (elmo-imap4-search-mergeable? a b)
+  (if (elmo-imap4-search-mergeable-p a b)
       (append (list (elmo-imap4-search-mergeable-charset a b))
               (cdr a) '(" ") (cdr b))
     (elmo-list-filter (elmo-imap4-search-perform session a)
@@ -2405,7 +2417,7 @@
 A search is either a list of UIDs or a list of the form (CHARSET
 IMAP-SEARCH-COMMAND ...) which is to be evaluated at a future
 time."
-  (if (elmo-imap4-search-mergeable? a b)
+  (if (elmo-imap4-search-mergeable-p a b)
       (append (list (elmo-imap4-search-mergeable-charset a b))
               '("OR " "(") (cdr a) '(")" " " "(") (cdr b) '(")"))
     (elmo-uniq-list (append (elmo-imap4-search-perform session a)
--- /home/dmaus/projects/wanderlust/git-egh/elmo/elmo-util.el	2011-05-27 19:58:51.000000000 +0200
+++ elmo-util.el	2011-07-17 16:09:22.000000000 +0200
@@ -892,6 +892,14 @@
 	  (delete-directory path) ; should be removed if empty.
 	  ))))
 
+(defun elmo-list-difference (l1 l2)
+  "Return a list from L2 in which each element is not a member of L1."
+  (let (result)
+    (dolist (element l2)
+      (if (not (memq element l1))
+	  (setq result (cons element result))))
+    (nreverse result)))
+
 (defun elmo-list-filter (l1 l2)
   "Return a list from L2 in which each element is a member of L1."
   (let (result)

Attachment: pgpfT3GN9JXBc.pgp
Description: PGP signature