home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / gnu / lucid / lemacs-19.6 / lisp / gnus / gnus-speedups.el < prev    next >
Encoding:
Text File  |  1992-12-28  |  5.3 KB  |  170 lines

  1. ;; -*- Mode: Emacs-Lisp -*-
  2.  
  3. ;; From flee@cs.psu.edu Fri May 22 12:16:20 1992
  4. ;; Newsgroups: gnu.emacs.gnus,gnu.emacs.sources
  5. ;; From: flee@cs.psu.edu (Felix Lee)
  6. ;; Subject: Two GNUS speedups.
  7. ;; Organization: Penn State Computer Science
  8. ;; Date: Thu, 21 May 1992 04:45:32 GMT
  9. ;; 
  10. ;; I've posted these speedups before, but here they are all in one place,
  11. ;; and cleaned up a bit.  (Upgrading to GNUS 3.14 was an excuse to go
  12. ;; back and clean things up.)
  13. ;; 
  14. ;; gnus-speedups|Felix Lee|flee@cs.psu.edu
  15. ;; |Simple performance enhancements for GNUS
  16. ;; |1992-05-18|1.2: stable||
  17.  
  18. ;; This package contains two plug-compatible performance enhancements
  19. ;; for GNUS 3.13 and 3.14:
  20.  
  21. ;; 1. A faster version of gnus-find-new-newsgroups, for making GNUS
  22. ;; start more quickly.
  23.  
  24. ;; 2. Faster subject and date sorting in the *Subject* buffer.
  25.  
  26. ;; This file must be loaded after "gnus.el".  You can do this by
  27. ;; adding '(load "gnus-speedups") at the end of your local gnus
  28. ;; wrapper, or at the end of "gnus.el".  Or you could just include
  29. ;; this file directly.
  30.  
  31. (require 'gnus)
  32.  
  33. ;;;;;
  34. ;; 1. A faster version of gnus-find-new-newsgroups.
  35.  
  36. ;; We reduce an O(N**2) process to O(N) by building a hash table for
  37. ;; the list of known newsgroups.  (It's a little strange that GNUS
  38. ;; doesn't already have a hash table for this.)
  39.  
  40. (defun gnus-find-new-newsgroups ()
  41.   "Look for new newsgroups and return names.
  42. `-n' option of options line in .newsrc file is recognized."
  43.   (let ( (group nil)
  44.      (new-groups nil)
  45.      (known-groups (gnus-make-hashtable)) )
  46.     ;; Build a table of known newsgroups.
  47.     (mapcar
  48.      (function (lambda (group) (gnus-sethash (car group) t known-groups)))
  49.      gnus-killed-assoc)
  50.     (mapcar
  51.      (function (lambda (group) (gnus-sethash (car group) t known-groups)))
  52.      gnus-newsrc-assoc)
  53.     ;; Compare the active file against what's known.
  54.     (mapatoms
  55.      (function
  56.       (lambda (sym)
  57.     (setq group (symbol-name sym))
  58.     ;; Take into account the -n option.
  59.     (and (or (null gnus-newsrc-options-n-no)
  60.          (not (string-match gnus-newsrc-options-n-no group))
  61.          (and gnus-newsrc-options-n-yes
  62.               (string-match gnus-newsrc-options-n-yes group)))
  63.          (null (gnus-gethash group known-groups))
  64.          (setq new-groups (cons group new-groups)))
  65.     ))
  66.      gnus-active-hashtb)
  67.     new-groups
  68.     ))
  69.  
  70.  
  71. ;;;;;
  72. ;; 2. Faster subject and date sorting in the *Subject* buffer.
  73.  
  74. ;; The basic idea is explained in 'gnus-keyed-sort.
  75.  
  76. ;; Sample hook usage:
  77. ;; (setq gnus-Select-group-hook
  78. ;;     (function
  79. ;;      (lambda ()
  80. ;;        (gnus-keyed-sort-headers
  81. ;;         (function gnus-string-lessp)
  82. ;;         (function (lambda (it) (gnus-simplify-subject it 're-only))))
  83. ;;        )))
  84.  
  85. (defun gnus-keyed-sort (list compare extract)
  86.   "Sort LIST stably and return the sorted list.  Does not modify LIST.
  87. Arguments are (LIST COMPARE EXTRACT).  Elements in the list are
  88. compared as if the predicate were:
  89.     (COMPARE (EXTRACT a) (EXTRACT b))
  90. but EXTRACT is run over each element of the list in a preprocessing
  91. stage for efficiency.  This reduces the number of EXTRACT calls from
  92. O(N log N) to O(N).
  93.  
  94. Example: (gnus-keyed-sort load-path 'string< 'downcase)
  95. "
  96.   (let ( (keyed-list
  97.       (mapcar
  98.        (function (lambda (it) (cons (funcall extract it) it)))
  99.        list)) )
  100.     (setq keyed-list
  101.       (sort keyed-list
  102.         (function
  103.          (lambda (a b) (funcall compare (car a) (car b))))))
  104.     (mapcar (function (lambda (it) (cdr it)))
  105.         keyed-list)
  106.     ))
  107.  
  108. (defun gnus-keyed-sort-headers (compare extract)
  109.   "Sort current group's headers by COMPARE and EXTRACT.  Sorting is
  110. done as if the predicate were
  111.     (COMPARE (EXTRACT a) (EXTRACT b))
  112. See 'gnus-keyed-sort for details.
  113. Note: interrupting the sort leaves the headers unsorted.
  114. "
  115.   (setq gnus-newsgroup-headers
  116.     (gnus-keyed-sort
  117.      gnus-newsgroup-headers
  118.      compare extract)))
  119.  
  120. (defun gnus-Subject-keyed-sort-subjects (compare extract &optional reverse)
  121.   "Sort and redisplay the *Subject* buffer by COMPARE and EXTRACT.
  122. Calls 'gnus-keyed-sort-headers to do the sorting.  Optional argument
  123. REVERSE means to do an 'nreverse after sorting.
  124. "
  125.   (let ( (current (gnus-Subject-article-number)) )
  126.     (gnus-keyed-sort-headers compare extract)
  127.     (if reverse
  128.     (setq gnus-newsgroup-headers (nreverse gnus-newsgroup-headers)))
  129.     (gnus-Subject-prepare)
  130.     (gnus-Subject-goto-subject current)
  131.     ))
  132.  
  133. ;; XXX It should be 'gnus-sort-fold-case, not 'case-fold-search
  134. (defun gnus-Subject-sort-by-subject (reverse)
  135.   "Sort *Subject* buffer by subject alphabetically.  Argument REVERSE
  136. means reverse order.  \"Re:\"s are ignored.  If 'case-fold-search, then
  137. case of letters will be ignored.
  138. "
  139.   (interactive "P")
  140.   ;; The main complication here is we try to speed up the sort process
  141.   ;; by hoisting conditions outside the sort.
  142.   (gnus-Subject-keyed-sort-subjects
  143.    'string<
  144.    (if case-fold-search
  145.        (function
  146.     (lambda (it)
  147.       (downcase (gnus-simplify-subject (nntp-header-subject it) 're-only))))
  148.      (function
  149.       (lambda (it)
  150.     (gnus-simplify-subject (nntp-header-subject it) 're-only)))
  151.      )
  152.    reverse)
  153.   )
  154.  
  155. ;; For backward compatibility with GNUS 3.13
  156. (if (not (fboundp 'gnus-sortable-date))
  157.     (fset 'gnus-sortable-date 'gnus-comparable-date))
  158.  
  159. (defun gnus-Subject-sort-by-date (reverse)
  160.   "Sort *Subject* buffer by posted date.  Argument REVERSE means
  161. reverse order."
  162.   (interactive "P")
  163.   (gnus-Subject-keyed-sort-subjects
  164.    'string<
  165.    (function
  166.     (lambda (it)
  167.       (gnus-sortable-date (nntp-header-date it))))
  168.    reverse)
  169.   )
  170.