emacs-pretest-bug
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: gnus crashes on threads deeper than 333 articles


From: Reiner Steib
Subject: Re: gnus crashes on threads deeper than 333 articles
Date: Mon, 04 Dec 2006 17:05:16 +0100
User-agent: Gnus/5.110006 (No Gnus v0.6) Emacs/22.0.91 (gnu/linux)

On Sun, Dec 03 2006, Chong Yidong wrote:

> Chris Moore <address@hidden> writes:
>
>> I just tried opening a mail folder using nnimap in gnus.
>>
>> One of the threads in the folder is 834 messages long, and each
>> message in the thread is a reply to the previous one which results in
>> the thread being 834 messages 'deep'.
>>
>> The definition of gnus-sort-threads in lisp/gnus/gnus-sum.el does
>> this:
>>     (let ((max-lisp-eval-depth 5000))
>> but it doesn't increase max-specpdl-size.  Maybe it should?
>>
>> Or maybe it shouldn't impose fixed limits on the maximum allowable
>> thread length at all.  A re-implementation using a loop instead of
>> recursion should be able to get around this limit.  It's walking the
>> thread tree, sorting as it goes.
>
> The attached patch provides a reimplementation of gnus-sort-threads-1
> that uses a loop instead of recursion.  It may be a little too
> intricate a change to check into Emacs at this point, though.  What do
> people think?

I searched the archives and I only found one more report about this
problem, so it seems to be a *very rare* situation.  I'm not sure if
such a change should be made now (in the stable series).

What about providing an option and keep the current recursive as
default?  See the patch below (`gnus-sort-threads-loop' is your
function).

Is your implementation faster or slower than the recursion?

--8<---------------cut here---------------start------------->8---
--- gnus-sum.el 09 Nov 2006 13:32:35 +0100      7.163
+++ gnus-sum.el 04 Dec 2006 16:55:43 +0100      
@@ -4649,20 +4649,48 @@
              (1+ (point-at-eol))
            (gnus-delete-line)))))))
 
-(defun gnus-sort-threads-1 (threads func)
+(defun gnus-sort-threads-recursive (threads func)
   (sort (mapcar (lambda (thread)
                  (cons (car thread)
                        (and (cdr thread)
-                            (gnus-sort-threads-1 (cdr thread) func))))
+                            (gnus-sort-threads-recursive (cdr thread) func))))
                threads) func))
 
+(defun gnus-sort-threads-loop (threads func)
+  (let* ((superthread (cons nil threads))
+        (stack (list (cons superthread threads)))
+        remaining-threads thread)
+    (while stack
+      (setq remaining-threads (cdr (car stack)))
+      (if remaining-threads
+         (progn (setq thread (car remaining-threads))
+                (setcdr (car stack) (cdr remaining-threads))
+                (if (cdr thread)
+                    (push (cons thread (cdr thread)) stack)))
+       (setq thread (caar stack))
+       (setcdr thread (sort (cdr thread) func))
+       (pop stack)))
+    (cdr superthread)))
+
+(defcustom gnus-sort-threads-function 'gnus-sort-threads-recursive
+  "Function used to sort threads.
+There are two pre-defined functions:
+`gnus-sort-threads-recursive', and `gnus-sort-threads-loop'.  If
+you get an error message \"Variable binding depth exceeds
+max-specpdl-size\" during threading, set this variable to
+`gnus-sort-threads-loop'."
+  :group 'gnus-thread
+  :version "22.1" ;; Gnus 5.10.9
+  :type '(choice (const :tag "recursion" gnus-sort-threads-recursive)
+                (const :tag "loop" gnus-sort-threads-loop)))
+
 (defun gnus-sort-threads (threads)
   "Sort THREADS."
   (if (not gnus-thread-sort-functions)
       threads
     (gnus-message 8 "Sorting threads...")
     (let ((max-lisp-eval-depth 5000))
-      (prog1 (gnus-sort-threads-1
+      (prog1 (funcall gnus-sort-threads-function
         threads
         (gnus-make-sort-function gnus-thread-sort-functions))
         (gnus-message 8 "Sorting threads...done")))))
--8<---------------cut here---------------end--------------->8---

Bye, Reiner.
-- 
       ,,,
      (o o)
---ooO-(_)-Ooo---  |  PGP key available  |  http://rsteib.home.pages.de/




reply via email to

[Prev in Thread] Current Thread [Next in Thread]