This project has retired. For details please refer to its
Attic page.
Swimlanes 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 import prefuse.data.io.sql.*;
22 import prefuse.data.expression.parser.*;
23 import prefuse.data.expression.*;
24 import prefuse.data.column.*;
25 import prefuse.data.query.*;
26 import prefuse.data.*;
27 import prefuse.action.*;
28 import prefuse.action.layout.*;
29 import prefuse.action.assignment.*;
30 import prefuse.visual.expression.*;
31 import prefuse.visual.*;
32 import prefuse.render.*;
33 import prefuse.util.collections.*;
34 import prefuse.util.*;
35 import prefuse.*;
36
37 import org.apache.hadoop.chukwa.hicc.OfflineTimeHandler;
38 import org.apache.hadoop.chukwa.hicc.TimeHandler;
39 import org.apache.hadoop.chukwa.util.DatabaseWriter;
40 import org.apache.hadoop.chukwa.database.Macro;
41 import org.apache.hadoop.chukwa.util.XssFilter;
42
43 import org.apache.commons.logging.Log;
44 import org.apache.commons.logging.LogFactory;
45
46 import javax.servlet.http.*;
47
48 import java.sql.*;
49 import java.util.*;
50
51 import java.awt.Font;
52 import java.awt.geom.Rectangle2D;
53
54
55
56
57
58
59
60
61 public class Swimlanes {
62
63 private static Log log = LogFactory.getLog(Swimlanes.class);
64
65 int SIZE_X=1600, SIZE_Y=1600;
66 final int [] BORDER = {50,50,50,50};
67 final int LEGEND_X_OFFSET = 50;
68 final int LEGEND_Y_OFFSET = 25;
69 final int LEGEND_TEXT_OFFSET = 20;
70 final int LEGEND_FONT_SIZE = 18;
71 final int AXIS_NAME_FONT_SIZE = 24;
72
73 protected boolean offline_use = true;
74 protected HttpServletRequest request;
75
76 protected String abc;
77
78
79
80
81
82 protected class MapReduceSwimlanes {
83 protected Table plot_tab;
84 protected HashMap<String, ArrayList<Tuple> > reducepart_hash;
85 protected boolean collate_reduces = false;
86
87 public MapReduceSwimlanes() {
88 this.plot_tab = new Table();
89 this.plot_tab.addColumn("ycoord",float.class);
90 this.plot_tab.addColumn("state_name",String.class);
91 this.plot_tab.addColumn("hostname",String.class);
92 this.plot_tab.addColumn("friendly_id",String.class);
93 this.plot_tab.addColumn(START_FIELD_NAME,double.class);
94 this.plot_tab.addColumn(END_FIELD_NAME,double.class);
95 this.plot_tab.addColumn(PolygonRenderer.POLYGON,float[].class);
96 this.reducepart_hash = new HashMap<String, ArrayList<Tuple> >();
97 }
98
99 public void populateTable_OneLinePerState(Table orig_tab) {
100 IntIterator rownumiter;
101 int newrownum, origrownum;
102 rownumiter = orig_tab.rows();
103 while (rownumiter.hasNext()) {
104 origrownum = ((Integer)rownumiter.next()).intValue();
105 newrownum = this.plot_tab.addRow();
106 this.plot_tab.set(newrownum, "state_name", orig_tab.getString(origrownum, "state_name"));
107 this.plot_tab.set(newrownum, "ycoord", orig_tab.getInt(origrownum, "seqno"));
108 this.plot_tab.set(newrownum,"hostname",orig_tab.getString(origrownum,"hostname"));
109 this.plot_tab.set(newrownum,"friendly_id",orig_tab.getString(origrownum,"friendly_id"));
110 this.plot_tab.set(newrownum,START_FIELD_NAME, orig_tab.getDouble(origrownum,START_FIELD_NAME));
111 this.plot_tab.set(newrownum,END_FIELD_NAME, orig_tab.getDouble(origrownum,END_FIELD_NAME));
112 }
113 }
114
115 public void populateTable_CollateReduces(Table orig_tab) {
116 IntIterator rownumiter;
117 int newrownum, origrownum;
118
119 this.collate_reduces = true;
120
121
122 rownumiter = orig_tab.rows(
123 (Predicate) ExpressionParser.parse("[state_name] == 'map' " +
124 "OR [state_name] == 'shuffle_local' " +
125 "OR [state_name] == 'shuffle_remote'")
126 );
127
128 while (rownumiter.hasNext()) {
129 origrownum = ((Integer)rownumiter.next()).intValue();
130 newrownum = this.plot_tab.addRow();
131 this.plot_tab.set(newrownum, "state_name", orig_tab.getString(origrownum, "state_name"));
132 this.plot_tab.set(newrownum, "ycoord", orig_tab.getInt(origrownum, "seqno"));
133 this.plot_tab.set(newrownum,"hostname",orig_tab.getString(origrownum,"hostname"));
134 this.plot_tab.set(newrownum,"friendly_id",orig_tab.getString(origrownum,"friendly_id"));
135 this.plot_tab.set(newrownum,START_FIELD_NAME, orig_tab.getDouble(origrownum,START_FIELD_NAME));
136 this.plot_tab.set(newrownum,END_FIELD_NAME, orig_tab.getDouble(origrownum,END_FIELD_NAME));
137 }
138
139
140 IntIterator rownumiter3 = orig_tab.rows(
141 (Predicate) ExpressionParser.parse("[state_name] == 'reduce_reducer' " +
142 "OR [state_name] == 'reduce_shufflewait' " +
143 "OR [state_name] == 'reduce_sort' " +
144 "OR [state_name] == 'reduce'")
145 );
146
147 ArrayList<Tuple> tuple_array;
148 while (rownumiter3.hasNext()) {
149 origrownum = ((Integer)rownumiter3.next()).intValue();
150 if (orig_tab.getString(origrownum,"state_name").equals("reduce")) {
151 continue;
152 }
153 String curr_reduce = orig_tab.getString(origrownum, "friendly_id");
154 newrownum = this.plot_tab.addRow();
155
156 this.plot_tab.set(newrownum, "state_name", orig_tab.getString(origrownum, "state_name"));
157 this.plot_tab.set(newrownum, "ycoord", orig_tab.getInt(origrownum, "seqno"));
158 this.plot_tab.set(newrownum,"hostname",orig_tab.getString(origrownum,"hostname"));
159 this.plot_tab.set(newrownum,"friendly_id",orig_tab.getString(origrownum,"friendly_id"));
160 this.plot_tab.set(newrownum,START_FIELD_NAME, orig_tab.getDouble(origrownum,START_FIELD_NAME));
161 this.plot_tab.set(newrownum,END_FIELD_NAME, orig_tab.getDouble(origrownum,END_FIELD_NAME));
162
163 tuple_array = this.reducepart_hash.get(curr_reduce);
164 if (tuple_array == null) {
165 tuple_array = new ArrayList<Tuple>();
166 tuple_array.add(this.plot_tab.getTuple(newrownum));
167 this.reducepart_hash.put(curr_reduce, tuple_array);
168 } else {
169 tuple_array.add(this.plot_tab.getTuple(newrownum));
170 }
171 }
172 }
173
174 public void populateTable_MapsReducesOnly(Table orig_tab) {
175 IntIterator rownumiter;
176 int newrownum, origrownum;
177 rownumiter = orig_tab.rows(
178 (Predicate) ExpressionParser.parse("[state_name] == 'map' OR [state_name] == 'reduce'")
179 );
180 while (rownumiter.hasNext()) {
181 origrownum = ((Integer)rownumiter.next()).intValue();
182 newrownum = this.plot_tab.addRow();
183 this.plot_tab.set(newrownum, "state_name", orig_tab.getString(origrownum, "state_name"));
184 this.plot_tab.set(newrownum, "ycoord", orig_tab.getInt(origrownum, "seqno"));
185 this.plot_tab.set(newrownum,"hostname",orig_tab.getString(origrownum,"hostname"));
186 this.plot_tab.set(newrownum,"friendly_id",orig_tab.getString(origrownum,"friendly_id"));
187 this.plot_tab.set(newrownum,START_FIELD_NAME, orig_tab.getDouble(origrownum,START_FIELD_NAME));
188 this.plot_tab.set(newrownum,START_FIELD_NAME, orig_tab.getDouble(origrownum,END_FIELD_NAME));
189 }
190 }
191
192
193
194
195 public void groupByState() {
196 int counter, rownum;
197 int rowcount = this.plot_tab.getRowCount();
198 HashSet<String> states = new HashSet<String>();
199 String curr_state = null;
200 Iterator<String> state_iter;
201 IntIterator rownumiter;
202
203 for (int i = 0; i < rowcount; i++) {
204 states.add(this.plot_tab.getString(i,"state_name"));
205 }
206
207 state_iter = states.iterator();
208 counter = 1;
209 while (state_iter.hasNext()) {
210 curr_state = state_iter.next();
211
212 if (this.collate_reduces && ((curr_state.equals("reduce_reducer") || curr_state.equals("reduce_sort")))) {
213 continue;
214 }
215 rownumiter = this.plot_tab.rows(
216 (Predicate) ExpressionParser.parse("[state_name] == '"+curr_state+"'")
217 );
218 if (this.collate_reduces && curr_state.equals("reduce_shufflewait")) {
219 while (rownumiter.hasNext()) {
220 rownum = ((Integer)rownumiter.next()).intValue();
221 this.plot_tab.setFloat(rownum,"ycoord",(float)counter);
222
223 ArrayList<Tuple> alt = this.reducepart_hash.get(this.plot_tab.getString(rownum,"friendly_id"));
224 Object [] tarr = alt.toArray();
225 for (int i = 0; i < tarr.length; i++) ((Tuple)tarr[i]).setFloat("ycoord",(float)counter);
226 counter++;
227 }
228 } else {
229 while (rownumiter.hasNext()) {
230 rownum = ((Integer)rownumiter.next()).intValue();
231 this.plot_tab.setFloat(rownum,"ycoord",(float)counter);
232 counter++;
233 }
234 }
235 }
236 }
237
238 public void groupByStartTime() {
239 int counter, rownum;
240 String curr_state = null;
241 IntIterator rownumiter;
242
243 rownumiter = this.plot_tab.rowsSortedBy(START_FIELD_NAME, true);
244
245 counter = 1;
246 while (rownumiter.hasNext()) {
247 rownum = ((Integer)rownumiter.next()).intValue();
248 curr_state = this.plot_tab.getString(rownum, "state_name");
249
250 if (this.collate_reduces && curr_state.equals("reduce_shufflewait")) {
251 this.plot_tab.setFloat(rownum,"ycoord",(float)counter);
252 ArrayList<Tuple> alt = this.reducepart_hash.get(this.plot_tab.getString(rownum,"friendly_id"));
253 Object [] tarr = alt.toArray();
254 for (int i = 0; i < tarr.length; i++) ((Tuple)tarr[i]).setFloat("ycoord",(float)counter);
255 counter++;
256 } else if (!curr_state.equals("reduce_sort") && !curr_state.equals("reduce_reducer")) {
257 this.plot_tab.setFloat(rownum,"ycoord",(float)counter);
258 counter++;
259 }
260 }
261 }
262
263 public void groupByEndTime() {
264 int counter, rownum;
265 String curr_state = null;
266 IntIterator rownumiter;
267
268 rownumiter = this.plot_tab.rowsSortedBy(END_FIELD_NAME, true);
269 counter = 1;
270 while (rownumiter.hasNext()) {
271 rownum = ((Integer)rownumiter.next()).intValue();
272 curr_state = this.plot_tab.getString(rownum, "state_name");
273
274 if (this.collate_reduces && curr_state.equals("reduce_reducer")) {
275 this.plot_tab.setFloat(rownum,"ycoord",(float)counter);
276 ArrayList<Tuple> alt = this.reducepart_hash.get(this.plot_tab.getString(rownum,"friendly_id"));
277 Object [] tarr = alt.toArray();
278 for (int i = 0; i < tarr.length; i++) ((Tuple)tarr[i]).setFloat("ycoord",(float)counter);
279 counter++;
280 } else if (!curr_state.equals("reduce_sort") && !curr_state.equals("reduce_shufflewait")) {
281 this.plot_tab.setFloat(rownum,"ycoord",(float)counter);
282 counter++;
283 }
284 }
285 }
286
287 public VisualTable addToVisualization(Visualization viz, String groupname) {
288 return viz.addTable(groupname, this.plot_tab);
289 }
290 }
291
292
293
294
295
296
297 public static class SwimlanesStatePalette {
298 protected final String [] states = {"map","reduce","reduce_shufflewait","reduce_sort","reduce_reducer","shuffle"};
299 HashMap<String,Integer> colourmap;
300 protected int [] palette;
301 public SwimlanesStatePalette() {
302 palette = ColorLib.getCategoryPalette(states.length);
303 colourmap = new HashMap<String,Integer>();
304 for (int i = 0; i < states.length; i++) {
305 colourmap.put(states[i], new Integer(palette[i]));
306 }
307 }
308 public int getColour(String state_name) {
309 Integer val = colourmap.get(state_name);
310 if (val == null) {
311 return ColorLib.color(java.awt.Color.BLACK);
312 } else {
313 return val.intValue();
314 }
315 }
316 public int getNumStates() {
317 return this.states.length;
318 }
319 public String [] getStates() {
320 return this.states;
321 }
322 }
323
324
325
326
327
328 public static class CoordScaler {
329 double x_pixel_size, y_pixel_size;
330 double x_max_value, y_max_value, x_min_value, y_min_value;
331 double x_start, y_start;
332
333 public CoordScaler() {
334 this.x_pixel_size = 0.0;
335 this.y_pixel_size = 0.0;
336 this.x_max_value = 1.0;
337 this.y_max_value = 1.0;
338 this.x_min_value = 0.0;
339 this.y_min_value = 0.0;
340 this.x_start = 0.0;
341 this.y_start = 0.0;
342 }
343 public void set_pixel_start(double x, double y) {
344 this.x_start = x;
345 this.y_start = y;
346 }
347 public void set_pixel_size(double x, double y) {
348 this.x_pixel_size = x;
349 this.y_pixel_size = y;
350 }
351 public void set_value_ranges(double x_min, double y_min, double x_max, double y_max) {
352 this.x_max_value = x_max;
353 this.y_max_value = y_max;
354 this.x_min_value = x_min;
355 this.y_min_value = y_min;
356 }
357 public double get_x_coord(double x_value) {
358 return x_start+(((x_value - x_min_value) / (x_max_value-x_min_value)) * x_pixel_size);
359 }
360 public double get_y_coord(double y_value) {
361
362 return y_start+(y_pixel_size - ((((y_value - y_min_value) / (y_max_value-y_min_value)) * y_pixel_size)));
363 }
364 }
365
366
367
368
369 public static class SwimlanesStateAction extends GroupAction {
370
371 protected CoordScaler cs;
372
373 public SwimlanesStateAction() {
374 super();
375 }
376
377 public SwimlanesStateAction(String group, CoordScaler cs) {
378 super(group);
379 this.cs = cs;
380 }
381
382 public void run (double frac) {
383 VisualItem item = null;
384 SwimlanesStatePalette pal = new SwimlanesStatePalette();
385
386 Iterator<?> curr_group_items = this.m_vis.items(this.m_group);
387
388 while (curr_group_items.hasNext()) {
389 item = (VisualItem) curr_group_items.next();
390
391 double start_time = item.getDouble(START_FIELD_NAME);
392 double finish_time = item.getDouble(END_FIELD_NAME);
393 item.setShape(Constants.POLY_TYPE_LINE);
394 item.setX(0.0);
395 item.setY(0.0);
396
397 float [] coords = new float[4];
398 coords[0] = (float) cs.get_x_coord(start_time);
399 coords[1] = (float) cs.get_y_coord((double)item.getInt("ycoord"));
400 coords[2] = (float) cs.get_x_coord(finish_time);
401 coords[3] = (float) cs.get_y_coord((double)item.getInt("ycoord"));
402
403 item.set(VisualItem.POLYGON,coords);
404 item.setStrokeColor(pal.getColour(item.getString("state_name")));
405 }
406 }
407 }
408
409
410
411 protected HashMap<String, String> param_map;
412
413 protected String cluster;
414 protected String timezone;
415 protected String shuffle_option;
416 protected final String table = new String("mapreduce_fsm");
417 protected boolean plot_legend = true;
418 protected String jobname = null;
419
420 protected Display dis;
421 protected Visualization viz;
422
423 protected Rectangle2D dataBound = new Rectangle2D.Double();
424 protected Rectangle2D xlabBound = new Rectangle2D.Double();
425 protected Rectangle2D ylabBound = new Rectangle2D.Double();
426 protected Rectangle2D labelBottomBound = new Rectangle2D.Double();
427
428 static final String START_FIELD_NAME = "start_time_num";
429 static final String END_FIELD_NAME = "finish_time_num";
430
431
432 final String maingroup = "Job";
433 final String othergroup = "Misc";
434 final String labelgroup = "Label";
435 final String legendgroup = "Legend";
436 final String legendshapegroup = "LegendShape";
437
438 public Swimlanes() {
439 this.cluster = new String("");
440 this.timezone = new String("");
441 this.shuffle_option = new String("");
442 param_map = new HashMap<String, String>();
443 }
444
445
446
447
448
449
450
451
452 public Swimlanes
453 (String timezone, String cluster, String event_type,
454 HashMap<String, String> valmap)
455 {
456 this.cluster = new String(cluster);
457 if (timezone != null) {
458 this.timezone = new String(timezone);
459 } else {
460 this.timezone = null;
461 }
462 this.shuffle_option = new String(event_type);
463
464
465
466
467 this.param_map = valmap;
468 }
469
470 public Swimlanes
471 (String timezone, String cluster, String event_type,
472 HashMap<String, String> valmap, int width, int height)
473 {
474 this.cluster = new String(cluster);
475 if (timezone != null) {
476 this.timezone = new String(timezone);
477 } else {
478 this.timezone = null;
479 }
480 this.shuffle_option = new String(event_type);
481
482
483
484
485 this.param_map = valmap;
486
487 this.SIZE_X = width;
488 this.SIZE_Y = height;
489 }
490
491 public Swimlanes
492 (String timezone, String cluster, String event_type,
493 HashMap<String, String> valmap, int width, int height,
494 String legend_opt)
495 {
496 this.cluster = new String(cluster);
497 if (timezone != null) {
498 this.timezone = new String(timezone);
499 } else {
500 this.timezone = null;
501 }
502 this.shuffle_option = new String(event_type);
503
504
505
506
507 this.param_map = valmap;
508
509 this.SIZE_X = width;
510 this.SIZE_Y = height;
511
512 if (legend_opt.equals("nolegend")) {
513 this.plot_legend = false;
514 }
515
516 }
517
518 public Swimlanes(HttpServletRequest request) {
519 XssFilter xf = new XssFilter(request);
520 this.offline_use = false;
521 this.request = request;
522 HttpSession session = request.getSession();
523 this.cluster = session.getAttribute("cluster").toString();
524 String evt_type = xf.getParameter("event_type");
525 if (evt_type != null) {
526 this.shuffle_option = new String(evt_type);
527 } else {
528 this.shuffle_option = new String("noshuffle");
529 }
530 this.timezone = session.getAttribute("time_zone").toString();
531 }
532
533
534
535
536
537 public void setJobName(String s) {
538 this.jobname = new String(s);
539 }
540
541
542
543
544
545 public void setDimensions(int width, int height) {
546 this.SIZE_X=width;
547 this.SIZE_Y=height;
548 }
549
550
551
552
553
554
555
556 public void setLegend(boolean legendopt) {
557 if (legendopt) {
558 this.plot_legend = true;
559 } else {
560 this.plot_legend = false;
561 }
562 }
563
564
565
566
567
568 public boolean getImage(java.io.OutputStream output, String img_fmt, double scale) {
569 dis = new Display(this.viz);
570 dis.setSize(SIZE_X,SIZE_Y);
571 dis.setHighQuality(true);
572 dis.setFont(new Font(Font.SANS_SERIF,Font.PLAIN,24));
573 return dis.saveImage(output, img_fmt, scale);
574 }
575
576
577
578
579
580
581
582
583
584
585
586
587
588 protected Table addTimeCol
589 (Table origTable, String srcFieldName,
590 String srcMillisecondFieldName, String dstFieldName)
591 {
592 origTable.addColumn(dstFieldName, long.class);
593
594 int total_rows = origTable.getRowCount();
595 for (int curr_row_num = 0; curr_row_num < total_rows; curr_row_num++) {
596 origTable.setLong(curr_row_num, dstFieldName,
597 ((Timestamp)origTable.get(curr_row_num, srcFieldName)).getTime() +
598 origTable.getLong(curr_row_num, srcMillisecondFieldName)
599 );
600 }
601
602 return origTable;
603 }
604
605
606
607
608
609
610
611
612
613
614
615
616 protected Table addTimeOffsetCol
617 (Table origTable, String srcFieldName,
618 String srcMillisecondFieldName, String dstFieldName,
619 long timeOffset)
620 {
621 Table newtable = addTimeCol(origTable, srcFieldName,
622 srcMillisecondFieldName, dstFieldName + "_fulltime");
623
624 ColumnMetadata dstcol = newtable.getMetadata(dstFieldName + "_fulltime");
625 long mintime = newtable.getLong(dstcol.getMinimumRow(), dstFieldName + "_fulltime");
626
627 if (timeOffset == 0) {
628 newtable.addColumn(dstFieldName, "ROUND((["+dstFieldName+"_fulltime] - " + mintime +"L) / 1000L)");
629 } else {
630 newtable.addColumn(dstFieldName, "ROUND((["+dstFieldName+"_fulltime] - " + timeOffset +"L) / 1000L)");
631 }
632
633 return newtable;
634 }
635
636 protected void setupRenderer() {
637 this.viz.setRendererFactory(new RendererFactory(){
638 AbstractShapeRenderer sr = new ShapeRenderer();
639 ShapeRenderer sr_big = new ShapeRenderer(20);
640 Renderer arY = new AxisRenderer(Constants.LEFT, Constants.TOP);
641 Renderer arX = new AxisRenderer(Constants.CENTER, Constants.BOTTOM);
642 PolygonRenderer pr = new PolygonRenderer(Constants.POLY_TYPE_LINE);
643 LabelRenderer lr = new LabelRenderer("label");
644 LabelRenderer lr_legend = new LabelRenderer("label");
645
646 public Renderer getRenderer(VisualItem item) {
647 lr.setHorizontalAlignment(Constants.CENTER);
648 lr.setVerticalAlignment(Constants.TOP);
649 lr_legend.setHorizontalAlignment(Constants.LEFT);
650 lr_legend.setVerticalAlignment(Constants.CENTER);
651
652 if (item.isInGroup("ylab")) {
653 return arY;
654 } else if (item.isInGroup("xlab")) {
655 return arX;
656 } else if (item.isInGroup(maingroup)) {
657 return pr;
658 } else if (item.isInGroup(labelgroup)) {
659 return lr;
660 } else if (item.isInGroup(legendgroup)) {
661 return lr_legend;
662 } else if (item.isInGroup(legendshapegroup)) {
663 return sr_big;
664 } else {
665 return sr;
666 }
667 }
668 });
669 }
670
671
672 protected Table setupDataTable() {
673 Table res_tab = this.getData();
674 if (res_tab == null) {
675 return res_tab;
676 }
677
678 res_tab.addColumn("seqno","ROW()");
679 res_tab = addTimeOffsetCol(res_tab, "start_time", "start_time_millis", START_FIELD_NAME, 0);
680 ColumnMetadata dstcol = res_tab.getMetadata(START_FIELD_NAME);
681 long mintime = ((Timestamp)res_tab.get(dstcol.getMinimumRow(), "start_time")).getTime();
682 res_tab = addTimeOffsetCol(res_tab, "finish_time", "finish_time_millis", END_FIELD_NAME, mintime);
683 res_tab.addColumn(PolygonRenderer.POLYGON,float[].class);
684
685 log.debug("After adding seqno: #cols: " + res_tab.getColumnCount() + "; #rows: " + res_tab.getRowCount());
686
687 return res_tab;
688 }
689
690 protected void addAxisNames() {
691 Table textlabels_table = new Table();
692 textlabels_table.addColumn("label",String.class);
693 textlabels_table.addColumn("type",String.class);
694 textlabels_table.addRow();
695 textlabels_table.setString(0,"label",new String("Time/s"));
696 textlabels_table.setString(0,"type",new String("xaxisname"));
697
698 VisualTable textlabelsviz = this.viz.addTable(labelgroup, textlabels_table);
699 textlabelsviz.setX(0,SIZE_X/2);
700 textlabelsviz.setY(0,SIZE_Y - BORDER[2] + (BORDER[2]*0.1));
701 textlabelsviz.setTextColor(0,ColorLib.color(java.awt.Color.GRAY));
702 textlabelsviz.setFont(0,new Font(Font.SANS_SERIF,Font.PLAIN,AXIS_NAME_FONT_SIZE));
703 }
704
705 protected void addLegend() {
706 SwimlanesStatePalette ssp = new SwimlanesStatePalette();
707
708 Table shapes_table = new Table();
709 shapes_table.addColumn(VisualItem.X,float.class);
710 shapes_table.addColumn(VisualItem.Y,float.class);
711
712 Table legend_labels_table = new Table();
713 legend_labels_table.addColumn("label",String.class);
714
715
716 int num_states = ssp.getNumStates();
717 String [] state_names = ssp.getStates();
718 legend_labels_table.addRows(num_states);
719 shapes_table.addRows(num_states);
720 for (int i = 0; i < num_states; i++) {
721 legend_labels_table.setString(i,"label",state_names[i]);
722 }
723
724
725 VisualTable shapes_table_viz = viz.addTable(legendshapegroup, shapes_table);
726 float start_x = BORDER[0] + LEGEND_X_OFFSET;
727 float start_y = BORDER[1] + LEGEND_Y_OFFSET;
728 float incr = (float) 30.0;
729 for (int i = 0; i < num_states; i++) {
730 shapes_table_viz.setFillColor(i, ssp.getColour(state_names[i]));
731 shapes_table_viz.setFloat(i, VisualItem.X, start_x);
732 shapes_table_viz.setFloat(i, VisualItem.Y, start_y + (i * incr));
733 }
734
735
736 VisualTable legend_labels_table_viz = this.viz.addTable(legendgroup, legend_labels_table);
737 for (int i = 0; i < num_states; i++) {
738 legend_labels_table_viz.setFloat(i, VisualItem.X, start_x + LEGEND_TEXT_OFFSET);
739 legend_labels_table_viz.setFloat(i, VisualItem.Y, start_y + (i * incr));
740 legend_labels_table_viz.setTextColor(i,ColorLib.color(java.awt.Color.BLACK));
741 legend_labels_table_viz.setFont(i,new Font(Font.SANS_SERIF,Font.PLAIN,LEGEND_FONT_SIZE));
742 }
743
744 }
745
746 public void run() {
747
748
749 this.dataBound.setRect(BORDER[0],BORDER[1],SIZE_X-BORDER[2]-BORDER[0],SIZE_Y-BORDER[3]-BORDER[1]);
750 this.xlabBound.setRect(BORDER[0],BORDER[1],SIZE_X-BORDER[2]-BORDER[0],SIZE_Y-BORDER[3]-BORDER[1]);
751 this.ylabBound.setRect(BORDER[0],BORDER[1],SIZE_X-BORDER[2]-BORDER[0],SIZE_Y-BORDER[3]-BORDER[1]);
752 this.labelBottomBound.setRect(BORDER[0],SIZE_X-BORDER[2],SIZE_Y-BORDER[0]-BORDER[1],BORDER[3]);
753
754
755 this.viz = new Visualization();
756 this.setupRenderer();
757
758
759 Table raw_data_tab = this.setupDataTable();
760 MapReduceSwimlanes mrs = new MapReduceSwimlanes();
761 mrs.populateTable_CollateReduces(raw_data_tab);
762 mrs.groupByState();
763 VisualTable maindatatable = mrs.addToVisualization(this.viz, maingroup);
764
765 addAxisNames();
766 if (plot_legend) {
767 addLegend();
768 }
769
770
771 ActionList draw = new ActionList();
772 {
773
774 AxisLayout xaxis = new AxisLayout(maingroup, START_FIELD_NAME, Constants.X_AXIS, VisiblePredicate.TRUE);
775 AxisLayout yaxis = new AxisLayout(maingroup, "ycoord", Constants.Y_AXIS, VisiblePredicate.FALSE);
776 xaxis.setLayoutBounds(dataBound);
777 yaxis.setLayoutBounds(dataBound);
778
779 ColumnMetadata starttime_meta = maindatatable.getMetadata(START_FIELD_NAME);
780 ColumnMetadata finishtime_meta = maindatatable.getMetadata(END_FIELD_NAME);
781 ColumnMetadata ycoord_meta = maindatatable.getMetadata("ycoord");
782 long x_min = (long) ((Double)maindatatable.get(starttime_meta.getMinimumRow(), START_FIELD_NAME)).doubleValue();
783 long x_max = (long) ((Double)maindatatable.get(finishtime_meta.getMaximumRow(), END_FIELD_NAME)).doubleValue();
784 xaxis.setRangeModel(new NumberRangeModel(x_min,x_max,x_min,x_max));
785 float y_max = maindatatable.getFloat(ycoord_meta.getMaximumRow(),"ycoord");
786 yaxis.setRangeModel(new NumberRangeModel(0,y_max,0,y_max));
787
788
789 CoordScaler cs = new CoordScaler();
790 cs.set_pixel_size(SIZE_X-BORDER[0]-BORDER[2], SIZE_Y-BORDER[1]-BORDER[3]);
791 cs.set_pixel_start(BORDER[0],BORDER[1]);
792 cs.set_value_ranges(x_min,0,x_max,y_max);
793
794 SwimlanesStateAction swimlaneslines = new SwimlanesStateAction(maingroup, cs);
795
796
797 draw.add(xaxis);
798 draw.add(yaxis);
799 draw.add(swimlaneslines);
800
801 AxisLabelLayout xlabels = new AxisLabelLayout("xlab", xaxis, xlabBound);
802 this.viz.putAction("xlabels",xlabels);
803 AxisLabelLayout ylabels = new AxisLabelLayout("ylab", yaxis, ylabBound);
804 this.viz.putAction("ylabels",ylabels);
805 }
806
807
808 {
809 SpecifiedLayout sl = new SpecifiedLayout(labelgroup, VisualItem.X, VisualItem.Y);
810 ActionList labeldraw = new ActionList();
811 labeldraw.add(sl);
812 this.viz.putAction(labelgroup, labeldraw);
813 }
814
815
816 if (plot_legend) {
817 ShapeAction legend_sa = new ShapeAction(legendshapegroup);
818 SpecifiedLayout legendlabels_sl = new SpecifiedLayout(legendgroup, VisualItem.X, VisualItem.Y);
819
820 ActionList legenddraw = new ActionList();
821 legenddraw.add(legend_sa);
822 this.viz.putAction(legendshapegroup, legenddraw);
823 ActionList legendlabelsdraw = new ActionList();
824 legendlabelsdraw.add(legendlabels_sl);
825 this.viz.putAction(legendgroup,legendlabelsdraw);
826 }
827
828
829 this.viz.putAction("draw",draw);
830
831
832 this.viz.run("draw");
833 this.viz.run("xlabels");
834 this.viz.run("ylabels");
835
836 }
837
838 public Table getData() {
839
840 OfflineTimeHandler time_offline;
841 TimeHandler time_online;
842 long start, end;
843
844 if (offline_use) {
845 time_offline = new OfflineTimeHandler(param_map, this.timezone);
846 start = time_offline.getStartTime();
847 end = time_offline.getEndTime();
848 } else {
849 time_online = new TimeHandler(this.request, this.timezone);
850 start = time_online.getStartTime();
851 end = time_online.getEndTime();
852 }
853
854 DatabaseWriter dbw = new DatabaseWriter(this.cluster);
855 String query;
856
857
858 if (this.shuffle_option != null && this.shuffle_option.equals("shuffles")) {
859 query = "select job_id,friendly_id,start_time,finish_time,start_time_millis,finish_time_millis,status,state_name,hostname from ["+this.table+"] where finish_time between '[start]' and '[end]'";
860 } else {
861 query = "select job_id,friendly_id,start_time,finish_time,start_time_millis,finish_time_millis,status,state_name,hostname from ["+this.table+"] where finish_time between '[start]' and '[end]' and not state_name like 'shuffle_local' and not state_name like 'shuffle_remote'";
862 }
863 if (this.jobname != null) {
864 query = query + " and job_id like '"+ this.jobname +"'";
865 }
866 Macro mp = new Macro(start,end,query);
867 query = mp.toString() + " order by start_time";
868
869 Table rs_tab = null;
870 DatabaseDataSource dds;
871
872 log.debug("Query: " + query);
873
874 try {
875 dds = ConnectionFactory.getDatabaseConnection(dbw.getConnection());
876 rs_tab = dds.getData(query);
877 } catch (prefuse.data.io.DataIOException e) {
878 System.err.println("prefuse data IO error: " + e);
879 log.warn("prefuse data IO error: " + e);
880 return null;
881 } catch (SQLException e) {
882 System.err.println("Error in SQL: " + e + " in statement: " + query);
883 log.warn("Error in SQL: " + e + " in statement: " + query);
884 return null;
885 }
886
887 HashMap<String, Integer> state_counts = new HashMap<String, Integer>();
888 HashSet<String> states = new HashSet<String>();
889 for (int i = 0; i < rs_tab.getRowCount(); i++) {
890 String curr_state = rs_tab.getString(i, "state_name");
891 states.add(curr_state);
892 Integer cnt = state_counts.get(curr_state);
893 if (cnt == null) {
894 state_counts.put(curr_state, new Integer(1));
895 } else {
896 state_counts.remove(curr_state);
897 state_counts.put(curr_state, new Integer(cnt.intValue()+1));
898 }
899 }
900
901 log.info("Search complete: #cols: " + rs_tab.getColumnCount() + "; #rows: " + rs_tab.getRowCount());
902
903 return rs_tab;
904 }
905
906 }