Synch to No Gnus 200401250222.
authoryamaoka <yamaoka>
Sun, 25 Jan 2004 14:27:50 +0000 (14:27 +0000)
committeryamaoka <yamaoka>
Sun, 25 Jan 2004 14:27:50 +0000 (14:27 +0000)
lisp/ChangeLog
lisp/nnmaildir.el
lisp/spam-stat.el

index 1136dc7..82fc310 100644 (file)
@@ -1,3 +1,18 @@
+2004-01-25  Paul Jarc  <prj@po.cwru.edu>
+
+       * nnmaildir.el (nnmaildir--num-file, nnmaildir--mkfile,
+       nnmaildir--emlink-p, nnmaildir--eexist-p, nnmaildir--new-number):
+       New macros and functions.
+       * nnmaildir.el (nnmaildir--group-maxnum, nnmaildir--update-nov):
+       Handle > NLINK_MAX messages.
+       * nnmaildir.el (nnmaildir-request-set-mark): Use
+       nnmaildir--emlink-p and nnmaildir--eexist-p.
+
+2004-01-25  Alex Schroeder  <alex@gnu.org>
+
+       * spam-stat.el (spam-stat-process-directory-age): New option.
+       (spam-stat-process-directory): Use it.
+
 2004-01-24  Hiroshi Fujishima <pooh@nature.tsukuba.ac.jp>  (tiny change)
 
        * spam-stat.el (spam-stat-reduce-size): Set spam-stat-dirty.
index c6d7765..bd498a5 100644 (file)
@@ -229,7 +229,6 @@ by nnmaildir-request-article.")
 (defmacro nnmaildir--nov-dir   (dir) `(nnmaildir--subdir ,dir "nov"))
 (defmacro nnmaildir--marks-dir (dir) `(nnmaildir--subdir ,dir "marks"))
 (defmacro nnmaildir--num-dir   (dir) `(nnmaildir--subdir ,dir "num"))
-(defmacro nnmaildir--num-file  (dir) `(concat ,dir ":"))
 
 (defmacro nnmaildir--unlink (file-arg)
   `(let ((file ,file-arg))
@@ -237,20 +236,36 @@ by nnmaildir-request-article.")
 (defun nnmaildir--mkdir (dir)
   (or (file-exists-p (file-name-as-directory dir))
       (make-directory-internal (directory-file-name dir))))
+(defun nnmaildir--mkfile (file)
+  (write-region "" nil file nil 'no-message))
 (defun nnmaildir--delete-dir-files (dir ls)
   (when (file-attributes dir)
     (mapcar 'delete-file (funcall ls dir 'full "\\`[^.]" 'nosort))
     (delete-directory dir)))
 
 (defun nnmaildir--group-maxnum (server group)
-  (if (zerop (nnmaildir--grp-count group)) 0
-    (let ((x (nnmaildir--srvgrp-dir (nnmaildir--srv-dir server)
-                                   (nnmaildir--grp-name group))))
-      (setq x (nnmaildir--nndir x)
-           x (nnmaildir--num-dir x)
-           x (nnmaildir--num-file x)
-           x (file-attributes x))
-      (if x (1- (nth 1 x)) 0))))
+  (catch 'return
+    (if (zerop (nnmaildir--grp-count group)) (throw 'return 0))
+    (let ((dir (nnmaildir--srvgrp-dir (nnmaildir--srv-dir server)
+                                   (nnmaildir--grp-name group)))
+         (number-opened 1)
+         attr ino-opened nlink number-linked)
+      (setq dir (nnmaildir--nndir dir)
+           dir (nnmaildir--num-dir dir))
+      (while t
+       (setq attr (file-attributes
+                   (concat dir (number-to-string number-opened))))
+       (or attr (throw 'return (1- number-opened)))
+       (setq ino-opened (nth 10 attr)
+             nlink (nth 1 attr)
+             number-linked (+ number-opened nlink))
+       (if (or (< nlink 1) (< number-linked nlink))
+           (signal 'error '("Arithmetic overflow")))
+       (setq attr (file-attributes
+                   (concat dir (number-to-string number-linked))))
+       (or attr (throw 'return (1- number-linked)))
+       (if (/= ino-opened (nth 10 attr))
+           (setq number-opened number-linked))))))
 
 ;; Make the given server, if non-nil, be the current server.  Then make the
 ;; given group, if non-nil, be the current group of the current server.  Then
@@ -287,6 +302,56 @@ by nnmaildir-request-article.")
       (setq pos (match-end 0))))
   string)
 
+(defun nnmaildir--emlink-p (err)
+  (and (eq (car err) 'file-error)
+       (string= (caddr err) "too many links")))
+
+(defun nnmaildir--eexist-p (err)
+  (eq (car err) 'file-already-exists))
+
+(defun nnmaildir--new-number (nndir)
+  "Allocate a new article number by atomically creating a file under NNDIR."
+  (let ((numdir (nnmaildir--num-dir nndir))
+       (make-new-file t)
+       (number-open 1)
+       number-link previous-number-link path-open path-link ino-open)
+    (nnmaildir--mkdir numdir)
+    (catch 'return
+      (while t
+       (setq path-open (concat numdir (number-to-string number-open)))
+       (if (not make-new-file)
+           (setq previous-number-link number-link)
+         (nnmaildir--mkfile path-open)
+         ;; If Emacs had O_CREAT|O_EXCL, we could return number-open here.
+         (setq make-new-file nil
+               previous-number-link 0))
+       (let* ((attr (file-attributes path-open))
+              (nlink (nth 1 attr)))
+         (setq ino-open (nth 10 attr)
+               number-link (+ number-open nlink))
+         (if (or (< nlink 1) (< number-link nlink))
+             (signal 'error '("Arithmetic overflow"))))
+       (if (= number-link previous-number-link)
+           ;; We've already tried this number, in the previous loop iteration,
+           ;; and failed.
+           (signal 'error `("Corrupt internal nnmaildir data" ,path-open)))
+       (setq path-link (concat numdir (number-to-string number-link)))
+       (condition-case err
+           (progn
+             (add-name-to-file path-open path-link)
+             (throw 'return number-link))
+         (error
+          (cond
+           ((nnmaildir--emlink-p err)
+            (setq make-new-file t
+                  number-open number-link))
+           ((nnmaildir--eexist-p err)
+            (let ((attr (file-attributes path-link)))
+              (if (/= (nth 10 attr) ino-open)
+                  (setq number-open number-link
+                        number-link 0))))
+           (t (signal (car err) (cdr err))))))))))
+
 (defun nnmaildir--update-nov (server group article)
   (let ((nnheader-file-coding-system 'binary)
        (srv-dir (nnmaildir--srv-dir server))
@@ -398,30 +463,7 @@ by nnmaildir-request-article.")
                                      nnmaildir--extra)
              num (nnmaildir--art-num article))
        (unless num
-         ;; Allocate a new article number.
-         (erase-buffer)
-         (setq numdir (nnmaildir--num-dir dir)
-               file (nnmaildir--num-file numdir)
-               num -1)
-         (nnmaildir--mkdir numdir)
-         (write-region "" nil file nil 'no-message)
-         (while file
-           ;; Get the number of links to file.
-           (setq attr (nth 1 (file-attributes file)))
-           (if (= attr num)
-               ;; We've already tried this number, in the previous loop
-               ;; iteration, and failed.
-               (signal 'error `("Corrupt internal nnmaildir data" ,numdir)))
-           ;; If attr is 123, try to link file to "123".  This atomically
-           ;; increases the link count and creates the "123" link, failing
-           ;; if that link was already created by another Gnus, just after
-           ;; we stat()ed file.
-           (condition-case nil
-               (progn
-                 (add-name-to-file file (concat numdir (format "%x" attr)))
-                 (setq file nil)) ;; Stop looping.
-             (file-already-exists nil))
-           (setq num attr))
+         (setq num (nnmaildir--new-number dir))
          (setf (nnmaildir--art-num article) num))
        ;; Store this new NOV data in a file
        (erase-buffer)
@@ -1502,16 +1544,15 @@ by nnmaildir-request-article.")
                   (add-name-to-file permarkfile mfile)
                 (error
                  (cond
-                  ((eq (car err) 'file-already-exists))
+                  ((nnmaildir--eexist-p err))
                   ((and (eq (car err) 'file-error)
                         (string= (caddr err) "no such file or directory"))
                    (nnmaildir--mkdir mdir)
-                   (write-region "" nil permarkfile nil 'no-message)
+                   (nnmaildir--mkfile permarkfile)
                    (add-name-to-file permarkfile mfile))
-                  ((and (eq (car err) 'file-error)
-                        (string= (caddr err) "too many links"))
+                  ((nnmaildir--emlink-p err)
                    (let ((permarkfilenew (concat permarkfile "{new}")))
-                     (write-region "" nil permarkfilenew nil 'no-message)
+                     (nnmaildir--mkfile permarkfilenew)
                      (rename-file permarkfilenew permarkfile 'replace)
                      (add-name-to-file permarkfile mfile)))
                   (t (signal (car err) (cdr err)))))))
index 451c085..958e68f 100644 (file)
@@ -1,6 +1,6 @@
 ;;; spam-stat.el --- detecting spam based on statistics
 
-;; Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+;; Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
 
 ;; Author: Alex Schroeder <alex@gnu.org>
 ;; Keywords: network
@@ -172,6 +172,14 @@ effect when spam-stat is invoked through spam.el."
   :type 'number
   :group 'spam-stat)
 
+(defcustom spam-stat-process-directory-age 90
+  "Max. age of files to be processed in directory, in days.
+When using `spam-stat-process-spam-directory' or
+`spam-stat-process-non-spam-directory', only files that have
+been touched in this many days will be considered.  Without
+this filter, re-training spam-stat with several thousand messages
+will start to take a very long time.")
+
 (defvar spam-stat-syntax-table
   (let ((table (copy-syntax-table text-mode-syntax-table)))
     (modify-syntax-entry ?- "w" table)
@@ -487,7 +495,9 @@ check the variable `spam-stat-score-data'."
       (dolist (f files)
        (when (and (file-readable-p f)
                   (file-regular-p f)
-                   (> (nth 7 (file-attributes f)) 0))
+                   (> (nth 7 (file-attributes f)) 0)
+                  (< (time-to-number-of-days (time-since (nth 5 (file-attributes f))))
+                     spam-stat-process-directory-age))
          (setq count (1+ count))
          (message "Reading %s: %.2f%%" dir (/ count max))
          (insert-file-contents f)