KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > websphinx > workbench > Statistics


1 /*
2  * WebSphinx web-crawling toolkit
3  *
4  * Copyright (c) 1998-2002 Carnegie Mellon University. All rights
5  * reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
11  * 1. Redistributions of source code must retain the above copyright
12  * notice, this list of conditions and the following disclaimer.
13  *
14  * 2. Redistributions in binary form must reproduce the above copyright
15  * notice, this list of conditions and the following disclaimer in
16  * the documentation and/or other materials provided with the
17  * distribution.
18  *
19  * THIS SOFTWARE IS PROVIDED BY CARNEGIE MELLON UNIVERSITY ``AS IS'' AND
20  * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY
23  * NOR ITS EMPLOYEES BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30  *
31  */

32
33 package websphinx.workbench;
34
35 import websphinx.*;
36 import java.awt.*;
37 //#ifdef JDK1.1
38
import java.text.NumberFormat JavaDoc;
39 //#endif JDK1.1
40
import rcm.awt.Constrain;
41 import rcm.util.Mem;
42 import rcm.awt.ClosableFrame;
43 import rcm.awt.BorderPanel;
44
45 public class Statistics extends Panel implements CrawlListener, Runnable JavaDoc {
46
47     Crawler crawler;
48     Thread JavaDoc thread;
49     boolean running = false;
50
51     static final int PAGES_PER_SEC_DECIMAL_PLACES = 1;
52 //#ifdef JDK1.1
53
static final NumberFormat JavaDoc fmtPagesPerSec = NumberFormat.getInstance ();
54     static {
55         fmtPagesPerSec.setMinimumFractionDigits (PAGES_PER_SEC_DECIMAL_PLACES);
56         fmtPagesPerSec.setMaximumFractionDigits (PAGES_PER_SEC_DECIMAL_PLACES);
57     }
58 //#endif JDK1.1
59

60     String JavaDoc runningTime;
61     String JavaDoc activeThreads;
62     String JavaDoc linksTested;
63     String JavaDoc pagesVisited;
64     String JavaDoc pagesPerSec;
65     String JavaDoc pagesLeft;
66     String JavaDoc memoryUsed;
67     String JavaDoc memoryMaxUsed;
68
69     Button refreshButton;
70
71     long msecTotal;
72     long timeLastUpdate = -1;
73     long kbMaxUsed;
74
75     public Statistics () {
76         setLayout (null);
77         add (refreshButton = new Button ("Refresh"));
78         update ();
79         measureFields (); // to initialize minSize
80
}
81
82
83     Image offscreen; // offscreen drawing area
84
Dimension offSize; // size of offscreen buffer
85
Graphics offg; // drawonable associated with offscreen buffer
86
FontMetrics fm; // font metrics for offscreen buffer
87

88     Dimension minSize = new Dimension ();
89     
90     public synchronized void layout () {
91         Dimension d = refreshButton.preferredSize();
92         int x = 0;
93         int y = minSize.height;
94         int w = d.width;
95         int h = d.height;
96         refreshButton.reshape (x, y, w, h);
97     }
98
99     public Dimension minimumSize () {
100         Dimension d = new Dimension (minSize);
101         d.height += refreshButton.preferredSize().height;
102         return d;
103     }
104
105     public Dimension preferredSize () {
106         return minimumSize ();
107     }
108
109     public synchronized void update (Graphics g) {
110         // don't clear window with background color first
111
paint (g);
112     }
113
114     void createOffscreenArea (Dimension d) {
115         offSize = new Dimension (d.width > 0 ? d.width : 1,
116                                  d.height > 0 ? d.height : 1);
117         offscreen = createImage (offSize.width, offSize.height);
118         offg = offscreen.getGraphics ();
119         offg.setFont (getFont ());
120         fm = offg.getFontMetrics ();
121     }
122
123     final static int GUTTER = 5;
124
125     int drawField (Graphics g, int y, String JavaDoc caption, String JavaDoc value) {
126         int cW = fm.stringWidth (caption);
127         int vW = fm.stringWidth (value);
128         minSize.width = Math.max (minSize.width, cW + vW + 10);
129
130         y += fm.getAscent ();
131         g.drawString (caption, 0, y);
132         g.drawString (value, offSize.width - fm.stringWidth (value), y);
133         return fm.getHeight ();
134     }
135
136     void drawFields (Graphics g) {
137         int y = 0;
138         int gutter = GUTTER;
139         //+ Math.max (0, offSize.height - minSize.height) / 8;
140

141         y += gutter;
142         y += drawField (offg, y, "Running time:", runningTime);
143         y += drawField (offg, y, "Active threads:", activeThreads);
144         y += gutter*2;
145         y += drawField (offg, y, "Links tested:", linksTested);
146         y += drawField (offg, y, "Links in queue:", pagesLeft);
147         y += gutter*2;
148         y += drawField (offg, y, "Pages visited:", pagesVisited);
149         y += drawField (offg, y, "Pages/sec:", pagesPerSec);
150         y += gutter*2;
151         y += drawField (offg, y, "Memory in use:", memoryUsed);
152         y += drawField (offg, y, "Max memory used:", memoryMaxUsed);
153         y += gutter;
154
155         minSize.height = y;
156     }
157
158     int measureField (FontMetrics fm, String JavaDoc caption, String JavaDoc value) {
159         int cW = fm.stringWidth (caption);
160         int vW = fm.stringWidth ("00000000");
161         minSize.width = Math.max (minSize.width, cW + vW + 10);
162         return fm.getHeight ();
163     }
164
165     void measureFields () {
166         Font font = getFont ();
167         if (font == null)
168             font = new Font ("Helvetica", Font.PLAIN, 12);
169         FontMetrics fm = Toolkit.getDefaultToolkit().getFontMetrics (font);
170         minSize = new Dimension ();
171
172         int y = 0;
173
174         y += GUTTER;
175         y += measureField (fm, "Running time:", runningTime);
176         y += measureField (fm, "Active threads:", activeThreads);
177         y += GUTTER*2;
178         y += measureField (fm, "Links tested:", linksTested);
179         y += measureField (fm, "Links in queue:", pagesLeft);
180         y += GUTTER*2;
181         y += measureField (fm, "Pages visited:", pagesVisited);
182         y += measureField (fm, "Pages/sec:", pagesPerSec);
183         y += GUTTER*2;
184         y += measureField (fm, "Memory in use:", memoryUsed);
185         y += measureField (fm, "Max memory used:", memoryMaxUsed);
186         y += GUTTER;
187
188         minSize.height = y;
189     }
190
191     Dimension cached;
192
193     public synchronized void paint (Graphics g) {
194         Dimension d = size ();
195         if (cached == null
196             || d.width != cached.width
197             || d.height != cached.height) {
198             g.setColor (getBackground ());
199             g.fillRect (0, 0, d.width, d.height);
200             cached = d;
201         }
202
203         if (offscreen == null)
204             createOffscreenArea (minSize);
205
206         // erase background
207
offg.setColor (getBackground ());
208         offg.fillRect (0, 0, offSize.width, offSize.height);
209         
210         // draw statistics
211
offg.setColor (getForeground ());
212         drawFields (offg);
213             
214         // copy to screen
215
g.drawImage (offscreen, 0, 0, null);
216     }
217
218     public boolean handleEvent (Event event) {
219         if (event.target == refreshButton && event.id == Event.ACTION_EVENT) {
220             Mem.gc ();
221             update ();
222         }
223         else
224             return super.handleEvent (event);
225         return true;
226     }
227             
228
229     /**
230      * Reset statistics (primarily the running time, since all other
231      * statistics are computed directly from the crawler's state).
232      * If listening to a crawler, this method is called automatically
233      * when the crawler is cleared.
234      */

235     public synchronized void clear () {
236         msecTotal = 0;
237         timeLastUpdate = -1;
238         update ();
239     }
240
241     /**
242      * Compute the latest statistics. Called automatically by
243      * a background thread when the crawler is running.
244      */

245     public synchronized void update () {
246         long now = System.currentTimeMillis ();
247         if (running) {
248             if (timeLastUpdate != -1)
249                 msecTotal += (now - timeLastUpdate);
250             timeLastUpdate = now;
251         }
252
253         int pV, lT, pL, nThreads;
254
255         if (crawler != null) {
256             lT = crawler.getLinksTested ();
257             pV = crawler.getPagesVisited ();
258             pL = crawler.getPagesLeft ();
259             nThreads = crawler.getActiveThreads ();
260         }
261         else {
262             lT = 0;
263             pV = 0;
264             pL = 0;
265             nThreads = 0;
266         }
267
268         long kbUsed = Mem.used () / 1024;
269         kbMaxUsed = Math.max (kbMaxUsed, kbUsed);
270
271         double pps = msecTotal > 0
272             ? (double)pV * 1000 / msecTotal
273             : 0.0;
274             
275             
276         runningTime = formatTime (msecTotal);
277         activeThreads = String.valueOf (nThreads);
278         linksTested = String.valueOf (lT);
279         pagesVisited = String.valueOf (pV);
280         pagesLeft = String.valueOf (pL);
281         pagesPerSec = formatPagesPerSec (pps);
282         memoryUsed = kbUsed + " KB";
283         memoryMaxUsed = kbMaxUsed + " KB";
284
285         // paint the window NOW
286
Graphics g = getGraphics ();
287         if (g != null)
288             update (g);
289     }
290
291     static String JavaDoc formatTime (long time) {
292         int h, m, s, d;
293         s = (int) (time/1000);
294         m = s / 60; s %= 60;
295         h = m / 60; m %= 60;
296         d = h / 24; h %= 24;
297         return formatTime (d, h, m, s);
298     }
299
300     static String JavaDoc formatTime (int d, int h, int m, int s) {
301         return
302             (d > 0 ? d + "d " : "")
303             + (h < 10 ? "0" : "") + h
304             + ":" + (m < 10 ? "0" : "") + m
305             + ":" + (s < 10 ? "0" : "") + s;
306     }
307     
308     static String JavaDoc formatPagesPerSec (double x) {
309         String JavaDoc result;
310
311 //#ifdef JDK1.1
312
result = fmtPagesPerSec.format (x);
313 //#endif JDK1.1
314

315 /*#ifdef JDK1.0
316         int places = PAGES_PER_SEC_DECIMAL_PLACES;
317         result = (int)x + ".";
318         if ((int)x == 0 && x < 0)
319             result = "-" + result;
320         x = Math.abs(x);
321         while (places-- > 0) {
322             x = (x - (int)x)*10;
323             result += (int)x;
324         }
325 #endif JDK1.0*/

326
327         return result;
328     }
329
330     /**
331      * Start the background thread to update the display. If listening
332      * to a crawler, this method is called automatically when the
333      * crawler starts.
334      */

335     public synchronized void start () {
336         running = true;
337         thread = new Thread JavaDoc (this, "Statistics");
338         thread.setDaemon (true);
339         thread.setPriority (Thread.MIN_PRIORITY);
340         thread.start ();
341     }
342
343     /**
344      * Stop the background thread that updates the display. If listening
345      * to a crawler, this method is called automatically when the
346      * crawler stops.
347      */

348     public synchronized void stop () {
349         running = false;
350         thread = null;
351         timeLastUpdate = -1;
352     }
353
354     /**
355      * Background thread. Clients shouldn't call this.
356      */

357     public void run () {
358         while (true) {
359             update ();
360
361             if (!running)
362                 break;
363
364             try {
365                 Thread.sleep (500);
366             } catch (InterruptedException JavaDoc e) {}
367         }
368     }
369
370     /**
371      * Notify that the crawler started.
372      */

373     public void started (CrawlEvent event) {
374         crawler = event.getCrawler ();
375         start ();
376     }
377
378     /**
379      * Notify that the crawler ran out of links to crawl
380      */

381     public synchronized void stopped (CrawlEvent event) {
382         if (running)
383             stop ();
384     }
385
386     /**
387      * Notify that the crawler's state was cleared.
388      */

389     public void cleared (CrawlEvent event) {
390         clear ();
391     }
392
393     /**
394      * Notify that the crawler timed out.
395      */

396     public void timedOut (CrawlEvent event) {
397         stop ();
398     }
399
400     /**
401      * Notify that the crawler is paused.
402      */

403     public void paused (CrawlEvent event) {
404         stop ();
405     }
406
407     /**
408      * Create a new Frame containing a Statistics panel connected to a crawler.
409      */

410     public static Frame monitor (Crawler crawler) {
411         Frame win = new ClosableFrame ("Statistics: " + crawler.getName ());
412
413         Statistics stats = new Statistics ();
414         crawler.addCrawlListener (stats);
415
416         win.add ("Center", BorderPanel.wrap (stats, 5, 5, 5, 5));
417         win.pack ();
418         win.show ();
419
420         return win;
421     }
422
423 }
424
Popular Tags