1 32 33 package websphinx.workbench; 34 35 import websphinx.*; 36 import java.awt.*; 37 import java.text.NumberFormat ; 39 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 { 46 47 Crawler crawler; 48 Thread thread; 49 boolean running = false; 50 51 static final int PAGES_PER_SEC_DECIMAL_PLACES = 1; 52 static final NumberFormat fmtPagesPerSec = NumberFormat.getInstance (); 54 static { 55 fmtPagesPerSec.setMinimumFractionDigits (PAGES_PER_SEC_DECIMAL_PLACES); 56 fmtPagesPerSec.setMaximumFractionDigits (PAGES_PER_SEC_DECIMAL_PLACES); 57 } 58 60 String runningTime; 61 String activeThreads; 62 String linksTested; 63 String pagesVisited; 64 String pagesPerSec; 65 String pagesLeft; 66 String memoryUsed; 67 String 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 (); } 81 82 83 Image offscreen; Dimension offSize; Graphics offg; FontMetrics fm; 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 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 caption, String 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 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 caption, String 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 offg.setColor (getBackground ()); 208 offg.fillRect (0, 0, offSize.width, offSize.height); 209 210 offg.setColor (getForeground ()); 212 drawFields (offg); 213 214 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 235 public synchronized void clear () { 236 msecTotal = 0; 237 timeLastUpdate = -1; 238 update (); 239 } 240 241 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 Graphics g = getGraphics (); 287 if (g != null) 288 update (g); 289 } 290 291 static String 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 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 formatPagesPerSec (double x) { 309 String result; 310 311 result = fmtPagesPerSec.format (x); 313 315 326 327 return result; 328 } 329 330 335 public synchronized void start () { 336 running = true; 337 thread = new Thread (this, "Statistics"); 338 thread.setDaemon (true); 339 thread.setPriority (Thread.MIN_PRIORITY); 340 thread.start (); 341 } 342 343 348 public synchronized void stop () { 349 running = false; 350 thread = null; 351 timeLastUpdate = -1; 352 } 353 354 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 e) {} 367 } 368 } 369 370 373 public void started (CrawlEvent event) { 374 crawler = event.getCrawler (); 375 start (); 376 } 377 378 381 public synchronized void stopped (CrawlEvent event) { 382 if (running) 383 stop (); 384 } 385 386 389 public void cleared (CrawlEvent event) { 390 clear (); 391 } 392 393 396 public void timedOut (CrawlEvent event) { 397 stop (); 398 } 399 400 403 public void paused (CrawlEvent event) { 404 stop (); 405 } 406 407 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 |