Version:
~ [ 10.0 ] ~
** Warning: Cannot open xref database.
1
2 /* $Id: dbstats.c,v 1.3 2005/01/11 22:48:05 andreradke Exp $ */
3
4 /******************************************************************************
5
6 UserLand Frontier(tm) -- High performance Web content management,
7 object database, system-level and Internet scripting environment,
8 including source code editing and debugging.
9
10 Copyright (C) 1992-2004 UserLand Software, Inc.
11
12 This program is free software; you can redistribute it and/or modify
13 it under the terms of the GNU General Public License as published by
14 the Free Software Foundation; either version 2 of the License, or
15 (at your option) any later version.
16
17 This program is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 GNU General Public License for more details.
21
22 You should have received a copy of the GNU General Public License
23 along with this program; if not, write to the Free Software
24 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25
26 ******************************************************************************/
27
28 #include "frontier.h"
29 #include "standard.h"
30
31 #include "memory.h"
32 #include "cursor.h"
33 #include "font.h"
34 #include "kb.h"
35 #include "quickdraw.h"
36 #include "resources.h"
37 #include "strings.h"
38 #include "frontierwindows.h"
39 #include "shell.h"
40 #include "db.h"
41 #include "dbinternal.h"
42
43
44
45 #define idstatsstringlist 140
46
47
48 enum { /*statsmessage indexes*/
49
50 idwindowtitle = 1,
51
52 idnodesinreleaselist,
53 idbytesinreleaselist,
54 idnodesinavaillist,
55 idbytesinavaillist,
56 idlargestfreenode,
57 idnumberinconsistent,
58 idnodesfreesequentially,
59 idbytesfreesequentially,
60 idnodesusedsequentially,
61 idbytesusedsequentially,
62 idnodesusedlogically,
63 idbytesusedlogically,
64 idnumberbytesorphaned,
65
66 idreadheaderfailed,
67 idreadusedheaderfailed,
68 idfreeblockinuse,
69 idreadavailnodefailed,
70 idgeteoffailed,
71 idreadheaderfailed1,
72 idreadtrailerfailed2,
73 idheadertrailerdisagree,
74 idavailshadowoutofsynch
75 };
76
77
78 typedef struct tystatsrecord {
79
80 boolean flstatscomputed;
81
82 long ctreleasenodes, ctreleasebytes;
83
84 long ctavail, cttotalbytes, ctlargestblock;
85
86 long seqctfree, seqctinuse, seqsizefree, seqsizeinuse;
87
88 long logctinuse, logsizeinuse;
89
90 long ctinconsistencies;
91
92 bigstring bsmessage;
93
94 short vstats; /*vertical offset next line is drawn at*/
95
96 short hstats; /*horizontal offset*/
97
98 short statslineheight;
99 } tystatsrecord, *ptrstatsrecord, **hdlstatsrecord;
100
101
102 static WindowPtr statswindow = nil;
103
104 static hdlwindowinfo statswindowinfo = nil;
105
106 static hdlstatsrecord statsdata = nil;
107
108
109
110
111 static void getstatsstring (short id, bigstring bs) {
112
113 getstringlist (idstatsstringlist, id, bs);
114 } /*getstatsstring*/
115
116
117 static void setstatsmessage (short id) {
118
119 bigstring bs;
120
121 getstatsstring (id, bs);
122
123 copystring (bs, (**statsdata).bsmessage);
124 } /*setstatsmessage*/
125
126
127 static void statsline (bigstring bs) {
128
129 register hdlstatsrecord hs = statsdata;
130
131 movepento ((**hs).hstats, (**hs).vstats);
132
133 pendrawstring (bs);
134
135 (**hs).vstats += (**hs).statslineheight;
136
137 //Timothy Paustian 10/5/00
138 //We need to flush the result to the stats window everytime to see it
139 //If this is not called the window remains blank.
140 #if TARGET_API_MAC_CARBON == 1
141 QDFlushPortBuffer(GetWindowPort(statswindow), nil);
142 #endif
143 } /*statsline*/
144
145
146 static void statsdisplay (short idstat, long n) {
147
148 bigstring bs;
149
150 getstatsstring (idstat, bs);
151
152 pushstring ((ptrstring) "\x03" " = ", bs);
153
154 pushlong (n, bs);
155
156 statsline (bs);
157 } /*statsdisplay*/
158
159
160 static void statsupdate (void) {
161
162 register hdlstatsrecord hs = statsdata;
163 register hdlwindowinfo hw = statswindowinfo;
164 Rect r;
165
166 pushstyle ((**hw).defaultfont, (**hw).defaultsize, (**hw).defaultstyle);
167
168 (**hs).statslineheight = globalfontinfo.ascent + globalfontinfo.descent + 3;
169
170 r = (**hw).contentrect;
171
172 if (!(**hs).flstatscomputed)
173 eraserect (r);
174
175 else {
176
177 (**hs).vstats = r.top + (**hs).statslineheight;
178
179 (**hs).hstats = r.left + 8;
180
181 statsdisplay (idnodesinreleaselist, (**hs).ctreleasenodes);
182
183 statsdisplay (idbytesinreleaselist, (**hs).ctreleasebytes);
184
185 statsline (zerostring);
186
187 if ((**hs).ctavail >= 0) {
188
189 statsdisplay (idnodesinavaillist, (**hs).ctavail);
190
191 statsdisplay (idbytesinavaillist, (**hs).cttotalbytes);
192
193 statsdisplay (idlargestfreenode, (**hs).ctlargestblock);
194
195 statsdisplay (idnumberinconsistent, (**hs).ctinconsistencies);
196
197 statsline (zerostring);
198 }
199
200 if ((**hs).seqctinuse > 0) {
201
202 statsdisplay (idnodesfreesequentially, (**hs).seqctfree);
203
204 statsdisplay (idbytesfreesequentially, (**hs).seqsizefree);
205
206 statsdisplay (idnodesusedsequentially, (**hs).seqctinuse);
207
208 statsdisplay (idbytesusedsequentially, (**hs).seqsizeinuse);
209
210 statsline (zerostring);
211 }
212
213 if ((**hs).logctinuse > 0) {
214
215 statsdisplay (idnodesusedlogically, (**hs).logctinuse);
216
217 statsdisplay (idbytesusedlogically, (**hs).logsizeinuse);
218
219 statsdisplay (idnumberbytesorphaned, (**hs).seqsizeinuse - (**hs).logsizeinuse - (**hs).ctreleasebytes);
220 }
221 }
222
223 popstyle ();
224 } /*statsupdate*/
225
226
227 static boolean statscountreleasestack (long *ctreleasenodes, long *ctreleasebytes) {
228
229 /*
230 release all the chunks accumulated in the database's releasestack.
231 */
232
233 Handle h = (**databasedata).releasestack;
234 register long ct;
235 register long ctreleased = 0;
236 long ctbytes;
237 boolean flfree;
238 tyvariance variance;
239 #ifdef DATABASE_DEBUG
240 register tydbreleasestackframe *p;
241 #else
242 register ptrdbaddress p;
243 #endif
244
245 *ctreleasenodes = 0;
246
247 *ctreleasebytes = 0;
248
249 if (h == nil) /*nothing released*/
250 return (true);
251
252 #ifdef DATABASE_DEBUG
253 ct = *ctreleasenodes = gethandlesize (h) / sizeof (tydbreleasestackframe);
254
255 p = (tydbreleasestackframe*) *h;
256
257 while (--ct >= 0) {
258
259 if (!dbreadheader ((p++)->adr, &flfree, &ctbytes, &variance)) {
260
261 setstatsmessage (idreadheaderfailed);
262
263 return (false);
264 }
265
266 rollbeachball ();
267
268 ctreleased += ctbytes;
269 }
270 #else
271 ct = *ctreleasenodes = gethandlesize (h) / sizeof (dbaddress);
272
273 p = (ptrdbaddress) *h;
274
275 while (--ct >= 0) {
276
277 if (!dbreadheader (*p++, &flfree, &ctbytes, &variance)) {
278
279 setstatsmessage (idreadheaderfailed);
280
281 return (false);
282 }
283
284 rollbeachball ();
285
286 ctreleased += ctbytes;
287 }
288 #endif
289
290 *ctreleasebytes = ctreleased;
291
292 return (true);
293 } /*statscountreleasestack*/
294
295
296 boolean statsblockinuse (dbaddress adr, bigstring bsitem) {
297
298 /*
299 called from the EFPs directly as we're doing our content-based
300 database scan.
301
302 5.0a25 dmb: added bsitem parameter, keyboardescape check
303 */
304
305 register hdlstatsrecord hs = statsdata;
306 boolean flfree;
307 long ctbytes;
308 tyvariance variance;
309
310 if (adr == nildbaddress) /*ok to pass nil*/
311 return (true);
312
313 if (keyboardescape ())
314 return (false);
315
316 /*
317 if (bsitem != nil) {
318
319 shellsetwindowmessage (statswindowinfo, bsitem);
320
321 shelldrawwindowmessage (statswindowinfo);
322 }
323 */
324
325 if (!dbreadheader (adr, &flfree, &ctbytes, &variance)) {
326
327 setstatsmessage (idreadusedheaderfailed);
328
329 return (false);
330 }
331
332 if (flfree) {
333
334 setstatsmessage (idfreeblockinuse);
335
336 return (false);
337 }
338
339 (**hs).logctinuse++;
340
341 (**hs).logsizeinuse += ctbytes;
342
343 return (true);
344 } /*statsblockinuse*/
345
346
347 static boolean statscompute (boolean flincludeusedblocks) {
348
349 /*
350 the first three statistics are numbers produced by traversing the
351 avail list.
352
353 the other numbers are determined by doing a sequential scan of the
354 database, record by record.
355
356 ctinconsistencies is the result of comparing the trailer with the balancing
357 header in each block in the database. if they all agree with each other
358 then ctinconsistencies is 0, otherwise the number of errors is reported.
359
360 7/8/91 dmb: roll the beach ball
361 */
362
363 register hdlstatsrecord hs = statsdata;
364 long ctnodes;
365 long totalbytes;
366 long largestblock;
367 dbaddress nomad;
368 boolean flfree, fl2;
369 long ctbytes, ct2;
370 dbaddress nextnomad;
371 long ctfree, ctinuse, sizefree, sizeinuse, eof;
372 long ctincon;
373 tyvariance variance;
374 hdlavaillistshadow havailshadow = (hdlavaillistshadow) (**databasedata).u.extensions.availlistshadow.data;
375
376 initbeachball (right);
377
378 clearhandle ((Handle) hs);
379
380 statsupdate ();
381
382 if (!statscountreleasestack (&ctnodes, &totalbytes))
383 return (false);
384
385 if (keyboardescape ())
386 return (false);
387
388 (**hs).ctreleasenodes = ctnodes; /*copy returned values*/
389
390 (**hs).ctreleasebytes = totalbytes; /*copy returned values*/
391
392 (**hs).flstatscomputed = true; // something has been computed
393
394 (**hs).ctavail = -1; // not yet calced
395
396 statsupdate ();
397
398 nomad = (**databasedata).availlist;
399
400 ctnodes = 0;
401
402 totalbytes = 0;
403
404 largestblock = 0;
405
406 while (nomad != nildbaddress) {
407
408 if (!dbreadavailnode (nomad, &flfree, &ctbytes, &nextnomad)) {
409
410 setstatsmessage (idreadavailnodefailed);
411
412 return (false);
413 }
414
415 if ((*havailshadow) [ctnodes].adr != nomad)
416 setstatsmessage (idavailshadowoutofsynch);
417
418 if ((*havailshadow) [ctnodes].size != ctbytes)
419 setstatsmessage (idavailshadowoutofsynch);
420
421 ctnodes++;
422
423 totalbytes += ctbytes;
424
425 nomad = nextnomad;
426
427 rollbeachball ();
428
429 if (ctbytes > largestblock)
430 largestblock = ctbytes;
431 } /*while*/
432
433 (**hs).ctavail = ctnodes; /*copy returned values*/
434
435 (**hs).cttotalbytes = totalbytes;
436
437 (**hs).ctlargestblock = largestblock;
438
439 statsupdate ();
440
441 if (!dbgeteof (&eof)) {
442
443 setstatsmessage (idgeteoffailed);
444
445 return (false);
446 }
447
448 ctfree = 0; /*initialize loop variables*/
449
450 ctinuse = 0;
451
452 sizefree = 0;
453
454 sizeinuse = 0;
455
456 ctincon = 0;
457
458 (**hs).seqctfree = 0; /*initialize returned values*/
459
460 (**hs).seqctinuse = 0;
461
462 (**hs).seqsizefree = 0;
463
464 (**hs).seqsizeinuse = 0;
465
466 (**hs).ctinconsistencies = 0;
467
468 (**hs).logctinuse = 0;
469
470 (**hs).logsizeinuse = 0;
471
472 nomad = firstphysicaladdress; /*point at first physical record in the database*/
473
474 initbeachball (left); /*reverse direction*/
475
476 while (nomad < eof) { /*scan the database sequentially*/
477
478 if (!dbreadheader (nomad, &flfree, &ctbytes, &variance)) {
479
480 setstatsmessage (idreadheaderfailed1);
481
482 return (false);
483 }
484
485 if (flfree) {
486
487 ctfree++;
488
489 sizefree += ctbytes;
490 }
491 else {
492 ctinuse++;
493
494 sizeinuse += ctbytes;
495 }
496
497 nomad += sizeheader + ctbytes; /*point at the trailer*/
498
499 if (!dbreadtrailer (nomad, &fl2, &ct2)) {
500
501 setstatsmessage (idreadtrailerfailed2);
502
503 return (false);
504 }
505
506 if ((fl2 != flfree) || (ct2 != ctbytes)) {
507
508 setstatsmessage (idheadertrailerdisagree);
509
510 ctincon++;
511 }
512
513 rollbeachball ();
514
515 nomad += sizetrailer; /*advance to next sequential record*/
516 } /*while*/
517
518 /*finished the sequential scan*/
519
520 (**hs).seqctfree = ctfree; /*copy returned values*/
521
522 (**hs).seqctinuse = ctinuse;
523
524 (**hs).seqsizefree = sizefree;
525
526 (**hs).seqsizeinuse = sizeinuse;
527
528 (**hs).ctinconsistencies = ctincon;
529
530 statsupdate ();
531
532 /*calculate logical block usage*/
533
534 if (!flincludeusedblocks)
535 return (true);
536
537 #ifdef SMART_DB_OPENING
538 statsblockinuse ((**databasedata).u.extensions.availlistblock, nil);
539 #endif
540
541 shellpushrootglobals (statswindow);
542
543 initbeachball (right); /*reverse direction again*/
544
545 (*shellglobals.findusedblocksroutine) (); /*traverses all database structures*/
546
547 shellpopglobals ();
548
549 return (true);
550 } /*statscompute*/
551
552
553 static boolean statsdispose (void) {
554
555 disposehandle ((Handle) statsdata);
556
557 return (true);
558 } /*statsdispose*/
559
560
561 static boolean statsmousedown (Point pt, tyclickflags flags) {
562
563 /*
564 smashrect ((**statswindowinfo).contentrect);
565
566 statscompute ();
567 */
568
569 return (true);
570
571 } /*statsmousedown*/
572
573
574 boolean statsstart (void) {
575
576 /*
577 set up callback routines record, and link our data into the shell's
578 data structure.
579 */
580
581 ptrcallbacks statscallbacks;
582 register ptrcallbacks cb;
583
584 shellnewcallbacks (&statscallbacks);
585
586 cb = statscallbacks; /*copy into register*/
587
588 loadconfigresource (idstatsconfig, &(*cb).config);
589
590 (*cb).configresnum = idstatsconfig;
591
592 (*cb).windowholder = &statswindow;
593
594 (*cb).dataholder = (Handle *) &statsdata;
595
596 (*cb).infoholder = &statswindowinfo;
597
598 (*cb).updateroutine = &statsupdate;
599
600 (*cb).disposerecordroutine = &statsdispose;
601
602 (*cb).mouseroutine = &statsmousedown;
603
604 return (true);
605 } /*statsstart*/
606
607
608 static boolean statsfindwindow (void) {
609
610 register boolean fl;
611
612 fl = shellfindwindow (
613
614 idstatsconfig, &statswindow, &statswindowinfo,
615
616 (Handle *) &statsdata);
617
618 return (fl);
619 } /*statsfindwindow*/
620
621
622 static boolean statsnewwindow (void) {
623
624 WindowPtr w;
625 hdlwindowinfo hw;
626 bigstring bstitle;
627 Rect rzoom, rwindow;
628 hdlwindowinfo hparent;
629 Handle hdata;
630
631 if (!shellgetfrontrootinfo (&hparent)) /*our parent is the frontmost root window*/
632 return (false);
633
634 shellgetwindowcenter (hparent, &rzoom);
635
636 if (!newclearhandle (sizeof (tystatsrecord), &hdata))
637 return (false);
638
639 rwindow.top = -1; /*accept default*/
640
641 getstatsstring (idwindowtitle, bstitle);
642
643 if (!newchildwindow (idstatsconfig, hparent, &rwindow, &rzoom, bstitle, &w)) {
644
645 disposehandle ((Handle) hdata);
646
647 return (false);
648 }
649
650 getwindowinfo (w, &hw);
651
652 (**hw).hdata = hdata;
653
654 /*ccnewsubwindow (messagewindowinfo, ixmsginfo);*/
655
656 // shellpushglobals (statswindow);
657
658 #if TARGET_API_MAC_CARBON == 1
659
660 SetThemeWindowBackground (w, kThemeBrushModelessDialogBackgroundActive, false);
661
662 #endif
663
664 windowzoom (w);
665
666 // shellpopglobals ();
667
668 statswindow = w;
669
670 return (true);
671 } /*statsnewwindow*/
672
673
674 boolean dbstatsmessage (hdldatabaserecord hdb, boolean flincludeusedblocks) {
675
676 if (!statsfindwindow ()) {
677
678 if (!statsnewwindow ()) /*sets dbstats.c globals if it worked*/
679 return (false);
680 }
681
682 if (optionkeydown ())
683 windowbringtofront (statswindow);
684
685 shellpushglobals (statswindow);
686
687 smashrect ((**statswindowinfo).contentrect);
688
689 if (hdb != nil)
690 dbpushdatabase (hdb);
691
692 statscompute (flincludeusedblocks);
693
694 if (hdb != nil)
695 dbpopdatabase ();
696
697 shellpopglobals ();
698
699 return (true);
700 } /*dbstatsmessage*/
701
702
703
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more
information.