prefetch.el 25.3 KB
Newer Older
Linus Tolke's avatar
Linus Tolke committed
1
2
;;;;;
;;;;; $Id$
3
;;;;; Copyright (C) 1991, 1996  Lysator Academic Computer Association.
Linus Tolke's avatar
Linus Tolke committed
4
5
6
7
8
;;;;;
;;;;; This file is part of the LysKOM server.
;;;;; 
;;;;; LysKOM is free software; you can redistribute it and/or modify it
;;;;; under the terms of the GNU General Public License as published by 
9
;;;;; the Free Software Foundation; either version 2, or (at your option) 
Linus Tolke's avatar
Linus Tolke committed
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
;;;;; any later version.
;;;;; 
;;;;; LysKOM is distributed in the hope that it will be useful, but WITHOUT
;;;;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
;;;;; FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
;;;;; for more details.
;;;;; 
;;;;; You should have received a copy of the GNU General Public License
;;;;; along with LysKOM; see the file COPYING.  If not, write to
;;;;; Lysator, c/o ISY, Linkoping University, S-581 83 Linkoping, SWEDEN,
;;;;; or the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, 
;;;;; MA 02139, USA.
;;;;;
;;;;; Please mail bug reports to bug-lyskom@lysator.liu.se. 
;;;;;
Per Cederqvist's avatar
.    
Per Cederqvist committed
25
26
27
28
29
30
31
32
33
34
35
;;;; ================================================================
;;;;
;;;; File: prefetch.el
;;;;
;;;; This file contains the functions that make up the prefetch
;;;; system.
;;;;
;;;; Author: Inge Wallin
;;;;


36
37
38
39
40
(setq lyskom-clientversion-long 
      (concat lyskom-clientversion-long
	      "$Id$\n"))


Per Cederqvist's avatar
.    
Per Cederqvist committed
41
42
43
44
;;; ================================================================
;;;                          Variables.


David Byers's avatar
X    
David Byers committed
45
(def-kom-var lyskom-prefetch-stack nil
Per Cederqvist's avatar
.    
Per Cederqvist committed
46
47
48
49
50
51
52
  "A stack where all prefetch requests are entered. New items are entered
first and when an item is to be prefetched, it is taken from the front of 
this list. 

Each entry is either the atom 'DONE, a cons cell as described below or a 
lyskom-queue.

David Byers's avatar
X    
David Byers committed
53
54
55
56
57
\('CONFSTAT . number\) - The conf stat of Conference NUMBER.
\('PERSSTAT . number\) - The pers stat of person NUMBER.
\('TEXTSTAT . number\) - The text stat of text NUMBER.
\('TEXTMASS . number\) - The text mass of text NUMBER.
\('TEXTAUTH . number\) - The text stat of the text NUMBER 
Per Cederqvist's avatar
.    
Per Cederqvist committed
58
                       and the conf-stat of the author of it.
David Byers's avatar
X    
David Byers committed
59
\('TEXT-ALL . number\) - The text stat and mass of text NUMBER, but also
Per Cederqvist's avatar
.    
Per Cederqvist committed
60
61
62
63
                       all information that will be used when writing
                       this text for the user to see, such as conf-stat
                       for the author, text stats for commented texts,
                       comments, a.s.o.
David Byers's avatar
X    
David Byers committed
64
\('TEXTTREE . number\) - The text stat, author, textauth of comments to 
Per Cederqvist's avatar
.    
Per Cederqvist committed
65
		       and texttree of all comments and footnotes.
David Byers's avatar
X    
David Byers committed
66
\('CONFSTATFORMAP conf-no first-local\) - The conf-stat of the conference
67
68
		       number CONF-NO is fetched and then we continue
		       to fetch the map.
David Byers's avatar
X    
David Byers committed
69
\('MAP conf-stat first-local\) -
70
71
72
                       The next part of the map in conference CONF-STAT.
		       The length fetched per revolution is according to
		       the value of lyskom-fetch-map-nos.
David Byers's avatar
X    
David Byers committed
73
\('MARKS\) -             The whole list of marked texts and then every info about
74
		       these texts.
David Byers's avatar
X    
David Byers committed
75
76
\('WHOBUFFER\) -         The who-is-on-info to construct the who-buffer.
\('MEMBERSHIP . pers-no\) -
77
78
79
80
81
82
83
		       The next part of the membership for person PERS-NO
		       is fetched. How long we already have fetched is
		       kept in the variable lyskom-membership-is-read. If 
		       lyskom-membership-is-read is not a number then we
		       are done.
		       For every membership-part we fetch the conf-stats
		       before continuing with the next part.
David Byers's avatar
X    
David Byers committed
84
\('MEMBERSHIPISREAD\) -  Just sets the lyskom-membership-is-read variable to t.
85

Per Cederqvist's avatar
.    
Per Cederqvist committed
86

David Byers's avatar
X    
David Byers committed
87
88
See further documentation in the source code."
  local)
Per Cederqvist's avatar
.    
Per Cederqvist committed
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113

;;;
;;; The four requests CONFSTAT, PERSSTAT, TEXTSTAT and TEXTMASS are 
;;; called simple requests and are handled immediately and removed.
;;; The others are called complex requests.  These will each generate
;;; further requests when they return.  
;;; 
;;; When one of the simple requests are sent to the server, the atom
;;; DONE is swapped for the request.
;;;
;;; When one of the complex requests are sent to the server, a
;;; lyskom-queue is swapped for the request and a pointer to the queue
;;; is sent to the handler.  When the call returns the new requests this 
;;; call generates will all be put on the queue.  This process can be
;;; repeated and a queue might contain other queues and so on.  
;;; 
;;; When the prefetch code is searching for a new request to process it
;;; always starts searching at the beginning of the variable 
;;; lyskom-prefetch-stack.  If an empty queue is encountered, it is simply
;;; skipped since this significates a complex request that has already 
;;; been sent and is awaiting its result.  A non-empty queue is recursively
;;; searched and treated in the same way as the original stack.
;;; 


David Byers's avatar
X    
David Byers committed
114
115
116
(def-kom-var lyskom-prefetch-in-action nil
  "t when the prefetch-process is started and going."
  local)
Per Cederqvist's avatar
.    
Per Cederqvist committed
117
118


119
120
121
122
123
(defvar lyskom-inhibit-prefetch nil
  "Set this to a non-nil value locally to inhibit the prefetch.
This is used to prevent the prefetch code to reenter itself.")


David Byers's avatar
X    
David Byers committed
124
125
126
(def-kom-var lyskom-pending-prefetch 0
  "Variable counting the number of unfinished prefetch requests."
  local)
Per Cederqvist's avatar
.    
Per Cederqvist committed
127
128
129
130
131
132
133
134


;;; ================================================================
;;;                 Functions callable from the outside


(defun lyskom-setup-prefetch ()
  "Sets up the prefetch process in lyskom."
135
  (setq lyskom-prefetch-stack (lyskom-stack-create))
136
137
  (setq lyskom-pending-prefetch 0)
  (setq lyskom-membership-is-read 0))
Per Cederqvist's avatar
.    
Per Cederqvist committed
138
139


140
141
142
143
144
145
146
147
148
149
150
151
152
;;;; ================================================================
;;; +++ lyskom-reset-prefetch  to be called on client reset.
;;;                            must restart everything.
;;; +++ THIS DOES NOT WORK CURRENTLY
(defun lyskom-reset-prefetch ()
  "Reset the prefetch system."
  (lyskom-setup-prefetch))


(defsubst lyskom-membership-is-read ()
  "Return t if the while membership list has been fetched, and nil otherwise."
  (eq lyskom-membership-is-read 't))

Per Cederqvist's avatar
.    
Per Cederqvist committed
153
154
155
156
(defun lyskom-prefetch-conf (conf-no &optional queue)
  "Prefetch the conf-stat for the conference with number CONF-NO.
If QUEUE is non-nil, put the request on it, otherwise put it on 
lyskom-prefetch-stack."
157
158
159
160
161
  (if conf-no
      (if queue
	  (lyskom-queue-enter queue (cons 'CONFSTAT conf-no))
	(lyskom-stack-push lyskom-prefetch-stack (cons 'CONFSTAT conf-no)))
    (signal 'lyskom-internal-error "No argument to lyskom-prefetch-conf"))
Per Cederqvist's avatar
.    
Per Cederqvist committed
162
163
164
165
166
167
168
169
  (lyskom-continue-prefetch))


(defun lyskom-prefetch-pers (pers-no &optional queue)
  "Prefetch the pers-stat for person with number PERS-NO.
If QUEUE is non-nil, put the request on it, otherwise put it on 
lyskom-prefetch-stack."
  (if queue
170
171
      (lyskom-queue-enter queue (cons 'PERSSTAT pers-no))
    (lyskom-stack-push lyskom-prefetch-stack (cons 'PERSSTAT pers-no)))
Per Cederqvist's avatar
.    
Per Cederqvist committed
172
173
174
175
176
177
178
179
  (lyskom-continue-prefetch))


(defun lyskom-prefetch-text (text-no &optional queue)
  "Prefetch the text-stat for the text with number TEXT-NO.
If QUEUE is non-nil, put the request on it, otherwise put it on 
lyskom-prefetch-stack."
  (if queue
180
181
      (lyskom-queue-enter queue (cons 'TEXTSTAT text-no))
    (lyskom-stack-push lyskom-prefetch-stack (cons 'TEXTSTAT text-no)))
Per Cederqvist's avatar
.    
Per Cederqvist committed
182
183
184
185
186
187
188
189
  (lyskom-continue-prefetch))


(defun lyskom-prefetch-textmass (text-no &optional queue)
  "Prefetch the text mass for the text with number TEXT-NO.
If QUEUE is non-nil, put the request on it, otherwise put it on 
lyskom-prefetch-stack."
  (if queue
190
191
      (lyskom-queue-enter queue (cons 'TEXTMASS text-no))
    (lyskom-stack-push lyskom-prefetch-stack (cons 'TEXTMASS text-no)))
Per Cederqvist's avatar
.    
Per Cederqvist committed
192
193
194
195
196
197
198
199
  (lyskom-continue-prefetch))
  

(defun lyskom-prefetch-textauth (text-no &optional queue)
  "Prefetch the text stat and the author of text number TEXT-NO.
If QUEUE is non-nil, put the request on it, otherwise put it on 
lyskom-prefetch-stack."
  (if queue
200
201
      (lyskom-queue-enter queue (cons 'TEXTAUTH text-no))
    (lyskom-stack-push lyskom-prefetch-stack (cons 'TEXTAUTH text-no)))
Per Cederqvist's avatar
.    
Per Cederqvist committed
202
203
204
205
206
207
208
209
  (lyskom-continue-prefetch))
  

(defun lyskom-prefetch-text-all (text-no &optional queue)
  "Prefetch all info about the text with number TEXT-NO.
If QUEUE is non-nil, put the request on it, otherwise put it on 
lyskom-prefetch-stack."
  (if queue
210
211
      (lyskom-queue-enter queue (cons 'TEXT-ALL text-no))
    (lyskom-stack-push lyskom-prefetch-stack (cons 'TEXT-ALL text-no)))
Per Cederqvist's avatar
.    
Per Cederqvist committed
212
213
214
  (lyskom-continue-prefetch))


215
(defun lyskom-prefetch-texttree (text-no &optional queue only-new)
Per Cederqvist's avatar
.    
Per Cederqvist committed
216
217
  "Prefetch all info about the text with number TEXT-NO and descends recursively.
If QUEUE is non-nil, put the request on it, otherwise put it on 
218
219
220
221
222
223
224
225
226
227
lyskom-prefetch-stack.

If ONLY-NEW is non-nil and the text-stat in question is already
prefetched the prefetch is not done."
  (if (and only-new
	   (cache-get-text-stat text-no))
      nil
    (if queue
	(lyskom-queue-enter queue (cons 'TEXTTREE text-no))
      (lyskom-stack-push lyskom-prefetch-stack (cons 'TEXTTREE text-no))))
Per Cederqvist's avatar
.    
Per Cederqvist committed
228
229
230
  (lyskom-continue-prefetch))
  

inge's avatar
inge committed
231
232
233
234
(defun lyskom-prefetch-membership (pers-no &optional queue)
  "+++"
  ;; h{mtar medlemsskapet i sm} delar 
  ;; och d{refter conf-stat f|r m|tena
235
236
237
238
239
240
  (if queue
      (lyskom-queue-enter queue (cons 'MEMBERSHIP pers-no))
    (lyskom-stack-push lyskom-prefetch-stack (cons 'MEMBERSHIP pers-no)))
  (lyskom-continue-prefetch))


241
242
243
244
245
246
247
248
249
250
(defun lyskom-prefetch-map (conf-no membership &optional queue)
  "Prefetches a map for conf CONFNO."
  (lyskom-prefetch-map-from conf-no
			    (1+ (membership->last-text-read membership))
			    membership
			    queue))


(defun lyskom-prefetch-map-from (conf-no first-local membership
					 &optional queue)
251
252
  "Prefetches a map for conf CONFNO starting att FIRST-LOCAL."
  (if queue
253
254
255
256
257
      (lyskom-queue-enter queue (list 'CONFSTATFORMAP
				      conf-no first-local membership))
    (lyskom-stack-push lyskom-prefetch-stack
		       (list 'CONFSTATFORMAP
			     conf-no first-local membership)))
258
259
260
  (lyskom-continue-prefetch))


261
(defun lyskom-prefetch-map-using-conf-stat (conf-stat first-local membership
262
263
264
						      &optional queue)
  "Prefetches a map for conf CONFSTAT starting att FIRST-LOCAL."
  (if queue
265
      (lyskom-queue-enter queue (list 'MAP conf-stat first-local membership))
266
    (lyskom-stack-push lyskom-prefetch-stack (list 'MAP
267
268
						   conf-stat first-local
						   membership)))
269
  (lyskom-continue-prefetch))
inge's avatar
inge committed
270
271
272
273
274
275
276
277


(defun lyskom-prefetch-all-conf-stats (&optional queue)
  "+++"
  nil)


(defun lyskom-prefetch-marks (&optional queue)
278
279
280
281
282
  "Prefetches the list of marked texts. Then all texts are fetched."
  (if queue
      (lyskom-queue-enter queue (list 'MARKS))
    (lyskom-stack-push lyskom-prefetch-stack (list 'MARKS)))
  (lyskom-continue-prefetch))
inge's avatar
inge committed
283
284
285


(defun lyskom-prefetch-who-is-on (&optional queue)
286
287
288
289
290
  "Prefetches the list of persons on the system."
  (if queue
      (lyskom-queue-enter queue (list 'WHOBUFFER))
    (lyskom-stack-push lyskom-prefetch-stack (list 'WHOBUFFER)))
  (lyskom-continue-prefetch))
inge's avatar
inge committed
291
292


293
294
295
296
297
298
;;(defun lyskom-prefetch-all-conf-texts (&optional queue)
;;  "Prefetches the texts in all conferences."
;;  (if queue
;;      (lyskom-queue-enter queue (list 'ALL-CONF-TEXTS))
;;    (lyskom-stack-push lyskom-prefetch-stack (list 'ALL-CONF-TEXTS)))
;;  (lyskom-continue-prefetch))
299
300


301
302
303
304
305
306
307
308
;;(defun lyskom-prefetch-conf-texts (text-list &optional queue)
;;  "Prefetches the texts in all conferences."
;;  (if (null (text-list->texts text-list))
;;      nil
;;    (if queue
;;	(lyskom-queue-enter queue (list 'CONF-TEXTS text-list))
;;      (lyskom-stack-push lyskom-prefetch-stack (list 'CONF-TEXTS text-list))))
;;  (lyskom-continue-prefetch))
309

310
(defun lyskom-prefetch-texts (texts &optional queue)
311
  "Prefetches a list of texts."
312
  (if (null texts)
313
314
      nil
    (if queue
315
	(lyskom-queue-enter queue
316
			    (list 'TEXTS texts))
317
      (lyskom-stack-push lyskom-prefetch-stack
318
			 (list 'TEXTS texts))))
319
320
  (lyskom-continue-prefetch))

321
322
323
324
325
326
327
328
329
;; (defun lyskom-prefetch-text-list-continue (texts &optional queue)
;;   "Prefetches a list of texts."
;;   (if (null texts)
;; 	 nil
;;     (if queue
;; 	   (lyskom-queue-enter queue (list 'TEXT-LIST-CONT texts))
;; 	 (lyskom-stack-push lyskom-prefetch-stack
;; 			    (list 'TEXT-LIST-CONT texts))))
;;   (lyskom-continue-prefetch))
330

331

Per Cederqvist's avatar
.    
Per Cederqvist committed
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
;;; ================================================================
;;;           Functions internal to the prefetch package


(defun lyskom-stop-prefetch ()
  "Stop the prefetch process temporarily."
  (setq lyskom-prefetch-in-action nil))


(defun lyskom-start-prefetch ()
  "Start the whole prefetch process"
  (setq lyskom-prefetch-in-action t)
  (lyskom-continue-prefetch))


(defun lyskom-continue-prefetch ()
  "Called after each prefetch is finished and also when the whole prefetch
process is started. Used to keep prefetch going."
350
351
  (if (not lyskom-inhibit-prefetch)
      (let ((lyskom-inhibit-prefetch t)) ; Make sure we don't call this 
352
353
354
355
					; recursively
	(while (and (< lyskom-pending-prefetch
		       lyskom-prefetch-limit)
		    (lyskom-prefetch-one-item)
356
357
358
359
360
361
362
363
		    ;; Only increase lyskom-pending-prefetch if a server
		    ;; call was made.
		    ;;
		    ;; The return value from lyskom-prefetch-one-item
		    ;; is whether it has sent a server call, but it
		    ;; should really be if the prefetch-stack has been
		    ;; altered. See the comment in
		    ;; lyskom-prefetch-one-item.
364
		    (++ lyskom-pending-prefetch))))))
Per Cederqvist's avatar
.    
Per Cederqvist committed
365
366
367
368
369
370
371
372
373
374


(defun lyskom-skip-finished-in-queue (queue)
  "Remove all 'DONE entries and queues who's only entry is 'FINISHED."
  (let ((element nil)
	(done nil))
    (while (not done)
      (setq element (lyskom-queue->first queue))
      (if (or (eq element 'DONE)
	      (and (lyskom-queue-p element)
375
		   (eq (lyskom-queue->first element) 'FINISHED)))
Per Cederqvist's avatar
.    
Per Cederqvist committed
376
377
378
379
380
381
382
383
	  (lyskom-queue-delete-first queue)
	(setq done t)))))


(defun lyskom-prefetch-one-item ()
  "Get the first element of the prefetch data structure and fetch it.
Return t if an element was prefetched, otherwise return nil."
  (let ((result nil)
384
	element
Per Cederqvist's avatar
.    
Per Cederqvist committed
385
386
387
388
	(prefetch-list (lyskom-stack->all-entries lyskom-prefetch-stack))
	(list-stack (lyskom-stack-create))
    	(done nil))

389
    ; Remove all finished entries at the top of lyskom-prefetch-stack
Per Cederqvist's avatar
.    
Per Cederqvist committed
390
391
392
393
    (while (not done)
      (setq element (lyskom-stack->top lyskom-prefetch-stack))
      (if (or (eq element 'DONE)
	      (and (lyskom-queue-p element)
394
		   (eq (lyskom-queue->first element) 'FINISHED)))
Per Cederqvist's avatar
.    
Per Cederqvist committed
395
396
397
398
399
	  (lyskom-stack-pop lyskom-prefetch-stack)
	(setq done t)))

    (while (and (not result)
		prefetch-list)
400
401
402
403
404
405
406
407
408
409
410
411
412
      (let ((element (car prefetch-list))
	    (rest-list (cdr prefetch-list)))
	(cond
	 ((eq element 'DONE) nil)
	 ((eq element 'FINISHED) nil)

	 ;; A queue ==> check it out first.
	 ((lyskom-queue-p element)
	  (lyskom-skip-finished-in-queue element)
	  (if (lyskom-queue-isempty element)
	      nil
	    (lyskom-stack-push list-stack rest-list)
	    (setq rest-list (lyskom-queue->all-entries element))))
Per Cederqvist's avatar
.    
Per Cederqvist committed
413
       
414
415
416
	 ;; A simple request?
	 ((and (listp element)
	       (memq (car element)
417
		     '(CONFSTAT PERSSTAT TEXTSTAT TEXTMASS)))
418
419
420
421
422
423
424
425
	  (setcar prefetch-list 'DONE)
	  (lyskom-prefetch-one-request element nil)
	  (setq result t))

	 ;; A complex request?
	 ((and (listp element)
	       (memq (car element)
		     '(TEXTAUTH TEXT-ALL TEXTTREE 
426
				CONFSTATFORMAP MAP MARKS
427
				MEMBERSHIP WHOBUFFER TEXTS)))
428
429
430
431
	  (let ((queue (lyskom-queue-create)))
	    (setcar prefetch-list queue)
	    (lyskom-prefetch-one-request element queue)
	    (setq result t)))
432

433
	 ;; Special requests
434
	 ((and (listp element)
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
	       (memq (car element) '(MEMBERSHIPISREAD ALL-CONF-TEXTS)))
	  (if (eq (car element) 'MEMBERSHIPISREAD)
	      (setq lyskom-membership-is-read t)
	    ;; Temporarily disabled
	    (let ((queue (lyskom-queue-create)))
	      (setcar prefetch-list queue)
	      (mapcar
	       (lambda (read-info)
		 (mapcar
		  (lambda (text-no)
		    (lyskom-prefetch-text-all text-no queue))
		  (text-list->texts (read-info->text-list read-info))))
	       (read-list->all-entries lyskom-to-do-list))
	      (lyskom-queue-enter queue 'FINISHED)))

	  ;; This is an ugly hack. If this function returns a non-nil
	  ;; value, lyskom-prefetch-continue will assume that a server
	  ;; call was made and increase lyskom-pending-prefetch. But
	  ;; no server call has been made, so we decrease
	  ;; lyskom-pending-prefetch "in advance". The reason that
	  ;; this sets result to t is that we want the loop in
	  ;; lyskom-continue-prefetch to keep running, as there is no
	  ;; server response that will wake the prefetch up in the
	  ;; future.
	  ;;(-- lyskom-pending-prefetch)
	  ;;(setq result t)
	  )

463
464
	 (t (signal 'lyskom-internal-error 
		    '(lyskom-prefetch-one-item ": unknown key"))))
465
	
466
467
468
469
	(setq prefetch-list rest-list)
	(if (not (or prefetch-list
		     (lyskom-stack-isempty list-stack)))
	    (setq prefetch-list (lyskom-stack-pop list-stack)))))
Per Cederqvist's avatar
.    
Per Cederqvist committed
470

471
    result))
Per Cederqvist's avatar
.    
Per Cederqvist committed
472
473
474
475
476
477


(defun lyskom-prefetch-one-request (request queue)
  "Prefetch REQUEST. If the request is complex, put the resulting requests on QUEUE."
  (cond
   ((eq (car request) 'CONFSTAT)
478
479
    (initiate-get-conf-stat 'prefetch
			    'lyskom-prefetch-handler (cdr request)))
Per Cederqvist's avatar
.    
Per Cederqvist committed
480
   ((eq (car request) 'PERSSTAT)
481
482
    (initiate-get-pers-stat 'prefetch
			    'lyskom-prefetch-handler (cdr request)))
Per Cederqvist's avatar
.    
Per Cederqvist committed
483
   ((eq (car request) 'TEXTSTAT)
484
485
    (initiate-get-text-stat 'prefetch
			    'lyskom-prefetch-handler (cdr request)))
Per Cederqvist's avatar
.    
Per Cederqvist committed
486
   ((eq (car request) 'TEXTMASS)
487
    (initiate-get-text 'prefetch 'lyskom-prefetch-handler (cdr request)))
Per Cederqvist's avatar
.    
Per Cederqvist committed
488
   ((eq (car request) 'TEXTAUTH)
489
490
    (initiate-get-text-stat 'prefetch 'lyskom-prefetch-textauth-handler 
			    (cdr request) queue))
Per Cederqvist's avatar
.    
Per Cederqvist committed
491
492
   ((eq (car request) 'TEXT-ALL)
    (initiate-get-text-stat 'prefetch 'lyskom-prefetch-text-all-handler
493
			    (cdr request) queue))
Per Cederqvist's avatar
.    
Per Cederqvist committed
494
495
   ((eq (car request) 'TEXTTREE)
    (initiate-get-text-stat 'prefetch 'lyskom-prefetch-texttree-handler
496
497
498
499
500
501
502
503
504
505
506
507
508
			    (cdr request) queue))
   ((eq (car request) 'MEMBERSHIP)
    (if (numberp lyskom-membership-is-read) ; Are we done?
	(initiate-get-part-of-membership 
	 'prefetch 'lyskom-prefetch-membership-handler
	 (cdr request)
	 lyskom-membership-is-read lyskom-fetch-membership-length 
	 (cdr request)
	 queue)
      ; We are done
      (lyskom-prefetch-handler)))
   ((eq (car request) 'CONFSTATFORMAP)
    (initiate-get-conf-stat 'prefetch 'lyskom-prefetch-confstatformap-handler
509
510
			    (nth 1 request) (nth 2 request) (nth 3 request)
			    queue))
511
512
   ((eq (car request) 'MAP)
    (initiate-get-map 'prefetch 'lyskom-prefetch-map-handler
513
514
515
		      (conf-stat->conf-no
		       (nth 1 request))	; conf-stat
		      (nth 2 request)	; first-local
516
		      lyskom-fetch-map-nos
517
518
519
		      (nth 1 request)	; conf-stat
		      (nth 2 request)	; first-local
		      (nth 3 request)	; membership
520
		      queue))
521
522
523
524
   ((eq (car request) 'MARKS)
    (initiate-get-marks 'prefetch 'lyskom-prefetch-marks-handler queue))
   ((eq (car request) 'WHOBUFFER)
    (initiate-who-is-on 'prefetch 'lyskom-prefetch-whobuffer-handler queue))
525
526
   ((eq (car request) 'TEXTS)
    (initiate-get-text-stat 'prefetch 'lyskom-prefetch-texts-handler
527
528
529
			    (car (nth 1 request))
			    (cdr (nth 1 request))
			    queue))
530
   
Per Cederqvist's avatar
.    
Per Cederqvist committed
531
532
533
534
535
536
537
538
539
540
541
542
543
   (t (signal 'lyskom-internal-error
	      (list "lyskom-prefetch-one-request - unknown key:"
		    (car request))))))


;;; ================================================================
;;;      Functions which handle the results of complex requests.


(defun lyskom-prefetch-textauth-handler (text-stat queue)
  "Prefetch the conf-stat of the author of the text TEXT-STAT.
Put the request on QUEUE."
  (lyskom-stop-prefetch)
544
545
546
547
  (if (not text-stat)
      nil
    (lyskom-prefetch-conf (text-stat->author text-stat) queue)
    (lyskom-queue-enter queue 'FINISHED))
Per Cederqvist's avatar
.    
Per Cederqvist committed
548
549
550
551
552
553
554
555
  (-- lyskom-pending-prefetch)
  (lyskom-start-prefetch))


(defun lyskom-prefetch-text-all-handler (text-stat queue)
  "Prefetch all info neccessary to write the text with text-stat TEXT-STAT.
Put the requests on QUEUE."
  (lyskom-stop-prefetch)
556
557
  (lyskom-prefetch-conf (text-stat->author text-stat) queue)
  (lyskom-prefetch-textmass (text-stat->text-no text-stat) queue)
Per Cederqvist's avatar
.    
Per Cederqvist committed
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
  (lyskom-traverse
   misc
   (text-stat->misc-info-list text-stat)
   (let ((type (misc-info->type misc)))
     (cond
      ((or (eq type 'RECPT)
	   (eq type 'CC-RECPT))
       (lyskom-prefetch-conf (misc-info->recipient-no misc) queue))
      ((eq type 'COMM-IN)
       (lyskom-prefetch-textauth (misc-info->comm-in misc) queue))
      ((eq type 'FOOTN-IN)
       (lyskom-prefetch-textauth (misc-info->footn-in misc) queue))
      ((eq type 'COMM-TO)
       (lyskom-prefetch-textauth (misc-info->comm-to misc) queue))
      ((eq type 'FOOTN-TO)
       (lyskom-prefetch-textauth (misc-info->footn-to misc) queue))
      (t nil))))
  (lyskom-queue-enter queue 'FINISHED)
  (-- lyskom-pending-prefetch)
  (lyskom-start-prefetch))


(defun lyskom-prefetch-texttree-handler (text-stat queue)
  "Prefetch all info neccessary to write the text with text-stat TEXT-STAT.
Then prefetch all info (texttree) of comments.
Put the requests on QUEUE."
584
585
586
587
588
589
590
591
592
593
594
595
596
597
  (if (not text-stat)
      nil				; We did not get anything
    (lyskom-stop-prefetch)
    (lyskom-prefetch-conf (text-stat->author text-stat) queue)
    (lyskom-prefetch-textmass (text-stat->text-no text-stat) queue)
    (lyskom-traverse
     misc
     (text-stat->misc-info-list text-stat)
     (let ((type (misc-info->type misc)))
       (cond
	((or (eq type 'RECPT)
	     (eq type 'CC-RECPT))
	 (lyskom-prefetch-conf (misc-info->recipient-no misc) queue))
	((eq type 'COMM-IN)
598
	 (lyskom-prefetch-texttree (misc-info->comm-in misc) queue t))
599
	((eq type 'FOOTN-IN)
600
	 (lyskom-prefetch-texttree (misc-info->footn-in misc) queue t))
601
602
603
604
605
606
	((eq type 'COMM-TO)
	 (lyskom-prefetch-textauth (misc-info->comm-to misc) queue))
	((eq type 'FOOTN-TO)
	 (lyskom-prefetch-textauth (misc-info->footn-to misc) queue))
	(t nil))))
    (lyskom-queue-enter queue 'FINISHED))
Per Cederqvist's avatar
.    
Per Cederqvist committed
607
608
609
610
  (-- lyskom-pending-prefetch)
  (lyskom-start-prefetch))


611
(defun lyskom-prefetch-membership-handler (memberships pers-no queue)
612
613
  "Handle the return of the membership prefetch call."
  (lyskom-stop-prefetch)
614
615
  (let ((size (length memberships))
	(i 0))
616
    (lyskom-add-memberships-to-membership memberships)
617
618
619
620
621
622
623
    (while (< i size)
      (let ((membership (aref memberships i)))
	(if (lyskom-visible-membership membership)
	    (lyskom-prefetch-map (membership->conf-no membership)
				 membership
				 queue)))
      (++ i))
624
    (if (and (numberp lyskom-membership-is-read)
625
	     (< (length memberships) lyskom-fetch-membership-length))
626
627
628
	(progn
	  (setq lyskom-membership-is-read 'almost)
	  (lyskom-queue-enter queue (list 'MEMBERSHIPISREAD)))
629
630
      (setq lyskom-membership-is-read (+ lyskom-membership-is-read
					 lyskom-fetch-membership-length))
631
632
      (lyskom-prefetch-membership pers-no queue)
      ))
633
634
635
636
637
  (lyskom-queue-enter queue 'FINISHED)
  (-- lyskom-pending-prefetch)
  (lyskom-start-prefetch))


638
639
(defun lyskom-prefetch-confstatformap-handler (conf-stat first-local
							 membership queue)
640
641
  "Now that we have the conf-stat we can fetch the map."
  (lyskom-stop-prefetch)
642
  (lyskom-prefetch-map-using-conf-stat conf-stat first-local membership queue)
643
644
645
646
647
  (lyskom-queue-enter queue 'FINISHED)
  (-- lyskom-pending-prefetch)
  (lyskom-start-prefetch))


648
(defun lyskom-prefetch-map-handler (map conf-stat first-local membership queue)
649
650
651
  "Handle the return of the membership prefetch call.
Maps are `cached' in lyskom-to-do-list."
  (lyskom-stop-prefetch)
652
653
654
655
656
657
658
659
660
661
662
663
  (let ((next-start (+ first-local lyskom-fetch-map-nos))
	(last-local (1- (+ (conf-stat->no-of-texts conf-stat)
		  (conf-stat->first-local-no conf-stat)))))
    (when map
      ;; An old version of this function tester if the map contained no
      ;; texts. That is not a correct termination condition.
      (when (< next-start last-local)
	(lyskom-prefetch-map-using-conf-stat conf-stat
					     next-start
					     membership
					     queue))
      (lyskom-enter-map-in-to-do-list map conf-stat membership)))
664
665
666
  (lyskom-queue-enter queue 'FINISHED)
  (-- lyskom-pending-prefetch)
  (lyskom-start-prefetch)
667
  (lyskom-update-prompt)
668
669
  (lyskom-set-mode-line))

670
671
672
673
674
675
676
677
678
679
680
681
682
683
(defun lyskom-prefetch-marks-handler (marks queue)
  "Handle the list of marked texts."
  (cache-set-marked-texts marks)
  (lyskom-stop-prefetch)
  (let ((list (cache-get-marked-texts)))
    (while list
      (lyskom-prefetch-text-all (mark->text-no (car list)) queue)
      (setq list (cdr list))))
  (-- lyskom-pending-prefetch)
  (lyskom-start-prefetch))


(defun lyskom-prefetch-whobuffer-handler (who-is-on queue)
  "Handle the who-is-on info. The goal here is to get an updated who-buffer."
684
685
  ;+++ should be done later
  (cache-initiate-who-info-buffer who-is-on lyskom-buffer)
686
  (-- lyskom-pending-prefetch)
687
688
  )

689
(defun lyskom-prefetch-texts-handler (text-stat texts queue)
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
  "Prefetch all info neccessary to write the text with text-stat TEXT-STAT.
Put the requests on QUEUE."
  (lyskom-stop-prefetch)
  (lyskom-prefetch-conf (text-stat->author text-stat) queue)
  (lyskom-prefetch-textmass (text-stat->text-no text-stat) queue)
  (lyskom-traverse
      misc
      (text-stat->misc-info-list text-stat)
    (let ((type (misc-info->type misc)))
      (cond
       ((or (eq type 'RECPT)
	    (eq type 'CC-RECPT))
	(lyskom-prefetch-conf (misc-info->recipient-no misc) queue))
       ((eq type 'COMM-IN)
	(lyskom-prefetch-textauth (misc-info->comm-in misc) queue))
       ((eq type 'FOOTN-IN)
	(lyskom-prefetch-textauth (misc-info->footn-in misc) queue))
       ((eq type 'COMM-TO)
	(lyskom-prefetch-textauth (misc-info->comm-to misc) queue))
       ((eq type 'FOOTN-TO)
	(lyskom-prefetch-textauth (misc-info->footn-to misc) queue))
       (t nil))))
712
713
714
  (lyskom-queue-enter queue 'FINISHED)
  ;; The queue is now used up.
  (lyskom-prefetch-texts texts)
715
716
  (-- lyskom-pending-prefetch)
  (lyskom-start-prefetch))
717

Per Cederqvist's avatar
.    
Per Cederqvist committed
718
719
720
721
(defun lyskom-prefetch-handler (&rest data)
  "Handler called after each simple prefetch request is done."
  (-- lyskom-pending-prefetch)
  (lyskom-continue-prefetch))