aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Monnier2020-02-14 11:05:57 -0500
committerStefan Monnier2020-02-14 11:05:57 -0500
commitd737e497a82431b2ca4debb7a68c5422cb5a7929 (patch)
treef6715187ff6d69afe24fe42b29e42187bb91f982
parent32f0149266162f8cfd161b35a1fe3744dcd36625 (diff)
downloademacs-d737e497a82431b2ca4debb7a68c5422cb5a7929.tar.gz
emacs-d737e497a82431b2ca4debb7a68c5422cb5a7929.zip
* lisp/gnus/nnmaildir.el: Fix O(n^2) problem when leaving a group
Use lexical-binding. (nnmaildir-close-group): Use a hash-table rather than a list to keep track of the files we have seen. * lisp/gnus/nnheader.el (nnheader-parse-naked-head): Use make-full-mail-header.
-rw-r--r--lisp/gnus/nnheader.el2
-rw-r--r--lisp/gnus/nnmaildir.el30
2 files changed, 19 insertions, 13 deletions
diff --git a/lisp/gnus/nnheader.el b/lisp/gnus/nnheader.el
index 199d5241973..fee7a169ff9 100644
--- a/lisp/gnus/nnheader.el
+++ b/lisp/gnus/nnheader.el
@@ -209,7 +209,7 @@ on your system, you could say something like:
209 ;; about twice as fast, even though it looks messier. You 209 ;; about twice as fast, even though it looks messier. You
210 ;; can't have everything, I guess. Speed and elegance don't 210 ;; can't have everything, I guess. Speed and elegance don't
211 ;; always go hand in hand. 211 ;; always go hand in hand.
212 (vector 212 (make-full-mail-header
213 ;; Number. 213 ;; Number.
214 (or number 0) 214 (or number 0)
215 ;; Subject. 215 ;; Subject.
diff --git a/lisp/gnus/nnmaildir.el b/lisp/gnus/nnmaildir.el
index bf1ac31bb3c..9c7b1254413 100644
--- a/lisp/gnus/nnmaildir.el
+++ b/lisp/gnus/nnmaildir.el
@@ -1,4 +1,4 @@
1;;; nnmaildir.el --- maildir backend for Gnus 1;;; nnmaildir.el --- maildir backend for Gnus -*- lexical-binding:t -*-
2 2
3;; This file is in the public domain. 3;; This file is in the public domain.
4 4
@@ -261,7 +261,7 @@ This variable is set by `nnmaildir-request-article'.")
261(defun nnmaildir--param (pgname param) 261(defun nnmaildir--param (pgname param)
262 (setq param (gnus-group-find-parameter pgname param 'allow-list)) 262 (setq param (gnus-group-find-parameter pgname param 'allow-list))
263 (if (vectorp param) (setq param (aref param 0))) 263 (if (vectorp param) (setq param (aref param 0)))
264 (eval param)) 264 (eval param t))
265 265
266(defmacro nnmaildir--with-nntp-buffer (&rest body) 266(defmacro nnmaildir--with-nntp-buffer (&rest body)
267 (declare (debug (body))) 267 (declare (debug (body)))
@@ -690,7 +690,7 @@ This variable is set by `nnmaildir-request-article'.")
690 "You must set \"directory\" in the select method") 690 "You must set \"directory\" in the select method")
691 (throw 'return nil)) 691 (throw 'return nil))
692 (setq dir (cadr dir) 692 (setq dir (cadr dir)
693 dir (eval dir) 693 dir (eval dir t) ;FIXME: Why `eval'?
694 dir (expand-file-name dir) 694 dir (expand-file-name dir)
695 dir (file-name-as-directory dir)) 695 dir (file-name-as-directory dir))
696 (unless (file-exists-p dir) 696 (unless (file-exists-p dir)
@@ -717,13 +717,13 @@ This variable is set by `nnmaildir-request-article'.")
717 (if x 717 (if x
718 (progn 718 (progn
719 (setq x (cadr x) 719 (setq x (cadr x)
720 x (eval x)) 720 x (eval x t)) ;FIXME: Why `eval'?
721 (setf (nnmaildir--srv-target-prefix server) x)) 721 (setf (nnmaildir--srv-target-prefix server) x))
722 (setq x (assq 'create-directory defs)) 722 (setq x (assq 'create-directory defs))
723 (if x 723 (if x
724 (progn 724 (progn
725 (setq x (cadr x) 725 (setq x (cadr x)
726 x (eval x) 726 x (eval x t) ;FIXME: Why `eval'?
727 x (file-name-as-directory x)) 727 x (file-name-as-directory x))
728 (setf (nnmaildir--srv-target-prefix server) x)) 728 (setf (nnmaildir--srv-target-prefix server) x))
729 (setf (nnmaildir--srv-target-prefix server) ""))) 729 (setf (nnmaildir--srv-target-prefix server) "")))
@@ -1428,7 +1428,7 @@ This variable is set by `nnmaildir-request-article'.")
1428 (nnmaildir--with-move-buffer 1428 (nnmaildir--with-move-buffer
1429 (erase-buffer) 1429 (erase-buffer)
1430 (nnheader-insert-file-contents nnmaildir--file) 1430 (nnheader-insert-file-contents nnmaildir--file)
1431 (setq result (eval accept-form))) 1431 (setq result (eval accept-form t)))
1432 (unless (or (null result) (nnmaildir--param pgname 'read-only)) 1432 (unless (or (null result) (nnmaildir--param pgname 'read-only))
1433 (nnmaildir--unlink nnmaildir--file) 1433 (nnmaildir--unlink nnmaildir--file)
1434 (nnmaildir--expired-article group article)) 1434 (nnmaildir--expired-article group article))
@@ -1544,7 +1544,7 @@ This variable is set by `nnmaildir-request-article'.")
1544(defun nnmaildir-request-expire-articles (ranges &optional gname server force) 1544(defun nnmaildir-request-expire-articles (ranges &optional gname server force)
1545 (let ((no-force (not force)) 1545 (let ((no-force (not force))
1546 (group (nnmaildir--prepare server gname)) 1546 (group (nnmaildir--prepare server gname))
1547 pgname time boundary high low target dir nlist 1547 pgname time boundary target dir nlist
1548 didnt nnmaildir--file nnmaildir-article-file-name 1548 didnt nnmaildir--file nnmaildir-article-file-name
1549 deactivate-mark) 1549 deactivate-mark)
1550 (catch 'return 1550 (catch 'return
@@ -1720,18 +1720,23 @@ This variable is set by `nnmaildir-request-article'.")
1720 1720
1721(defun nnmaildir-close-group (gname &optional server) 1721(defun nnmaildir-close-group (gname &optional server)
1722 (let ((group (nnmaildir--prepare server gname)) 1722 (let ((group (nnmaildir--prepare server gname))
1723 pgname ls dir msgdir files flist dirs) 1723 pgname ls dir msgdir files dirs
1724 (fset (make-hash-table :test #'equal)))
1724 (if (null group) 1725 (if (null group)
1725 (progn 1726 (progn
1726 (setf (nnmaildir--srv-error nnmaildir--cur-server) 1727 (setf (nnmaildir--srv-error nnmaildir--cur-server)
1727 (concat "No such group: " gname)) 1728 (concat "No such group: " gname))
1728 nil) 1729 nil)
1730 ;; Delete the now obsolete NOV files.
1731 ;; FIXME: This can take a somewhat long time, so maybe it's better
1732 ;; to do it asynchronously (i.e. in an idle timer).
1729 (setq pgname (nnmaildir--pgname nnmaildir--cur-server gname) 1733 (setq pgname (nnmaildir--pgname nnmaildir--cur-server gname)
1730 ls (nnmaildir--group-ls nnmaildir--cur-server pgname) 1734 ls (nnmaildir--group-ls nnmaildir--cur-server pgname)
1731 dir (nnmaildir--srv-dir nnmaildir--cur-server) 1735 dir (nnmaildir--srv-dir nnmaildir--cur-server)
1732 dir (nnmaildir--srvgrp-dir dir gname) 1736 dir (nnmaildir--srvgrp-dir dir gname)
1733 msgdir (if (nnmaildir--param pgname 'read-only) 1737 msgdir (if (nnmaildir--param pgname 'read-only)
1734 (nnmaildir--new dir) (nnmaildir--cur dir)) 1738 (nnmaildir--new dir) (nnmaildir--cur dir))
1739 ;; The dir with the NOV files.
1735 dir (nnmaildir--nndir dir) 1740 dir (nnmaildir--nndir dir)
1736 dirs (cons (nnmaildir--nov-dir dir) 1741 dirs (cons (nnmaildir--nov-dir dir)
1737 (funcall ls (nnmaildir--marks-dir dir) 'full "\\`[^.]" 1742 (funcall ls (nnmaildir--marks-dir dir) 'full "\\`[^.]"
@@ -1744,14 +1749,15 @@ This variable is set by `nnmaildir-request-article'.")
1744 (save-match-data 1749 (save-match-data
1745 (dolist (file files) 1750 (dolist (file files)
1746 (string-match "\\`\\([^:]*\\)\\(:.*\\)?\\'" file) 1751 (string-match "\\`\\([^:]*\\)\\(:.*\\)?\\'" file)
1747 (push (match-string 1 file) flist))) 1752 (puthash (match-string 1 file) t fset)))
1753 ;; Not sure why, but we specifically avoid deleting the `:' file.
1754 (puthash ":" t fset)
1748 (dolist (dir dirs) 1755 (dolist (dir dirs)
1749 (setq files (cdr dir) 1756 (setq files (cdr dir)
1750 dir (file-name-as-directory (car dir))) 1757 dir (file-name-as-directory (car dir)))
1751 (dolist (file files) 1758 (dolist (file files)
1752 (unless (or (member file flist) (string= file ":")) 1759 (unless (gethash file fset)
1753 (setq file (concat dir file)) 1760 (delete-file (concat dir file)))))
1754 (delete-file file))))
1755 t))) 1761 t)))
1756 1762
1757(defun nnmaildir-close-server (&optional server _defs) 1763(defun nnmaildir-close-server (&optional server _defs)