This project has retired. For details please refer to its
Attic page.
Heatmap xref
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.hadoop.chukwa.analysis.salsa.visualization;
20
21
22 import prefuse.data.*;
23 import prefuse.action.*;
24 import prefuse.action.layout.*;
25 import prefuse.action.assignment.*;
26 import prefuse.visual.*;
27 import prefuse.render.*;
28 import prefuse.util.*;
29 import prefuse.*;
30
31 import org.apache.hadoop.chukwa.hicc.OfflineTimeHandler;
32 import org.apache.hadoop.chukwa.hicc.TimeHandler;
33 import org.apache.hadoop.chukwa.util.DatabaseWriter;
34 import org.apache.hadoop.chukwa.database.Macro;
35 import org.apache.hadoop.chukwa.util.XssFilter;
36
37 import javax.servlet.http.*;
38
39 import org.apache.commons.logging.Log;
40 import org.apache.commons.logging.LogFactory;
41
42 import java.sql.*;
43 import java.util.*;
44
45 import java.awt.Font;
46 import java.awt.geom.Rectangle2D;
47 import java.awt.Color;
48
49
50
51
52
53
54
55
56 public class Heatmap {
57
58
59
60
61
62 protected static class HeatmapData {
63 public Table agg_tab;
64 public long [][] stats;
65 public long min;
66 public long max;
67 public int num_hosts;
68 public String [] hostnames;
69 public HeatmapData() {
70 }
71 }
72
73 private static Log log = LogFactory.getLog(Heatmap.class);
74
75 static final String START_FIELD_NAME = "start_time_num";
76 static final String END_FIELD_NAME = "finish_time_num";
77
78 int BOXWIDTH = 250;
79 int SIZE_X = 1600, SIZE_Y=1600;
80 final int [] BORDER = {200,150,150,150};
81 final int LEGEND_X_OFFSET = 10;
82 final int LEGEND_Y_OFFSET = 0;
83 final int LEGEND_TEXT_OFFSET = 10;
84 final int LEGEND_FONT_SIZE = 24;
85 final int AXIS_NAME_FONT_SIZE = 24;
86
87 protected boolean offline_use = true;
88 protected HttpServletRequest request;
89
90
91
92
93 protected HashMap<String, String> param_map;
94
95 protected String cluster;
96 protected String timezone;
97 protected String query_state;
98 protected String query_stat_type;
99 protected final String table = new String("filesystem_fsm");
100 protected boolean plot_legend = false;
101 protected boolean sort_nodes = true;
102 protected boolean plot_additional_info = true;
103 protected String add_info_extra = null;
104
105 protected Display dis;
106 protected Visualization viz;
107
108 protected Rectangle2D dataBound = new Rectangle2D.Double();
109 protected Rectangle2D xlabBound = new Rectangle2D.Double();
110 protected Rectangle2D ylabBound = new Rectangle2D.Double();
111 protected Rectangle2D labelBottomBound = new Rectangle2D.Double();
112
113 protected HashMap<String, String> prettyStateNames;
114
115
116 final String maingroup = "Data";
117 final String othergroup = "Misc";
118 final String labelgroup = "Label";
119 final String legendgroup = "Legend";
120 final String legendshapegroup = "LegendShape";
121 final String addinfogroup = "AddInfo";
122 final String addinfoshapegroup = "AddInfoShape";
123
124 public Heatmap() {
125 this.cluster = new String("");
126 this.timezone = new String("");
127 this.query_state = new String("");
128 this.query_stat_type = new String("");
129 param_map = new HashMap<String, String>();
130 }
131
132
133
134
135
136
137
138
139 public Heatmap
140 (String timezone, String cluster, String event_type,
141 String query_stat_type,
142 HashMap<String, String> valmap)
143 {
144 this.cluster = new String(cluster);
145 if (timezone != null) {
146 this.timezone = new String(timezone);
147 } else {
148 this.timezone = null;
149 }
150 this.query_state = new String(event_type);
151 this.query_stat_type = new String(query_stat_type);
152
153
154
155
156 this.param_map = valmap;
157 }
158
159 public Heatmap
160 (String timezone, String cluster, String query_state,
161 String query_stat_type,
162 HashMap<String, String> valmap, String shuffles)
163 {
164
165 this.cluster = new String(cluster);
166 if (timezone != null) {
167 this.timezone = new String(timezone);
168 } else {
169 this.timezone = null;
170 }
171 this.query_state = new String(query_state);
172 this.query_stat_type = new String(query_stat_type);
173
174
175
176
177 this.param_map = valmap;
178
179 }
180
181 public Heatmap
182 (String timezone, String cluster, String query_state,
183 String query_stat_type,
184 HashMap<String, String> valmap,
185 int w, int h)
186 {
187
188 this.cluster = new String(cluster);
189 if (timezone != null) {
190 this.timezone = new String(timezone);
191 } else {
192 this.timezone = null;
193 }
194 this.query_state = new String(query_state);
195 this.query_stat_type = new String(query_stat_type);
196
197
198
199
200 this.param_map = valmap;
201
202 this.SIZE_X = w;
203 this.SIZE_Y = h;
204 }
205
206 public Heatmap(HttpServletRequest request) {
207 XssFilter xf = new XssFilter(request);
208 this.offline_use = false;
209 this.request = request;
210 HttpSession session = request.getSession();
211 this.cluster = session.getAttribute("cluster").toString();
212 String query_state = xf.getParameter("query_state");
213 if (query_state != null) {
214 this.query_state = new String(query_state);
215 } else {
216 this.query_state = new String("read");
217 }
218 String query_stat_type = xf.getParameter("query_stat_type");
219 if (query_stat_type != null) {
220 this.query_stat_type = new String(query_stat_type);
221 } else {
222 this.query_stat_type = new String("transaction_count");
223 }
224 this.timezone = session.getAttribute("time_zone").toString();
225 }
226
227
228
229
230
231 public void setDimensions(int width, int height) {
232 this.SIZE_X=width;
233 this.SIZE_Y=height;
234 }
235
236
237
238
239
240 public void setLegend(boolean legendopt) {
241 if (legendopt) {
242 this.plot_legend = true;
243 } else {
244 this.plot_legend = false;
245 }
246 }
247
248
249
250
251
252
253 public boolean getImage(java.io.OutputStream output, String img_fmt, double scale) {
254 dis = new Display(this.viz);
255 dis.setSize(SIZE_X,SIZE_Y);
256 dis.setHighQuality(true);
257 dis.setFont(new Font(Font.SANS_SERIF,Font.PLAIN,24));
258 return dis.saveImage(output, img_fmt, scale);
259 }
260
261 protected void setupRenderer() {
262 this.viz.setRendererFactory(new RendererFactory(){
263 AbstractShapeRenderer sr = new ShapeRenderer();
264 ShapeRenderer sr_big = new ShapeRenderer(BOXWIDTH);
265 Renderer arY = new AxisRenderer(Constants.LEFT, Constants.TOP);
266 Renderer arX = new AxisRenderer(Constants.CENTER, Constants.BOTTOM);
267 PolygonRenderer pr = new PolygonRenderer(Constants.POLY_TYPE_LINE);
268 LabelRenderer lr = new LabelRenderer("label");
269 LabelRenderer lr_legend = new LabelRenderer("label");
270
271 public Renderer getRenderer(VisualItem item) {
272 lr_legend.setHorizontalAlignment(Constants.LEFT);
273 lr_legend.setVerticalAlignment(Constants.CENTER);
274 lr.setHorizontalAlignment(Constants.CENTER);
275 lr.setVerticalAlignment(Constants.CENTER);
276 if (item.isInGroup(maingroup)) {
277 return sr_big;
278 } else if (item.isInGroup(legendgroup)) {
279 return lr_legend;
280 } else if (item.isInGroup(addinfogroup)) {
281 return lr;
282 }
283 return sr;
284 }
285 });
286 }
287
288
289 protected HeatmapData setupDataTable() {
290 HeatmapData hd = this.getData();
291 return hd;
292 }
293
294 protected void setupHeatmap(VisualTable vtab, HeatmapData hd)
295 {
296 long [][] stats = hd.stats;
297 int i, j, curr_idx;
298 long curr_val;
299 int num_hosts = hd.num_hosts;
300 ColorMap cm = new ColorMap(
301 ColorLib.getInterpolatedPalette(
302 ColorLib.color(ColorLib.getColor(32,0,0)),
303 ColorLib.color(Color.WHITE)
304 ),
305 (double)hd.min,(double)hd.max
306 );
307
308 for (i = 0; i < num_hosts; i++) {
309 for (j = 0; j < num_hosts; j++) {
310 curr_idx = j+(i*num_hosts);
311 curr_val = stats[i][j];
312 if (curr_val >= hd.min) {
313 vtab.setFillColor(curr_idx, cm.getColor((double)curr_val));
314 } else if (curr_val == 0) {
315 vtab.setFillColor(curr_idx, ColorLib.color(Color.BLACK));
316 }
317 }
318 }
319
320
321 GridLayout gl = new GridLayout(maingroup, num_hosts, num_hosts);
322 gl.setLayoutBounds(this.dataBound);
323 ActionList gl_list = new ActionList();
324 gl_list.add(gl);
325 this.viz.putAction("gridlayout",gl_list);
326 this.viz.run("gridlayout");
327 }
328
329 protected void addHostLabels(HeatmapData hd) {
330 Table legend_labels_table = new Table();
331 legend_labels_table.addColumn("label",String.class);
332 legend_labels_table.addRows(hd.hostnames.length);
333 for (int i = 0; i < hd.hostnames.length; i++) {
334 legend_labels_table.setString(i,"label",hd.hostnames[i]);
335 }
336 float start_x = LEGEND_X_OFFSET;
337 float start_y = LEGEND_Y_OFFSET + BORDER[1] + (BOXWIDTH/2);
338 float incr = this.BOXWIDTH;
339 VisualTable legend_labels_table_viz = this.viz.addTable(legendgroup, legend_labels_table);
340 for (int i = 0; i < hd.hostnames.length; i++) {
341 legend_labels_table_viz.setFloat(i, VisualItem.X, start_x + LEGEND_TEXT_OFFSET);
342 legend_labels_table_viz.setFloat(i, VisualItem.Y, start_y + (i * incr));
343 legend_labels_table_viz.setTextColor(i,ColorLib.color(java.awt.Color.BLACK));
344 legend_labels_table_viz.setFont(i,new Font(Font.SANS_SERIF,Font.PLAIN,LEGEND_FONT_SIZE));
345 }
346 }
347
348 protected void addAddlInfo(HeatmapData hd) {
349 Table legend_labels_table = new Table();
350 legend_labels_table.addColumn("label",String.class);
351 legend_labels_table.addRows(3);
352
353 String hostnumstring = "Number of hosts: " + hd.num_hosts;
354 if (sort_nodes) {
355 hostnumstring += " (nodes sorted)";
356 } else {
357 hostnumstring += " (nodes not sorted)";
358 }
359 if (add_info_extra != null) hostnumstring += add_info_extra;
360 legend_labels_table.setString(0,"label",hostnumstring);
361 legend_labels_table.setString(1,"label","Src. Hosts");
362 legend_labels_table.setString(2,"label","Dest. Hosts");
363
364 VisualTable legend_labels_table_viz = this.viz.addTable(addinfogroup, legend_labels_table);
365
366 legend_labels_table_viz.setFloat(0, VisualItem.X, this.SIZE_X/2);
367 legend_labels_table_viz.setFloat(0, VisualItem.Y, BORDER[1]/2);
368 legend_labels_table_viz.setTextColor(0,ColorLib.color(java.awt.Color.BLACK));
369 legend_labels_table_viz.setFont(0,new Font(Font.SANS_SERIF,Font.PLAIN,LEGEND_FONT_SIZE));
370
371 legend_labels_table_viz.setFloat(1, VisualItem.X, this.SIZE_X/2);
372 legend_labels_table_viz.setFloat(1, VisualItem.Y, BORDER[1] + (BOXWIDTH*hd.num_hosts) + BORDER[3]/2);
373 legend_labels_table_viz.setTextColor(1,ColorLib.color(java.awt.Color.BLACK));
374 legend_labels_table_viz.setFont(1,new Font(Font.SANS_SERIF,Font.PLAIN,LEGEND_FONT_SIZE));
375
376 legend_labels_table_viz.setFloat(2, VisualItem.X, BORDER[0] + (BOXWIDTH*hd.num_hosts) + BORDER[2]/2);
377 legend_labels_table_viz.setFloat(2, VisualItem.Y, this.SIZE_Y/2);
378 legend_labels_table_viz.setTextColor(2,ColorLib.color(java.awt.Color.BLACK));
379 legend_labels_table_viz.setFont(2,new Font(Font.SANS_SERIF,Font.PLAIN,LEGEND_FONT_SIZE));
380
381 }
382
383 protected void initPrettyNames() {
384 this.prettyStateNames = new HashMap<String, String>();
385
386 prettyStateNames.put("read","Block Reads");
387 prettyStateNames.put("write","Block Writes");
388 prettyStateNames.put("read_local", "Local Block Reads");
389 prettyStateNames.put("write_local", "Local Block Writes");
390 prettyStateNames.put("read_remote", "Remote Block Reads");
391 prettyStateNames.put("write_remote", "Remote Block Writes");
392 prettyStateNames.put("write_replicated", "Replicated Block Writes");
393 }
394
395
396
397
398 public void run() {
399 initPrettyNames();
400
401
402 this.viz = new Visualization();
403
404
405 HeatmapData hd = this.setupDataTable();
406
407
408 int width;
409 if (SIZE_X-BORDER[0]-BORDER[2] < SIZE_Y-BORDER[1]-BORDER[3]) {
410 BOXWIDTH = (SIZE_X-BORDER[0]-BORDER[2]) / hd.num_hosts;
411 } else {
412 BOXWIDTH = (SIZE_Y-BORDER[1]-BORDER[3]) / hd.num_hosts;
413 }
414 width = hd.num_hosts * BOXWIDTH;
415 this.dataBound.setRect(
416 BORDER[0]+BOXWIDTH/2,
417 BORDER[1]+BOXWIDTH/2,
418 width-BOXWIDTH,width-BOXWIDTH
419 );
420 this.SIZE_X = BORDER[0] + BORDER[2] + (hd.num_hosts * BOXWIDTH);
421 this.SIZE_Y = BORDER[1] + BORDER[3] + (hd.num_hosts * BOXWIDTH);
422
423 log.debug("width total: " + width + " width per state: " + BOXWIDTH + " xstart: "
424 + (BORDER[0]+BOXWIDTH/2)
425 + " ystart: " + (BORDER[1]+BOXWIDTH/2) + " (num hosts: "+hd.num_hosts+")");
426 log.debug("X size: " + this.SIZE_X + " Y size: " + this.SIZE_Y);
427
428 this.setupRenderer();
429 VisualTable data_tab_viz = viz.addTable(maingroup, hd.agg_tab);
430 setupHeatmap(data_tab_viz, hd);
431
432 ShapeAction legend_sa1 = null, legend_sa2 = null;
433 SpecifiedLayout legendlabels_sl1 = null, legendlabels_sl2 = null;
434
435 if (plot_legend) {
436 addHostLabels(hd);
437 legend_sa1 = new ShapeAction(legendshapegroup);
438 legendlabels_sl1 = new SpecifiedLayout(legendgroup, VisualItem.X, VisualItem.Y);
439 ActionList legenddraw = new ActionList();
440 legenddraw.add(legend_sa1);
441 this.viz.putAction(legendshapegroup, legenddraw);
442 ActionList legendlabelsdraw = new ActionList();
443 legendlabelsdraw.add(legendlabels_sl1);
444 this.viz.putAction(legendgroup,legendlabelsdraw);
445 }
446
447 if (plot_additional_info) {
448 addAddlInfo(hd);
449 legend_sa2 = new ShapeAction(addinfoshapegroup);
450 legendlabels_sl2 = new SpecifiedLayout(addinfogroup, VisualItem.X, VisualItem.Y);
451 ActionList legenddraw = new ActionList();
452 legenddraw.add(legend_sa2);
453 this.viz.putAction(addinfoshapegroup, legenddraw);
454 ActionList legendlabelsdraw = new ActionList();
455 legendlabelsdraw.add(legendlabels_sl2);
456 this.viz.putAction(addinfogroup,legendlabelsdraw);
457 }
458
459 }
460
461 protected boolean checkDone(int [] clustId) {
462 for (int i = 1; i < clustId.length; i++) {
463 if (clustId[i] != clustId[0]) return false;
464 }
465 return true;
466 }
467
468
469
470
471 protected int [] hClust (long [][] stat)
472 {
473 int statlen = stat.length;
474 long [] rowSums = new long[statlen];
475 int [] permute = new int[statlen];
476 int i,j;
477
478
479 for (i = 0; i < statlen; i++) {
480 permute[i] = i;
481 }
482
483 for (i = 0; i < statlen; i++) {
484 rowSums[i] = 0;
485 for (j = 0; j < statlen; j++) {
486 rowSums[i] += stat[i][j];
487 }
488 }
489
490
491 for (i = 0; i < statlen-1; i++) {
492 long val = rowSums[i];
493 int thispos = permute[i];
494 j = i-1;
495 while (j >= 0 && rowSums[j] > val) {
496 rowSums[j+1] = rowSums[j];
497 permute[j+1] = permute[j];
498 j--;
499 }
500 rowSums[j+1] = val;
501 permute[j+1] = thispos;
502 }
503
504 return permute;
505
506 }
507
508
509
510
511
512 protected long [][] doPermute (long [][] stat, int [] permute) {
513 int statlen = stat.length;
514 int i, j, curr_pos;
515 long [][] stat2 = new long[statlen][statlen];
516
517 assert(stat.length == permute.length);
518
519 for (i = 0; i < statlen; i++) {
520 curr_pos = permute[i];
521 for (j = 0; j < statlen; j++) {
522 stat2[i][j] = stat[curr_pos][permute[j]];
523 }
524 }
525
526 return stat2;
527 }
528
529
530
531
532
533 public HeatmapData getData() {
534
535 OfflineTimeHandler time_offline;
536 TimeHandler time_online;
537 long start, end, min, max;
538
539 if (offline_use) {
540 time_offline = new OfflineTimeHandler(param_map, this.timezone);
541 start = time_offline.getStartTime();
542 end = time_offline.getEndTime();
543 } else {
544 time_online = new TimeHandler(this.request, this.timezone);
545 start = time_online.getStartTime();
546 end = time_online.getEndTime();
547 }
548
549 DatabaseWriter dbw = new DatabaseWriter(this.cluster);
550
551
552 String query;
553 if (this.query_state != null && this.query_state.equals("read")) {
554 query = "select block_id,start_time,finish_time,start_time_millis,finish_time_millis,status,state_name,hostname,other_host,bytes from ["+table+"] where finish_time between '[start]' and '[end]' and (state_name like 'read_local' or state_name like 'read_remote')";
555 } else if (this.query_state != null && this.query_state.equals("write")) {
556 query = "select block_id,start_time,finish_time,start_time_millis,finish_time_millis,status,state_name,hostname,other_host,bytes from ["+table+"] where finish_time between '[start]' and '[end]' and (state_name like 'write_local' or state_name like 'write_remote' or state_name like 'write_replicated')";
557 } else {
558 query = "select block_id,start_time,finish_time,start_time_millis,finish_time_millis,status,state_name,hostname,other_host,bytes from ["+table+"] where finish_time between '[start]' and '[end]' and state_name like '" + query_state + "'";
559 }
560 Macro mp = new Macro(start,end,query);
561 query = mp.toString() + " order by start_time";
562
563 ArrayList<HashMap<String, Object>> events = new ArrayList<HashMap<String, Object>>();
564
565 ResultSet rs = null;
566
567 log.debug("Query: " + query);
568
569 try {
570 rs = dbw.query(query);
571 ResultSetMetaData rmeta = rs.getMetaData();
572 int col = rmeta.getColumnCount();
573 while (rs.next()) {
574 HashMap<String, Object> event = new HashMap<String, Object>();
575 for(int i=1;i<=col;i++) {
576 if(rmeta.getColumnType(i)==java.sql.Types.TIMESTAMP) {
577 event.put(rmeta.getColumnName(i),rs.getTimestamp(i).getTime());
578 } else {
579 event.put(rmeta.getColumnName(i),rs.getString(i));
580 }
581 }
582 events.add(event);
583 }
584 } catch (SQLException ex) {
585
586 log.error("SQLException: " + ex.getMessage());
587 log.error("SQLState: " + ex.getSQLState());
588 log.error("VendorError: " + ex.getErrorCode());
589 } finally {
590 dbw.close();
591 }
592
593 log.info(events.size() + " results returned.");
594
595 HashSet<String> host_set = new HashSet<String>();
596 HashMap<String, Integer> host_indices = new HashMap<String, Integer>();
597 HashMap<Integer, String> host_rev_indices = new HashMap<Integer, String>();
598
599
600 for(int i = 0; i < events.size(); i++) {
601 HashMap<String, Object> event = events.get(i);
602 String curr_host = (String) event.get("hostname");
603 String other_host = (String) event.get("other_host");
604 host_set.add(curr_host);
605 host_set.add(other_host);
606 }
607 int num_hosts = host_set.size();
608
609 Iterator<String> host_iter = host_set.iterator();
610 for (int i = 0; i < num_hosts && host_iter.hasNext(); i++) {
611 String curr_host = host_iter.next();
612 host_indices.put(curr_host, new Integer(i));
613 host_rev_indices.put(new Integer(i),curr_host);
614 }
615
616 System.out.println("Number of hosts: " + num_hosts);
617 long stats[][] = new long[num_hosts][num_hosts];
618 long count[][] = new long[num_hosts][num_hosts];
619
620 int start_millis = 0, end_millis = 0;
621
622
623
624
625
626 log.info("Query statistic type: "+this.query_stat_type);
627 if (this.query_stat_type.equals("transaction_count")) {
628 for(int i=0;i<events.size();i++) {
629 HashMap<String, Object> event = events.get(i);
630 start=(Long)event.get("start_time");
631 end=(Long)event.get("finish_time");
632 start_millis = Integer.parseInt(((String)event.get("start_time_millis")));
633 end_millis = Integer.parseInt(((String)event.get("finish_time_millis")));
634 String this_host = (String) event.get("hostname");
635 String other_host = (String) event.get("other_host");
636 int this_host_idx = host_indices.get(this_host).intValue();
637 int other_host_idx = host_indices.get(other_host).intValue();
638
639
640 stats[other_host_idx][this_host_idx] += 1;
641 }
642 } else if (this.query_stat_type.equals("avg_duration")) {
643 for(int i=0;i<events.size();i++) {
644 HashMap<String, Object> event = events.get(i);
645 start=(Long)event.get("start_time");
646 end=(Long)event.get("finish_time");
647 start_millis = Integer.parseInt(((String)event.get("start_time_millis")));
648 end_millis = Integer.parseInt(((String)event.get("finish_time_millis")));
649 String this_host = (String) event.get("hostname");
650 String other_host = (String) event.get("other_host");
651 int this_host_idx = host_indices.get(this_host).intValue();
652 int other_host_idx = host_indices.get(other_host).intValue();
653
654 long curr_val = end_millis - start_millis + ((end - start)*1000);
655
656
657 stats[other_host_idx][this_host_idx] += curr_val;
658 count[other_host_idx][this_host_idx] += 1;
659 }
660 for (int i = 0; i < num_hosts; i++) {
661 for (int j = 0; j < num_hosts; j++) {
662 if (count[i][j] > 0) stats[i][j] = stats[i][j] / count[i][j];
663 }
664 }
665 } else if (this.query_stat_type.equals("avg_volume")) {
666 for(int i=0;i<events.size();i++) {
667 HashMap<String, Object> event = events.get(i);
668 start=(Long)event.get("start_time");
669 end=(Long)event.get("finish_time");
670 start_millis = Integer.parseInt(((String)event.get("start_time_millis")));
671 end_millis = Integer.parseInt(((String)event.get("finish_time_millis")));
672 String this_host = (String) event.get("hostname");
673 String other_host = (String) event.get("other_host");
674 int this_host_idx = host_indices.get(this_host).intValue();
675 int other_host_idx = host_indices.get(other_host).intValue();
676
677 long curr_val = Long.parseLong((String)event.get("bytes"));
678
679
680 stats[other_host_idx][this_host_idx] += curr_val;
681 count[other_host_idx][this_host_idx] += 1;
682 }
683 for (int i = 0; i < num_hosts; i++) {
684 for (int j = 0; j < num_hosts; j++) {
685 if (count[i][j] > 0) stats[i][j] = stats[i][j] / count[i][j];
686 }
687 }
688 } else if (this.query_stat_type.equals("total_duration")) {
689 for(int i=0;i<events.size();i++) {
690 HashMap<String, Object> event = events.get(i);
691 start=(Long)event.get("start_time");
692 end=(Long)event.get("finish_time");
693 start_millis = Integer.parseInt(((String)event.get("start_time_millis")));
694 end_millis = Integer.parseInt(((String)event.get("finish_time_millis")));
695 String this_host = (String) event.get("hostname");
696 String other_host = (String) event.get("other_host");
697 int this_host_idx = host_indices.get(this_host).intValue();
698 int other_host_idx = host_indices.get(other_host).intValue();
699
700 double curr_val = end_millis - start_millis + ((end - start)*1000);
701
702
703 stats[other_host_idx][this_host_idx] += curr_val;
704 }
705 } else if (this.query_stat_type.equals("total_volume")) {
706 for(int i=0;i<events.size();i++) {
707 HashMap<String, Object> event = events.get(i);
708 start=(Long)event.get("start_time");
709 end=(Long)event.get("finish_time");
710 start_millis = Integer.parseInt(((String)event.get("start_time_millis")));
711 end_millis = Integer.parseInt(((String)event.get("finish_time_millis")));
712 String this_host = (String) event.get("hostname");
713 String other_host = (String) event.get("other_host");
714 int this_host_idx = host_indices.get(this_host).intValue();
715 int other_host_idx = host_indices.get(other_host).intValue();
716
717 long curr_val = Long.parseLong((String)event.get("bytes"));
718
719
720 stats[other_host_idx][this_host_idx] += curr_val;
721 }
722 }
723
724 int [] permute = null;
725 if (sort_nodes) {
726 permute = hClust(stats);
727 stats = doPermute(stats,permute);
728 }
729
730 Table agg_tab = new Table();
731 agg_tab.addColumn("stat", long.class);
732 min = Long.MAX_VALUE;
733 max = Long.MIN_VALUE;
734 agg_tab.addRows(num_hosts*num_hosts);
735
736
737 for (int i = 0; i < num_hosts; i++) {
738 for (int j = 0; j < num_hosts; j++) {
739 agg_tab.setLong((i*num_hosts)+j,"stat",stats[i][j]);
740 if (stats[i][j] > max) max = stats[i][j];
741 if (stats[i][j] > 0 && stats[i][j] < min) min = stats[i][j];
742 }
743 }
744 if (min == Long.MAX_VALUE) min = 0;
745
746 log.info(agg_tab);
747
748
749 HeatmapData hd = new HeatmapData();
750 hd.stats = new long[num_hosts][num_hosts];
751 hd.stats = stats;
752 hd.min = min;
753 hd.max = max;
754 hd.num_hosts = num_hosts;
755 hd.agg_tab = agg_tab;
756
757 this.add_info_extra = new String("\nState: "+this.prettyStateNames.get(this.query_state)+
758 " ("+events.size()+" "+this.query_state+"'s ["+this.query_stat_type+"])\n" +
759 "Plotted value range: ["+hd.min+","+hd.max+"] (Zeros in black)");
760
761 hd.hostnames = new String [num_hosts];
762 for (int i = 0; i < num_hosts; i++) {
763 String curr_host = host_rev_indices.get(new Integer(permute[i]));
764 if (sort_nodes) {
765 hd.hostnames[i] = new String(curr_host);
766 } else {
767 hd.hostnames[i] = new String(curr_host);
768 }
769 }
770
771 return hd;
772 }
773
774 }