aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLars Ingebrigtsen2015-01-26 04:18:57 +0000
committerKatsumi Yamaoka2015-01-26 04:18:57 +0000
commit8e39ec680c7068c2dc2143bf915e5acca7bf7c0f (patch)
tree89598639b850e639377adea7a877a1a1a5a40739
parent44df0a8f506db385473ed36c2a5fa26e06e7788d (diff)
downloademacs-8e39ec680c7068c2dc2143bf915e5acca7bf7c0f.tar.gz
emacs-8e39ec680c7068c2dc2143bf915e5acca7bf7c0f.zip
[Gnus] Make moving IMAP articles faster in large groups
-rw-r--r--lisp/gnus/ChangeLog15
-rw-r--r--lisp/gnus/gnus-group.el4
-rw-r--r--lisp/gnus/gnus-int.el8
-rw-r--r--lisp/gnus/nnimap.el117
4 files changed, 93 insertions, 51 deletions
diff --git a/lisp/gnus/ChangeLog b/lisp/gnus/ChangeLog
index 08e904adf48..e47e8ad282c 100644
--- a/lisp/gnus/ChangeLog
+++ b/lisp/gnus/ChangeLog
@@ -1,3 +1,18 @@
12015-01-26 Lars Ingebrigtsen <larsi@gnus.org>
2
3 * nnimap.el (nnimap-request-accept-article): Allow respooling using
4 nnimap.
5
6 * gnus-group.el (gnus-group-get-new-news-this-group): Explicitly
7 request rescans when being run interactively.
8
9 * nnimap.el (nnimap-request-group): Don't rescan the group here,
10 because that can be very slow in large groups.
11
12 * gnus-int.el (gnus-request-group-scan): New backend function.
13
14 * nnimap.el (nnimap-request-scan-group): Implement in on IMAP.
15
12015-01-25 Lars Ingebrigtsen <larsi@gnus.org> 162015-01-25 Lars Ingebrigtsen <larsi@gnus.org>
2 17
3 * gnus-group.el (gnus-group-suspend): Close all backends. 18 * gnus-group.el (gnus-group-suspend): Close all backends.
diff --git a/lisp/gnus/gnus-group.el b/lisp/gnus/gnus-group.el
index dc11442656d..e22138b7028 100644
--- a/lisp/gnus/gnus-group.el
+++ b/lisp/gnus/gnus-group.el
@@ -4075,7 +4075,9 @@ If DONT-SCAN is non-nil, scan non-activated groups as well."
4075 (gnus-group-remove-mark group) 4075 (gnus-group-remove-mark group)
4076 ;; Bypass any previous denials from the server. 4076 ;; Bypass any previous denials from the server.
4077 (gnus-remove-denial (setq method (gnus-find-method-for-group group))) 4077 (gnus-remove-denial (setq method (gnus-find-method-for-group group)))
4078 (if (gnus-activate-group group (if dont-scan nil 'scan) nil method) 4078 (if (or (and (not dont-scan)
4079 (gnus-request-group-scan group (gnus-get-info group)))
4080 (gnus-activate-group group (if dont-scan nil 'scan) nil method))
4079 (let ((info (gnus-get-info group)) 4081 (let ((info (gnus-get-info group))
4080 (active (gnus-active group))) 4082 (active (gnus-active group)))
4081 (when info 4083 (when info
diff --git a/lisp/gnus/gnus-int.el b/lisp/gnus/gnus-int.el
index 487b85f581d..dd938ce0758 100644
--- a/lisp/gnus/gnus-int.el
+++ b/lisp/gnus/gnus-int.el
@@ -439,6 +439,14 @@ If it is down, start it up (again)."
439 (funcall (gnus-get-function gnus-command-method func) 439 (funcall (gnus-get-function gnus-command-method func)
440 (gnus-group-real-name group) (nth 1 gnus-command-method))))) 440 (gnus-group-real-name group) (nth 1 gnus-command-method)))))
441 441
442(defun gnus-request-group-scan (group info)
443 "Request that GROUP get a complete rescan."
444 (let ((gnus-command-method (gnus-find-method-for-group group))
445 (func 'request-group-description))
446 (when (gnus-check-backend-function func group)
447 (funcall (gnus-get-function gnus-command-method func)
448 (gnus-group-real-name group) (nth 1 gnus-command-method) info))))
449
442(defun gnus-close-group (group) 450(defun gnus-close-group (group)
443 "Request the GROUP be closed." 451 "Request the GROUP be closed."
444 (let ((gnus-command-method (inline (gnus-find-method-for-group group)))) 452 (let ((gnus-command-method (inline (gnus-find-method-for-group group))))
diff --git a/lisp/gnus/nnimap.el b/lisp/gnus/nnimap.el
index f3a89574430..ced55619881 100644
--- a/lisp/gnus/nnimap.el
+++ b/lisp/gnus/nnimap.el
@@ -792,43 +792,55 @@ textual parts.")
792 articles active marks high low) 792 articles active marks high low)
793 (with-current-buffer nntp-server-buffer 793 (with-current-buffer nntp-server-buffer
794 (when result 794 (when result
795 (if (and dont-check 795 (when (or (not dont-check)
796 (setq active (nth 2 (assoc group nnimap-current-infos)))) 796 (not (setq active
797 (insert (format "211 %d %d %d %S\n" 797 (nth 2 (assoc group nnimap-current-infos)))))
798 (- (cdr active) (car active)) 798 (let ((sequences (nnimap-retrieve-group-data-early
799 (car active) 799 server (list info))))
800 (cdr active) 800 (nnimap-finish-retrieve-group-infos server (list info) sequences
801 group)) 801 t)
802 (with-current-buffer (nnimap-buffer) 802 (setq active (nth 2 (assoc group nnimap-current-infos)))))
803 (erase-buffer) 803 (insert (format "211 %d %d %d %S\n"
804 (let ((group-sequence 804 (- (cdr active) (car active))
805 (nnimap-send-command "SELECT %S" (utf7-encode group t))) 805 (car active)
806 (flag-sequence 806 (cdr active)
807 (nnimap-send-command "UID FETCH 1:* FLAGS"))) 807 group))
808 (setf (nnimap-group nnimap-object) group)
809 (nnimap-wait-for-response flag-sequence)
810 (setq marks
811 (nnimap-flags-to-marks
812 (nnimap-parse-flags
813 (list (list group-sequence flag-sequence
814 1 group "SELECT")))))
815 (when (and info
816 marks)
817 (nnimap-update-infos marks (list info))
818 (nnimap-store-info info (gnus-active (gnus-info-group info))))
819 (goto-char (point-max))
820 (let ((uidnext (nth 5 (car marks))))
821 (setq high (or (if uidnext
822 (1- uidnext)
823 (nth 3 (car marks)))
824 0)
825 low (or (nth 4 (car marks)) uidnext 1)))))
826 (erase-buffer)
827 (insert
828 (format
829 "211 %d %d %d %S\n" (1+ (- high low)) low high group)))
830 t)))) 808 t))))
831 809
810(deffoo nnimap-request-scan-group (group &optional server info)
811 (setq group (nnimap-decode-gnus-group group))
812 (let (marks high low)
813 (with-current-buffer (nnimap-buffer)
814 (erase-buffer)
815 (let ((group-sequence
816 (nnimap-send-command "SELECT %S" (utf7-encode group t)))
817 (flag-sequence
818 (nnimap-send-command "UID FETCH 1:* FLAGS")))
819 (setf (nnimap-group nnimap-object) group)
820 (nnimap-wait-for-response flag-sequence)
821 (setq marks
822 (nnimap-flags-to-marks
823 (nnimap-parse-flags
824 (list (list group-sequence flag-sequence
825 1 group "SELECT")))))
826 (when (and info
827 marks)
828 (nnimap-update-infos marks (list info))
829 (nnimap-store-info info (gnus-active (gnus-info-group info))))
830 (goto-char (point-max))
831 (let ((uidnext (nth 5 (car marks))))
832 (setq high (or (if uidnext
833 (1- uidnext)
834 (nth 3 (car marks)))
835 0)
836 low (or (nth 4 (car marks)) uidnext 1)))))
837 (with-current-buffer nntp-server-buffer
838 (erase-buffer)
839 (insert
840 (format
841 "211 %d %d %d %S\n" (1+ (- high low)) low high group))
842 t)))
843
832(deffoo nnimap-request-create-group (group &optional server args) 844(deffoo nnimap-request-create-group (group &optional server args)
833 (setq group (nnimap-decode-gnus-group group)) 845 (setq group (nnimap-decode-gnus-group group))
834 (when (nnimap-change-group nil server) 846 (when (nnimap-change-group nil server)
@@ -1122,8 +1134,11 @@ If LIMIT, first try to limit the search to the N last articles."
1122 (setq group 1134 (setq group
1123 (caar 1135 (caar
1124 (nnmail-article-group 1136 (nnmail-article-group
1137 ;; We don't really care about the article number, because
1138 ;; that's determined by the IMAP server later. So just
1139 ;; return the group name.
1125 `(lambda (group) 1140 `(lambda (group)
1126 (nnml-active-number group ,server)))))) 1141 (list (list group)))))))
1127 (setq group (nnimap-decode-gnus-group group)) 1142 (setq group (nnimap-decode-gnus-group group))
1128 (when (nnimap-change-group nil server) 1143 (when (nnimap-change-group nil server)
1129 (nnmail-check-syntax) 1144 (nnmail-check-syntax)
@@ -1371,7 +1386,8 @@ If LIMIT, first try to limit the search to the N last articles."
1371 command 1386 command
1372 (nth 2 quirk)))) 1387 (nth 2 quirk))))
1373 1388
1374(deffoo nnimap-finish-retrieve-group-infos (server infos sequences) 1389(deffoo nnimap-finish-retrieve-group-infos (server infos sequences
1390 &optional dont-insert)
1375 (when (and sequences 1391 (when (and sequences
1376 (nnimap-change-group nil server t) 1392 (nnimap-change-group nil server t)
1377 ;; Check that the process is still alive. 1393 ;; Check that the process is still alive.
@@ -1391,19 +1407,20 @@ If LIMIT, first try to limit the search to the N last articles."
1391 (nnimap-parse-flags 1407 (nnimap-parse-flags
1392 (nreverse sequences))) 1408 (nreverse sequences)))
1393 infos) 1409 infos)
1394 ;; Finally, just return something resembling an active file in 1410 (unless dont-insert
1395 ;; the nntp buffer, so that the agent can save the info, too. 1411 ;; Finally, just return something resembling an active file in
1396 (with-current-buffer nntp-server-buffer 1412 ;; the nntp buffer, so that the agent can save the info, too.
1397 (erase-buffer) 1413 (with-current-buffer nntp-server-buffer
1398 (dolist (info infos) 1414 (erase-buffer)
1399 (let* ((group (gnus-info-group info)) 1415 (dolist (info infos)
1400 (active (gnus-active group))) 1416 (let* ((group (gnus-info-group info))
1401 (when active 1417 (active (gnus-active group)))
1402 (insert (format "%S %d %d y\n" 1418 (when active
1403 (decode-coding-string 1419 (insert (format "%S %d %d y\n"
1404 (gnus-group-real-name group) 'utf-8) 1420 (decode-coding-string
1405 (cdr active) 1421 (gnus-group-real-name group) 'utf-8)
1406 (car active))))))))))) 1422 (cdr active)
1423 (car active))))))))))))
1407 1424
1408(defun nnimap-update-infos (flags infos) 1425(defun nnimap-update-infos (flags infos)
1409 (dolist (info infos) 1426 (dolist (info infos)