aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLars Magne Ingebrigtsen2010-09-05 00:34:16 +0000
committerKatsumi Yamaoka2010-09-05 00:34:16 +0000
commit8c3e17f87bb02b8a2b05f66948c28b08a89e6d87 (patch)
tree4c4abcd967c2ffa8a91b8e1df0fbc68fe45a5bea
parent6aeafb34372289081799c952bad2b80f19736be3 (diff)
downloademacs-8c3e17f87bb02b8a2b05f66948c28b08a89e6d87.tar.gz
emacs-8c3e17f87bb02b8a2b05f66948c28b08a89e6d87.zip
Rewrite the Gnus group activation method to be more efficient; nnmh.el (nnmh-request-list-1): Fix up the recursion behavior; Add more changes related to the new methodology for requesting backend data.
-rw-r--r--lisp/gnus/ChangeLog11
-rw-r--r--lisp/gnus/gnus-group.el24
-rw-r--r--lisp/gnus/gnus-int.el3
-rw-r--r--lisp/gnus/gnus-start.el176
-rw-r--r--lisp/gnus/mail-source.el7
-rw-r--r--lisp/gnus/nnmail.el7
-rw-r--r--lisp/gnus/nnmh.el33
-rw-r--r--lisp/gnus/nnvirtual.el4
8 files changed, 125 insertions, 140 deletions
diff --git a/lisp/gnus/ChangeLog b/lisp/gnus/ChangeLog
index c4a451248f6..a487b63ffed 100644
--- a/lisp/gnus/ChangeLog
+++ b/lisp/gnus/ChangeLog
@@ -1,5 +1,16 @@
12010-09-04 Lars Magne Ingebrigtsen <larsi@gnus.org> 12010-09-04 Lars Magne Ingebrigtsen <larsi@gnus.org>
2 2
3 * gnus-start.el (gnus-get-unread-articles): Rewrite the way we request
4 data from the backends, so that we only request the list of groups from
5 each method once. This should speed things up considerably.
6
7 * nnvirtual.el (nnvirtual-request-list): Remove function so that we can
8 detect that it's not implemented.
9
10 * nnmh.el (nnmh-request-list-1): Fix up the recursion behavior so that
11 we actually do recurse down into the tree, but don't stat all leaf
12 nodes.
13
3 * gnus-html.el (gnus-html-show-images): If there are no images to show, 14 * gnus-html.el (gnus-html-show-images): If there are no images to show,
4 then say so instead of bugging out. 15 then say so instead of bugging out.
5 16
diff --git a/lisp/gnus/gnus-group.el b/lisp/gnus/gnus-group.el
index 3d34fa7c002..5cc4ef68bd9 100644
--- a/lisp/gnus/gnus-group.el
+++ b/lisp/gnus/gnus-group.el
@@ -3982,23 +3982,13 @@ re-scanning. If ARG is non-nil and not a number, this will force
3982 (>= arg gnus-use-nocem)) 3982 (>= arg gnus-use-nocem))
3983 (not arg))) 3983 (not arg)))
3984 (gnus-nocem-scan-groups)) 3984 (gnus-nocem-scan-groups))
3985 ;; If ARG is not a number, then we read the active file. 3985
3986 (when (and arg (not (numberp arg))) 3986 (gnus-get-unread-articles arg)
3987 (let ((gnus-read-active-file t)) 3987
3988 (gnus-read-active-file)) 3988 ;; If the user wants it, we scan for new groups.
3989 (setq arg nil) 3989 (when (eq gnus-check-new-newsgroups 'always)
3990 3990 (gnus-find-new-newsgroups))
3991 ;; If the user wants it, we scan for new groups. 3991
3992 (when (eq gnus-check-new-newsgroups 'always)
3993 (gnus-find-new-newsgroups)))
3994
3995 (setq arg (gnus-group-default-level arg t))
3996 (if (and gnus-read-active-file (not arg))
3997 (progn
3998 (gnus-read-active-file)
3999 (gnus-get-unread-articles arg))
4000 (let ((gnus-read-active-file (if arg nil gnus-read-active-file)))
4001 (gnus-get-unread-articles arg)))
4002 (gnus-check-reasonable-setup) 3992 (gnus-check-reasonable-setup)
4003 (gnus-run-hooks 'gnus-after-getting-new-news-hook) 3993 (gnus-run-hooks 'gnus-after-getting-new-news-hook)
4004 (gnus-group-list-groups (and (numberp arg) 3994 (gnus-group-list-groups (and (numberp arg)
diff --git a/lisp/gnus/gnus-int.el b/lisp/gnus/gnus-int.el
index fb9b482b148..1054506acef 100644
--- a/lisp/gnus/gnus-int.el
+++ b/lisp/gnus/gnus-int.el
@@ -544,7 +544,8 @@ If GROUP is nil, all groups on GNUS-COMMAND-METHOD are scanned."
544 (if group (gnus-find-method-for-group group) gnus-command-method)) 544 (if group (gnus-find-method-for-group group) gnus-command-method))
545 (gnus-inhibit-demon t) 545 (gnus-inhibit-demon t)
546 (mail-source-plugged gnus-plugged)) 546 (mail-source-plugged gnus-plugged))
547 (when (or gnus-plugged (not (gnus-agent-method-p gnus-command-method))) 547 (when (or gnus-plugged
548 (not (gnus-agent-method-p gnus-command-method)))
548 (setq gnus-internal-registry-spool-current-method gnus-command-method) 549 (setq gnus-internal-registry-spool-current-method gnus-command-method)
549 (funcall (gnus-get-function gnus-command-method 'request-scan) 550 (funcall (gnus-get-function gnus-command-method 'request-scan)
550 (and group (gnus-group-real-name group)) 551 (and group (gnus-group-real-name group))
diff --git a/lisp/gnus/gnus-start.el b/lisp/gnus/gnus-start.el
index 2a332f7c420..16a733d1452 100644
--- a/lisp/gnus/gnus-start.el
+++ b/lisp/gnus/gnus-start.el
@@ -1684,8 +1684,8 @@ If SCAN, request a scan of that group as well."
1684 alevel)) 1684 alevel))
1685 (methods-cache nil) 1685 (methods-cache nil)
1686 (type-cache nil) 1686 (type-cache nil)
1687 scanned-methods info group active method retrieve-groups cmethod 1687 infos info group active method cmethod
1688 method-type) 1688 method-type method-group-list)
1689 (gnus-message 6 "Checking new news...") 1689 (gnus-message 6 "Checking new news...")
1690 1690
1691 (while newsrc 1691 (while newsrc
@@ -1704,14 +1704,19 @@ If SCAN, request a scan of that group as well."
1704 ;; nil for non-foreign groups that the user has requested not be checked 1704 ;; nil for non-foreign groups that the user has requested not be checked
1705 ;; t for unchecked foreign groups or bogus groups, or groups that can't 1705 ;; t for unchecked foreign groups or bogus groups, or groups that can't
1706 ;; be checked, for one reason or other. 1706 ;; be checked, for one reason or other.
1707 (when (setq method (gnus-info-method info)) 1707
1708 ;; First go through all the groups, see what select methods they
1709 ;; belong to, and then collect them into lists per unique select
1710 ;; method.
1711 (if (not (setq method (gnus-info-method info)))
1712 (setq method gnus-select-method)
1708 (if (setq cmethod (assoc method methods-cache)) 1713 (if (setq cmethod (assoc method methods-cache))
1709 (setq method (cdr cmethod)) 1714 (setq method (cdr cmethod))
1710 (setq cmethod (inline (gnus-server-get-method nil method))) 1715 (setq cmethod (inline (gnus-server-get-method nil method)))
1711 (push (cons method cmethod) methods-cache) 1716 (push (cons method cmethod) methods-cache)
1712 (setq method cmethod))) 1717 (setq method cmethod)))
1713 (when (and method 1718 (setq method-group-list (assoc method type-cache))
1714 (not (setq method-type (cdr (assoc method type-cache))))) 1719 (unless method-group-list
1715 (setq method-type 1720 (setq method-type
1716 (cond 1721 (cond
1717 ((gnus-secondary-method-p method) 1722 ((gnus-secondary-method-p method)
@@ -1720,99 +1725,74 @@ If SCAN, request a scan of that group as well."
1720 'primary) 1725 'primary)
1721 (t 1726 (t
1722 'foreign))) 1727 'foreign)))
1723 (push (cons method method-type) type-cache)) 1728 (push (setq method-group-list (list method method-type nil))
1724 1729 type-cache))
1725 (cond ((and method (eq method-type 'foreign)) 1730 (setcar (nthcdr 2 method-group-list)
1726 ;; These groups are foreign. Check the level. 1731 (cons info (nth 2 method-group-list))))
1727 (if (<= (gnus-info-level info) foreign-level) 1732
1728 (when (setq active (gnus-activate-group group 'scan)) 1733 ;; Sort the methods based so that the primary and secondary
1729 ;; Let the Gnus agent save the active file. 1734 ;; methods come first. This is done for legacy reasons to try to
1730 (when (and gnus-agent active (gnus-online method)) 1735 ;; ensure that side-effect behaviour doesn't change from previous
1731 (gnus-agent-save-group-info 1736 ;; Gnus versions.
1732 method (gnus-group-real-name group) active)) 1737 (setq type-cache
1733 (unless (inline (gnus-virtual-group-p group)) 1738 (sort (nreverse type-cache)
1734 (inline (gnus-close-group group))) 1739 (lambda (c1 c2)
1735 (when (fboundp (intern (concat (symbol-name (car method)) 1740 (< (gnus-method-rank (cadr c1) (car c1))
1736 "-request-update-info"))) 1741 (gnus-method-rank (cadr c2) (car c2))))))
1737 (inline (gnus-request-update-info info method)))) 1742
1738 (if (and level 1743 (while type-cache
1739 ;; If `active' is nil that means the group has 1744 (setq method (nth 0 (car type-cache))
1740 ;; never been read, the group should be marked 1745 method-type (nth 1 (car type-cache))
1741 ;; as having never been checked (see below). 1746 infos (nth 2 (car type-cache)))
1742 active 1747 (pop type-cache)
1743 (> (gnus-info-level info) level)) 1748
1744 ;; Don't check groups of which levels are higher 1749 ;; See if any of the groups from this method require updating.
1745 ;; than the one that a user specified. 1750 (when (block nil
1746 (setq active 'ignore)))) 1751 (dolist (info infos)
1747 ;; These groups are native or secondary. 1752 (when (<= (gnus-info-level info)
1748 ((> (gnus-info-level info) alevel) 1753 (if (eq method-type 'foreign)
1749 ;; We don't want these groups. 1754 foreign-level
1750 (setq active 'ignore)) 1755 alevel))
1751 ;; Activate groups. 1756 (return t))))
1752 ((not gnus-read-active-file) 1757 (gnus-read-active-for-groups method infos)
1753 (if (gnus-check-backend-function 'retrieve-groups group) 1758 (dolist (info infos)
1754 ;; if server support gnus-retrieve-groups we push 1759 (inline (gnus-get-unread-articles-in-group
1755 ;; the group onto retrievegroups for later checking 1760 info (gnus-active (gnus-info-group info)))))))
1756 (if (assoc method retrieve-groups)
1757 (setcdr (assoc method retrieve-groups)
1758 (cons group (cdr (assoc method retrieve-groups))))
1759 (push (list method group) retrieve-groups))
1760 ;; hack: `nnmail-get-new-mail' changes the mail-source depending
1761 ;; on the group, so we must perform a scan for every group
1762 ;; if the users has any directory mail sources.
1763 ;; hack: if `nnmail-scan-directory-mail-source-once' is non-nil,
1764 ;; for it scan all spool files even when the groups are
1765 ;; not required.
1766 (if (and
1767 (or nnmail-scan-directory-mail-source-once
1768 (null (assq 'directory mail-sources)))
1769 (member method scanned-methods))
1770 (setq active (gnus-activate-group group))
1771 (setq active (gnus-activate-group group 'scan))
1772 (push method scanned-methods))
1773 (when active
1774 (gnus-close-group group)))))
1775
1776 ;; Get the number of unread articles in the group.
1777 (cond
1778 ((eq active 'ignore)
1779 ;; Don't do anything.
1780 )
1781 (active
1782 (inline (gnus-get-unread-articles-in-group info active t)))
1783 (t
1784 ;; The group couldn't be reached, so we nix out the number of
1785 ;; unread articles and stuff.
1786 (gnus-set-active group nil)
1787 (let ((tmp (gnus-group-entry group)))
1788 (when tmp
1789 (setcar tmp t))))))
1790
1791 ;; iterate through groups on methods which support gnus-retrieve-groups
1792 ;; and fetch a partial active file and use it to find new news.
1793 (dolist (rg retrieve-groups)
1794 (let ((method (or (car rg) gnus-select-method))
1795 (groups (cdr rg)))
1796 (when (gnus-check-server method)
1797 ;; Request that the backend scan its incoming messages.
1798 (when (gnus-check-backend-function 'request-scan (car method))
1799 (gnus-request-scan nil method))
1800 (gnus-read-active-file-2
1801 (mapcar (lambda (group) (gnus-group-real-name group)) groups)
1802 method)
1803 (dolist (group groups)
1804 (cond
1805 ((setq active (gnus-active (gnus-info-group
1806 (setq info (gnus-get-info group)))))
1807 (inline (gnus-get-unread-articles-in-group info active t)))
1808 (t
1809 ;; The group couldn't be reached, so we nix out the number of
1810 ;; unread articles and stuff.
1811 (gnus-set-active group nil)
1812 (setcar (gnus-group-entry group) t)))))))
1813
1814 (gnus-message 6 "Checking new news...done"))) 1761 (gnus-message 6 "Checking new news...done")))
1815 1762
1763(defun gnus-method-rank (type method)
1764 (cond
1765 ((eq type 'primary)
1766 1)
1767 ;; Compute the rank of the secondary methods based on where they
1768 ;; are in the secondary select list.
1769 ((eq type 'secondary)
1770 (let ((i 2))
1771 (block nil
1772 (dolist (smethod gnus-secondary-select-methods)
1773 (when (equalp method smethod)
1774 (return i))
1775 (incf i))
1776 i)))
1777 ;; Just say that all foreign groups have the same rank.
1778 (t
1779 100)))
1780
1781(defun gnus-read-active-for-groups (method infos)
1782 (with-current-buffer nntp-server-buffer
1783 (cond
1784 ((gnus-check-backend-function 'retrieve-groups (car method))
1785 (gnus-read-active-file-2
1786 (mapcar (lambda (info)
1787 (gnus-group-real-name (gnus-info-group info)))
1788 infos)
1789 method))
1790 ((gnus-check-backend-function 'request-list (car method))
1791 (gnus-read-active-file-1 method nil))
1792 (t
1793 (dolist (info infos)
1794 (gnus-activate-group (gnus-info-group info) nil nil method))))))
1795
1816;; Create a hash table out of the newsrc alist. The `car's of the 1796;; Create a hash table out of the newsrc alist. The `car's of the
1817;; alist elements are used as keys. 1797;; alist elements are used as keys.
1818(defun gnus-make-hashtable-from-newsrc-alist () 1798(defun gnus-make-hashtable-from-newsrc-alist ()
@@ -2043,7 +2023,9 @@ If SCAN, request a scan of that group as well."
2043 (gnus-message 5 mesg) 2023 (gnus-message 5 mesg)
2044 (when (gnus-check-server method) 2024 (when (gnus-check-server method)
2045 ;; Request that the backend scan its incoming messages. 2025 ;; Request that the backend scan its incoming messages.
2046 (when (gnus-check-backend-function 'request-scan (car method)) 2026 (when (and gnus-agent
2027 (gnus-online method)
2028 (gnus-check-backend-function 'request-scan (car method)))
2047 (gnus-request-scan nil method)) 2029 (gnus-request-scan nil method))
2048 (cond 2030 (cond
2049 ((and (eq gnus-read-active-file 'some) 2031 ((and (eq gnus-read-active-file 'some)
diff --git a/lisp/gnus/mail-source.el b/lisp/gnus/mail-source.el
index ec15e982390..08b7a5ebbd2 100644
--- a/lisp/gnus/mail-source.el
+++ b/lisp/gnus/mail-source.el
@@ -536,7 +536,7 @@ See `mail-source-bind'."
536 (t 536 (t
537 value))) 537 value)))
538 538
539(defun mail-source-fetch (source callback) 539(defun mail-source-fetch (source callback &optional method)
540 "Fetch mail from SOURCE and call CALLBACK zero or more times. 540 "Fetch mail from SOURCE and call CALLBACK zero or more times.
541CALLBACK will be called with the name of the file where (some of) 541CALLBACK will be called with the name of the file where (some of)
542the mail from SOURCE is put. 542the mail from SOURCE is put.
@@ -544,6 +544,11 @@ Return the number of files that were found."
544 (mail-source-bind-common source 544 (mail-source-bind-common source
545 (if (or mail-source-plugged plugged) 545 (if (or mail-source-plugged plugged)
546 (save-excursion 546 (save-excursion
547 (nnheader-message 4 "%sReading incoming mail from %s..."
548 (if method
549 (format "%s: " method)
550 "")
551 (car source))
547 (let ((function (cadr (assq (car source) mail-source-fetcher-alist))) 552 (let ((function (cadr (assq (car source) mail-source-fetcher-alist)))
548 (found 0)) 553 (found 0))
549 (unless function 554 (unless function
diff --git a/lisp/gnus/nnmail.el b/lisp/gnus/nnmail.el
index 2f218681918..b7d834ecd8c 100644
--- a/lisp/gnus/nnmail.el
+++ b/lisp/gnus/nnmail.el
@@ -1823,8 +1823,6 @@ See the Info node `(gnus)Fancy Mail Splitting' for more details."
1823 ;; The we go through all the existing mail source specification 1823 ;; The we go through all the existing mail source specification
1824 ;; and fetch the mail from each. 1824 ;; and fetch the mail from each.
1825 (while (setq source (pop fetching-sources)) 1825 (while (setq source (pop fetching-sources))
1826 (nnheader-message 4 "%s: Reading incoming mail from %s..."
1827 method (car source))
1828 (when (setq new 1826 (when (setq new
1829 (mail-source-fetch 1827 (mail-source-fetch
1830 source 1828 source
@@ -1842,8 +1840,9 @@ See the Info node `(gnus)Fancy Mail Splitting' for more details."
1842 (incf i))) 1840 (incf i)))
1843 ;; If we did indeed read any incoming spools, we save all info. 1841 ;; If we did indeed read any incoming spools, we save all info.
1844 (if (zerop total) 1842 (if (zerop total)
1845 (nnheader-message 4 "%s: Reading incoming mail (no new mail)...done" 1843 (when mail-source-plugged
1846 method (car source)) 1844 (nnheader-message 4 "%s: Reading incoming mail (no new mail)...done"
1845 method (car source)))
1847 (nnmail-save-active 1846 (nnmail-save-active
1848 (nnmail-get-value "%s-group-alist" method) 1847 (nnmail-get-value "%s-group-alist" method)
1849 (nnmail-get-value "%s-active-file" method)) 1848 (nnmail-get-value "%s-active-file" method))
diff --git a/lisp/gnus/nnmh.el b/lisp/gnus/nnmh.el
index 86f751c7669..4b843e62153 100644
--- a/lisp/gnus/nnmh.el
+++ b/lisp/gnus/nnmh.el
@@ -209,24 +209,25 @@ as unread by Gnus.")
209 ;; Recurse down all directories. 209 ;; Recurse down all directories.
210 (let ((files (nnheader-directory-files dir t nil t)) 210 (let ((files (nnheader-directory-files dir t nil t))
211 (max 0) 211 (max 0)
212 min rdir attributes num) 212 min rdir num subdirectoriesp)
213 ;; Recurse down directories. 213 ;; Recurse down directories.
214 (setq subdirectoriesp (> (nth 1 (file-attributes dir)) 2))
214 (dolist (rdir files) 215 (dolist (rdir files)
215 (setq attributes (file-attributes rdir)) 216 (if (or (not subdirectoriesp)
216 (when (null (nth 0 attributes)) 217 (file-regular-p rdir))
217 (setq file (file-name-nondirectory rdir)) 218 (progn
218 (when (string-match "^[0-9]+$" file) 219 (setq file (file-name-nondirectory rdir))
219 (setq num (string-to-number file)) 220 (when (string-match "^[0-9]+$" file)
220 (setq max (max max num)) 221 (setq num (string-to-number file))
221 (when (or (null min) 222 (setq max (max max num))
222 (< num min)) 223 (when (or (null min)
223 (setq min num)))) 224 (< num min))
224 (when (and (eq (nth 0 attributes) t) ; Is a directory 225 (setq min num))))
225 (> (nth 1 attributes) 2) ; Has sub-directories 226 ;; This is a directory.
226 (file-readable-p rdir) 227 (when (and (file-readable-p rdir)
227 (not (equal (file-truename rdir) 228 (not (equal (file-truename rdir)
228 (file-truename dir)))) 229 (file-truename dir))))
229 (nnmh-request-list-1 rdir))) 230 (nnmh-request-list-1 rdir))))
230 ;; For each directory, generate an active file line. 231 ;; For each directory, generate an active file line.
231 (unless (string= (expand-file-name nnmh-toplev) dir) 232 (unless (string= (expand-file-name nnmh-toplev) dir)
232 (when min 233 (when min
diff --git a/lisp/gnus/nnvirtual.el b/lisp/gnus/nnvirtual.el
index 74339729500..94f43216b38 100644
--- a/lisp/gnus/nnvirtual.el
+++ b/lisp/gnus/nnvirtual.el
@@ -300,10 +300,6 @@ component group will show up when you enter the virtual group.")
300 t) 300 t)
301 301
302 302
303(deffoo nnvirtual-request-list (&optional server)
304 (nnheader-report 'nnvirtual "LIST is not implemented."))
305
306
307(deffoo nnvirtual-request-newgroups (date &optional server) 303(deffoo nnvirtual-request-newgroups (date &optional server)
308 (nnheader-report 'nnvirtual "NEWGROUPS is not supported.")) 304 (nnheader-report 'nnvirtual "NEWGROUPS is not supported."))
309 305