--- gnus-cache.el 01 Mar 2008 22:54:54 +0100 6.26.2.13 +++ gnus-cache.el 19 Apr 2008 16:01:26 +0200 @@ -501,10 +501,14 @@ (setq gnus-cache-active-altered t))) articles))) + (defun gnus-cache-braid-nov (group cached &optional file) + (message "Merging cached articles with ones on server...") (let ((cache-buf (gnus-get-buffer-create " *gnus-cache*")) - beg end) + (new-records nil) + beg end server-cursor) (gnus-cache-save-buffers) + ;; create new buffer for reading cache overview (save-excursion (set-buffer cache-buf) (erase-buffer) @@ -513,27 +517,58 @@ (insert-file-contents (or file (gnus-cache-file-name group ".overview")))) (goto-char (point-min)) - (insert "\n") + (insert "\n") ; so we can search for, e.g., \n123\t (goto-char (point-min))) (set-buffer nntp-server-buffer) (goto-char (point-min)) + (setq server-cursor (point)) (while cached + (set-buffer nntp-server-buffer) + ;; skip server records preceding first cached article (while (and (not (eobp)) (< (read (current-buffer)) (car cached))) (forward-line 1)) (beginning-of-line) + ;; grab those records for the new buffer + (let ((new-server-cursor (point))) + (when (> new-server-cursor server-cursor) + (push (buffer-substring server-cursor new-server-cursor) new-records) + (setq server-cursor new-server-cursor))) + ;; grab first cached article, if present (set-buffer cache-buf) (if (search-forward (concat "\n" (int-to-string (car cached)) "\t") nil t) (setq beg (gnus-point-at-bol) end (progn (end-of-line) (point))) (setq beg nil)) - (set-buffer nntp-server-buffer) + ;; grab that article's data for new buffer (when beg - (insert-buffer-substring cache-buf beg end) - (insert "\n")) + (push (buffer-substring beg end) new-records) + (push "\n" new-records)) (setq cached (cdr cached))) - (kill-buffer cache-buf))) + ;; we're finished with the cache overview now + (kill-buffer cache-buf) + ;; grab any remaining stuff from old server buffer for new one + (set-buffer nntp-server-buffer) + (let ((new-server-cursor (point-max))) + (when (> new-server-cursor server-cursor) + (push (buffer-substring server-cursor new-server-cursor) new-records))) + ;; reverse chunks and concatenate + (let ((n 0) (records new-records)) + (while records + (incf n (length (car records))) + (setq records (cdr records))) + (let ((new-content (make-string n ?.))) + (setq n 0) + (setq records (nreverse new-records)) + (setf new-records nil) ; help the GC a little + (while records + (store-substring new-content n (car records)) + (incf n (length (car records))) + (setq records (cdr records))) + (set-buffer nntp-server-buffer) + (erase-buffer) + (insert new-content))) )) (defun gnus-cache-braid-heads (group cached) (let ((cache-buf (gnus-get-buffer-create " *gnus-cache*")))