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