mirror of
https://github.com/nasa/trick.git
synced 2024-12-19 21:27:54 +00:00
Break up and document the classes that compose JobPerf.
This commit is contained in:
parent
1c6c73bdc6
commit
c311abce8a
@ -0,0 +1,50 @@
|
|||||||
|
package trick.jobperf;
|
||||||
|
|
||||||
|
import java.awt.*;
|
||||||
|
import java.awt.event.*;
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
import java.io.*;
|
||||||
|
import java.lang.Math;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.List;
|
||||||
|
import javax.swing.*;
|
||||||
|
import javax.swing.event.*;
|
||||||
|
import java.net.URL;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class JobExecutionEvent represents one execution/run of a Trick job.
|
||||||
|
* <id> identifies the job. <start> and <stop> specify the
|
||||||
|
* clock times at which the job started and finished.
|
||||||
|
* <isEOF> and <isTOF> indicate whether the job was run as
|
||||||
|
* an "end-of-frame", or a "top-of-frame" job.
|
||||||
|
*/
|
||||||
|
class JobExecutionEvent {
|
||||||
|
public String id;
|
||||||
|
public boolean isEOF;
|
||||||
|
public boolean isTOF;
|
||||||
|
public double start;
|
||||||
|
public double stop;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param identifier identifies the relavant Trick job.
|
||||||
|
* @param isTopOfFrame true if the job is a "top-of-frame" job, otherwise false.
|
||||||
|
* @param isEndOfFrame true if the job is a "end-of-frame" job, otherwise false.
|
||||||
|
* @param start_time the start time (seconds) of the identified job.
|
||||||
|
* @param stop_time the stop time (seconds) of the identified job.
|
||||||
|
*/
|
||||||
|
public JobExecutionEvent(String identifier, boolean isTopOfFrame, boolean isEndOfFrame, double start_time, double stop_time) {
|
||||||
|
id = identifier;
|
||||||
|
isEOF = isEndOfFrame;
|
||||||
|
isTOF = isTopOfFrame;
|
||||||
|
start = start_time;
|
||||||
|
stop = stop_time;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Create a String representation of an object of this class.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return ( "JobExecutionEvent: " + id + "," + start + "," + stop );
|
||||||
|
}
|
||||||
|
}
|
@ -1,737 +1,23 @@
|
|||||||
package trick.jobperf;
|
package trick.jobperf;
|
||||||
|
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
import java.awt.event.*;
|
|
||||||
import java.awt.image.BufferedImage;
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.lang.Math;
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.List;
|
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
import javax.swing.event.*;
|
|
||||||
|
|
||||||
class JobExecutionEvent {
|
|
||||||
public String id;
|
|
||||||
public boolean isEOF;
|
|
||||||
public boolean isTOF;
|
|
||||||
public double start;
|
|
||||||
public double stop;
|
|
||||||
|
|
||||||
public JobExecutionEvent(String identifier, boolean isTopOfFrame, boolean isEndOfFrame, double start_time, double stop_time) {
|
|
||||||
id = identifier;
|
|
||||||
isEOF = isEndOfFrame;
|
|
||||||
isTOF = isTopOfFrame;
|
|
||||||
start = start_time;
|
|
||||||
stop = stop_time;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String toString() {
|
|
||||||
return ( "JobExecutionEvent: " + id + "," + start + "," + stop );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class KeyedColorMap {
|
|
||||||
private Map<String, Color> colorMap;
|
|
||||||
int minColorIntensity;
|
|
||||||
|
|
||||||
public KeyedColorMap() {
|
|
||||||
colorMap = new HashMap<String, Color>();
|
|
||||||
minColorIntensity = 100;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Color generateColor () {
|
|
||||||
Random rand = new Random();
|
|
||||||
boolean found = false;
|
|
||||||
int R = 0;
|
|
||||||
int G = 0;
|
|
||||||
int B = 0;
|
|
||||||
|
|
||||||
while (!found) {
|
|
||||||
R = rand.nextInt(256);
|
|
||||||
G = rand.nextInt(256);
|
|
||||||
B = rand.nextInt(256);
|
|
||||||
found = true;
|
|
||||||
if ((R < minColorIntensity) && (G < minColorIntensity) && (B < minColorIntensity)) {
|
|
||||||
found = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return new Color( R,G,B);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addKey( String identifier ) {
|
|
||||||
if (!colorMap.containsKey(identifier)) {
|
|
||||||
colorMap.put(identifier, generateColor());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Given the key, return the color.
|
|
||||||
public Color getColor(String identifier) {
|
|
||||||
return colorMap.get(identifier);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Given the color, return the key.
|
|
||||||
public String getKeyOfColor(Color search_color) {
|
|
||||||
for (Map.Entry<String, Color> entry : colorMap.entrySet()) {
|
|
||||||
String id = entry.getKey();
|
|
||||||
Color color = entry.getValue();
|
|
||||||
if (color.getRGB() == search_color.getRGB()) {
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void readFile(String fileName) throws IOException {
|
|
||||||
try {
|
|
||||||
BufferedReader in = new BufferedReader( new FileReader(fileName) );
|
|
||||||
String line;
|
|
||||||
String field[];
|
|
||||||
|
|
||||||
while( (line = in.readLine()) !=null) {
|
|
||||||
field = line.split(",");
|
|
||||||
String id = field[0];
|
|
||||||
int R = Integer.parseInt( field[1]);
|
|
||||||
int G = Integer.parseInt( field[2]);
|
|
||||||
int B = Integer.parseInt( field[3]);
|
|
||||||
colorMap.put(id, new Color(R,G,B));
|
|
||||||
}
|
|
||||||
in.close();
|
|
||||||
} catch ( java.io.FileNotFoundException e ) {
|
|
||||||
System.out.println("File \"" + fileName + "\" not found.\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void writeFile(String fileName) throws IOException {
|
|
||||||
BufferedWriter out = new BufferedWriter( new FileWriter(fileName) );
|
|
||||||
for (Map.Entry<String, Color> entry : colorMap.entrySet()) {
|
|
||||||
String id = entry.getKey();
|
|
||||||
Color color = entry.getValue();
|
|
||||||
String line = String.format(id + "," + color.getRed() +
|
|
||||||
"," + color.getGreen() +
|
|
||||||
"," + color.getBlue() + "\n");
|
|
||||||
out.write(line, 0, line.length());
|
|
||||||
}
|
|
||||||
out.flush();
|
|
||||||
out.close();
|
|
||||||
}
|
|
||||||
} // KeyedColorMap
|
|
||||||
|
|
||||||
class TraceViewCanvas extends JPanel {
|
|
||||||
|
|
||||||
public static final int MIN_TRACE_WIDTH = 4;
|
|
||||||
public static final int DEFAULT_TRACE_WIDTH = 10;
|
|
||||||
public static final int MAX_TRACE_WIDTH = 30;
|
|
||||||
public static final int LEFT_MARGIN = 100;
|
|
||||||
public static final int RIGHT_MARGIN = 100;
|
|
||||||
public static final int TOP_MARGIN = 20;
|
|
||||||
public static final int BOTTOM_MARGIN = 20;
|
|
||||||
|
|
||||||
private int traceWidth;
|
|
||||||
private double frameDuration;
|
|
||||||
private List<JobExecutionEvent> jobExecList;
|
|
||||||
private KeyedColorMap idToColorMap;
|
|
||||||
private BufferedImage image;
|
|
||||||
private TraceViewOutputToolBar sToolBar;
|
|
||||||
private Cursor crossHairCursor;
|
|
||||||
private Cursor defaultCursor;
|
|
||||||
|
|
||||||
public TraceViewCanvas( ArrayList<JobExecutionEvent> jobExecEvtList, TraceViewOutputToolBar outputToolBar ) {
|
|
||||||
|
|
||||||
traceWidth = DEFAULT_TRACE_WIDTH;
|
|
||||||
frameDuration = 1.0;
|
|
||||||
image = null;
|
|
||||||
sToolBar = outputToolBar;
|
|
||||||
jobExecList = jobExecEvtList;
|
|
||||||
crossHairCursor = new Cursor( Cursor.CROSSHAIR_CURSOR );
|
|
||||||
defaultCursor = new Cursor( Cursor.DEFAULT_CURSOR );
|
|
||||||
double smallestStart = Double.MAX_VALUE;
|
|
||||||
double largestStop = -Double.MAX_VALUE;
|
|
||||||
|
|
||||||
try {
|
|
||||||
idToColorMap = new KeyedColorMap();
|
|
||||||
idToColorMap.readFile("IdToColors.txt");
|
|
||||||
|
|
||||||
boolean wasTOF = false;
|
|
||||||
double startOfFrame = 0.0;
|
|
||||||
double lastStartOfFrame = 0.0;
|
|
||||||
double frameSizeSum = 0.0;
|
|
||||||
int frameNumber = 0;
|
|
||||||
int frameSizeCount = 0;
|
|
||||||
|
|
||||||
for (JobExecutionEvent jobExec : jobExecList ) {
|
|
||||||
if (jobExec.start < smallestStart) smallestStart = jobExec.start;
|
|
||||||
if (jobExec.stop > largestStop) largestStop = jobExec.stop;
|
|
||||||
// Calculate the average frame size.
|
|
||||||
if (!wasTOF && jobExec.isTOF) {
|
|
||||||
startOfFrame = jobExec.start;
|
|
||||||
if (frameNumber > 0) {
|
|
||||||
double frameSize = (startOfFrame - lastStartOfFrame);
|
|
||||||
frameSizeSum += frameSize;
|
|
||||||
frameSizeCount ++;
|
|
||||||
}
|
|
||||||
lastStartOfFrame = startOfFrame;
|
|
||||||
frameNumber++;
|
|
||||||
}
|
|
||||||
wasTOF = jobExec.isTOF;
|
|
||||||
idToColorMap.addKey(jobExec.id);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Calculate the average frame size.
|
|
||||||
frameDuration = frameSizeSum / frameSizeCount;
|
|
||||||
idToColorMap.writeFile("IdToColors.txt");
|
|
||||||
|
|
||||||
System.out.println("File loaded.\n");
|
|
||||||
} catch ( java.io.FileNotFoundException e ) {
|
|
||||||
System.out.println("File not found.\n");
|
|
||||||
System.exit(0);
|
|
||||||
} catch ( java.io.IOException e ) {
|
|
||||||
System.out.println("IO Exception.\n");
|
|
||||||
System.exit(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
int preferredHeight = traceWidth * (int)((largestStop - smallestStart) / frameDuration) + TOP_MARGIN;
|
|
||||||
setPreferredSize(new Dimension(500, preferredHeight));
|
|
||||||
|
|
||||||
ViewListener viewListener = new ViewListener();
|
|
||||||
addMouseListener(viewListener);
|
|
||||||
addMouseMotionListener(viewListener);
|
|
||||||
}
|
|
||||||
|
|
||||||
public double getFrameDuration() {
|
|
||||||
return frameDuration;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setFrameDuration(double duration) {
|
|
||||||
frameDuration = duration;
|
|
||||||
repaint();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void increaseTraceWidth() {
|
|
||||||
if (traceWidth < MAX_TRACE_WIDTH) {
|
|
||||||
traceWidth ++;
|
|
||||||
repaint();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void decreaseTraceWidth() {
|
|
||||||
if (traceWidth > MIN_TRACE_WIDTH) {
|
|
||||||
traceWidth --;
|
|
||||||
repaint();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean traceRectContains(int x, int y) {
|
|
||||||
int traceRectXMax = getWidth() - RIGHT_MARGIN;
|
|
||||||
if ( x < (LEFT_MARGIN)) return false;
|
|
||||||
if ( x > (traceRectXMax)) return false;
|
|
||||||
if ( y < TOP_MARGIN) return false;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean timeRectContains(int x, int y) {
|
|
||||||
int timeRectXMin = 30;
|
|
||||||
int timeRectXMax = LEFT_MARGIN;
|
|
||||||
if ( x < 30 ) return false;
|
|
||||||
if ( x > LEFT_MARGIN) return false;
|
|
||||||
if ( y < TOP_MARGIN) return false;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private class ViewListener extends MouseInputAdapter {
|
|
||||||
public void mouseReleased(MouseEvent e) {
|
|
||||||
int x = e.getX();
|
|
||||||
int y = e.getY();
|
|
||||||
Color color = new Color ( image.getRGB(x,y) );
|
|
||||||
|
|
||||||
String id = idToColorMap.getKeyOfColor( color );
|
|
||||||
sToolBar.setJobID(id);
|
|
||||||
|
|
||||||
if ( y > TOP_MARGIN) {
|
|
||||||
int frameNumber = (y - TOP_MARGIN) / traceWidth;
|
|
||||||
sToolBar.setFrameNumber(frameNumber);
|
|
||||||
}
|
|
||||||
if ( traceRectContains(x, y)) {
|
|
||||||
double pixelsPerSecond = (double)calcTraceRectWidth() / frameDuration;
|
|
||||||
double subFrameTime = (x - LEFT_MARGIN) / pixelsPerSecond;
|
|
||||||
sToolBar.setSubFrameTime(subFrameTime);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void mouseMoved(MouseEvent e) {
|
|
||||||
int x = e.getX();
|
|
||||||
int y = e.getY();
|
|
||||||
if ( traceRectContains(x, y)) {
|
|
||||||
setCursor(crossHairCursor);
|
|
||||||
} else {
|
|
||||||
setCursor(defaultCursor);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private int calcTraceRectHeight() {
|
|
||||||
return ( getHeight() - TOP_MARGIN - BOTTOM_MARGIN);
|
|
||||||
}
|
|
||||||
|
|
||||||
private int calcTraceRectWidth() {
|
|
||||||
return ( getWidth() - LEFT_MARGIN - RIGHT_MARGIN);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void doDrawing(Graphics g) {
|
|
||||||
Graphics2D g2d = (Graphics2D) g;
|
|
||||||
|
|
||||||
RenderingHints rh = new RenderingHints(
|
|
||||||
RenderingHints.KEY_ANTIALIASING,
|
|
||||||
RenderingHints.VALUE_ANTIALIAS_ON);
|
|
||||||
|
|
||||||
rh.put(RenderingHints.KEY_RENDERING,
|
|
||||||
RenderingHints.VALUE_RENDER_QUALITY);
|
|
||||||
|
|
||||||
int traceRectHeight = calcTraceRectHeight();
|
|
||||||
int traceRectWidth = calcTraceRectWidth();
|
|
||||||
double pixelsPerSecond = (double)traceRectWidth / frameDuration;
|
|
||||||
|
|
||||||
// Panel Background Color Fill
|
|
||||||
g2d.setPaint(Color.WHITE);
|
|
||||||
g2d.fillRect(0, 0, getWidth(), getHeight());
|
|
||||||
|
|
||||||
// Frame Trace Rectangle Fill
|
|
||||||
g2d.setPaint(Color.BLACK);
|
|
||||||
g2d.fillRect(LEFT_MARGIN, TOP_MARGIN, traceRectWidth, traceRectHeight);
|
|
||||||
|
|
||||||
boolean wasEOF = false;
|
|
||||||
boolean wasTOF = false;
|
|
||||||
double startOfFrame = 0.0;
|
|
||||||
int frameNumber = 0;
|
|
||||||
|
|
||||||
for (JobExecutionEvent jobExec : jobExecList ) {
|
|
||||||
|
|
||||||
if (!wasTOF && jobExec.isTOF) {
|
|
||||||
startOfFrame = jobExec.start;
|
|
||||||
frameNumber ++;
|
|
||||||
}
|
|
||||||
|
|
||||||
wasTOF = jobExec.isTOF;
|
|
||||||
wasEOF = jobExec.isEOF;
|
|
||||||
|
|
||||||
int jobY = TOP_MARGIN + frameNumber * traceWidth;
|
|
||||||
int jobStartX = LEFT_MARGIN + (int)((jobExec.start - startOfFrame) * pixelsPerSecond);
|
|
||||||
int jobWidth = (int)( (jobExec.stop - jobExec.start) * pixelsPerSecond);
|
|
||||||
|
|
||||||
g2d.setPaint(Color.BLACK);
|
|
||||||
g2d.drawString ( String.format("%8.3f", startOfFrame), 30, jobY + traceWidth/2);
|
|
||||||
g2d.setPaint( idToColorMap.getColor( jobExec.id ) );
|
|
||||||
g2d.fillRect(jobStartX, jobY, jobWidth, traceWidth-2);
|
|
||||||
|
|
||||||
} // for
|
|
||||||
} // doDrawing
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void paintComponent(Graphics g) {
|
|
||||||
super.paintComponent(g);
|
|
||||||
image = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_RGB);
|
|
||||||
Graphics2D g2 = image.createGraphics();
|
|
||||||
doDrawing(g2);
|
|
||||||
g.drawImage(image, 0, 0, this);
|
|
||||||
g2.dispose();
|
|
||||||
}
|
|
||||||
} // class TraceViewCanvas
|
|
||||||
|
|
||||||
class TraceViewInputToolBar extends JToolBar implements ActionListener {
|
|
||||||
|
|
||||||
private TraceViewCanvas traceView;
|
|
||||||
private JTextField frameDurationField;
|
|
||||||
|
|
||||||
public TraceViewInputToolBar (TraceViewCanvas tv) {
|
|
||||||
traceView = tv;
|
|
||||||
add( new JLabel(" Frame Size: "));
|
|
||||||
frameDurationField = new JTextField(15);
|
|
||||||
frameDurationField.setText( String.format("%8.4f", traceView.getFrameDuration()) );
|
|
||||||
add(frameDurationField);
|
|
||||||
|
|
||||||
JButton setButton = new JButton("Set");
|
|
||||||
setButton.addActionListener(this);
|
|
||||||
setButton.setActionCommand("setFrameSize");
|
|
||||||
setButton.setToolTipText("Set frame size in seconds.");
|
|
||||||
add(setButton);
|
|
||||||
}
|
|
||||||
public void actionPerformed(ActionEvent event) {
|
|
||||||
String s = event.getActionCommand();
|
|
||||||
switch (s) {
|
|
||||||
case "setFrameSize":
|
|
||||||
double newFrameSize = 0.0;
|
|
||||||
try {
|
|
||||||
newFrameSize = Double.parseDouble( frameDurationField.getText() );
|
|
||||||
} catch ( NumberFormatException e) {
|
|
||||||
frameDurationField.setText( String.format("%8.4f", traceView.getFrameDuration()) );
|
|
||||||
}
|
|
||||||
if ( newFrameSize > 0.0) {
|
|
||||||
traceView.setFrameDuration( newFrameSize );
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
System.out.println("Unknown Action Command:" + s);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} // class TraceViewInputToolBar
|
|
||||||
|
|
||||||
class TraceViewOutputToolBar extends JToolBar {
|
|
||||||
private JTextField IDField;
|
|
||||||
private JTextField frameNumberField;
|
|
||||||
private JTextField subFrameTimeField;
|
|
||||||
|
|
||||||
public TraceViewOutputToolBar () {
|
|
||||||
|
|
||||||
add( new JLabel(" Job ID: "));
|
|
||||||
IDField = new JTextField(15);
|
|
||||||
IDField.setEditable(false);
|
|
||||||
IDField.setText( "");
|
|
||||||
add(IDField);
|
|
||||||
|
|
||||||
add( new JLabel(" Frame Number: "));
|
|
||||||
frameNumberField = new JTextField(15);
|
|
||||||
frameNumberField.setEditable(false);
|
|
||||||
frameNumberField.setText( "0");
|
|
||||||
add(frameNumberField);
|
|
||||||
|
|
||||||
add( new JLabel(" Subframe Time: "));
|
|
||||||
subFrameTimeField = new JTextField(15);
|
|
||||||
subFrameTimeField.setEditable(false);
|
|
||||||
subFrameTimeField.setText( "0.00");
|
|
||||||
add(subFrameTimeField);
|
|
||||||
}
|
|
||||||
public void setJobID(String id) {
|
|
||||||
IDField.setText( id );
|
|
||||||
}
|
|
||||||
public void setFrameNumber(int fn) {
|
|
||||||
frameNumberField.setText( String.format("%d", fn));
|
|
||||||
}
|
|
||||||
public void setSubFrameTime(double time) {
|
|
||||||
subFrameTimeField.setText( String.format("%8.4f", time));
|
|
||||||
}
|
|
||||||
} // class TraceViewOutputToolBar
|
|
||||||
|
|
||||||
class TraceViewMenuBar extends JMenuBar implements ActionListener {
|
|
||||||
|
|
||||||
private TraceViewCanvas traceView;
|
|
||||||
|
|
||||||
public TraceViewMenuBar(TraceViewCanvas tv) {
|
|
||||||
traceView = tv;
|
|
||||||
|
|
||||||
JMenu fileMenu = new JMenu("File");
|
|
||||||
JMenuItem fileMenuExit = new JMenuItem("Exit");
|
|
||||||
fileMenuExit.setActionCommand("exit");
|
|
||||||
fileMenuExit.addActionListener(this);
|
|
||||||
fileMenu.add(fileMenuExit);
|
|
||||||
add(fileMenu);
|
|
||||||
|
|
||||||
JMenu optionsMenu = new JMenu("Options");
|
|
||||||
JMenu traceSizeMenu = new JMenu("TraceSize");
|
|
||||||
JMenuItem traceSizeMenuIncrease = new JMenuItem("Increase Trace Width");
|
|
||||||
traceSizeMenuIncrease.setActionCommand("increase-trace_width");
|
|
||||||
KeyStroke ctrlPlus = KeyStroke.getKeyStroke('P', InputEvent.CTRL_MASK );
|
|
||||||
traceSizeMenuIncrease.setAccelerator(ctrlPlus);
|
|
||||||
traceSizeMenuIncrease.addActionListener(this);
|
|
||||||
traceSizeMenu.add(traceSizeMenuIncrease);
|
|
||||||
JMenuItem traceSizeMenuDecrease = new JMenuItem("Decrease Trace Width");
|
|
||||||
traceSizeMenuDecrease.setActionCommand("decrease-trace_width");
|
|
||||||
KeyStroke ctrlMinus = KeyStroke.getKeyStroke('-', InputEvent.CTRL_MASK);
|
|
||||||
traceSizeMenuDecrease.setAccelerator(ctrlMinus);
|
|
||||||
traceSizeMenuDecrease.addActionListener(this);
|
|
||||||
traceSizeMenu.add(traceSizeMenuDecrease);
|
|
||||||
optionsMenu.add(traceSizeMenu);
|
|
||||||
add(optionsMenu);
|
|
||||||
|
|
||||||
}
|
|
||||||
public void actionPerformed(ActionEvent e) {
|
|
||||||
String s = e.getActionCommand();
|
|
||||||
switch (s) {
|
|
||||||
case "increase-trace_width":
|
|
||||||
traceView.increaseTraceWidth();
|
|
||||||
break;
|
|
||||||
case "decrease-trace_width":
|
|
||||||
traceView.decreaseTraceWidth();
|
|
||||||
break;
|
|
||||||
case "exit":
|
|
||||||
System.exit(0);
|
|
||||||
default:
|
|
||||||
System.out.println("Unknown Action Command:" + s);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} // class TraceViewMenuBar
|
|
||||||
|
|
||||||
class TraceViewWindow extends JFrame {
|
|
||||||
|
|
||||||
public TraceViewWindow( ArrayList<JobExecutionEvent> jobExecList ) {
|
|
||||||
TraceViewOutputToolBar outputToolBar = new TraceViewOutputToolBar();
|
|
||||||
TraceViewCanvas traceView = new TraceViewCanvas( jobExecList, outputToolBar);
|
|
||||||
|
|
||||||
TraceViewMenuBar menuBar = new TraceViewMenuBar(traceView);
|
|
||||||
setJMenuBar(menuBar);
|
|
||||||
|
|
||||||
TraceViewInputToolBar nToolBar = new TraceViewInputToolBar( traceView );
|
|
||||||
add(nToolBar, BorderLayout.NORTH);
|
|
||||||
|
|
||||||
JScrollPane scrollPane = new JScrollPane( traceView );
|
|
||||||
scrollPane.setPreferredSize(new Dimension(800, 400));
|
|
||||||
|
|
||||||
JPanel tracePanel = new JPanel();
|
|
||||||
tracePanel.setPreferredSize(new Dimension(800, 400));
|
|
||||||
tracePanel.add(scrollPane);
|
|
||||||
tracePanel.setLayout(new BoxLayout(tracePanel, BoxLayout.X_AXIS));
|
|
||||||
|
|
||||||
JPanel mainPanel = new JPanel();
|
|
||||||
mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.Y_AXIS));
|
|
||||||
mainPanel.add(tracePanel);
|
|
||||||
|
|
||||||
add(outputToolBar, BorderLayout.SOUTH);
|
|
||||||
|
|
||||||
setTitle("JobPerf");
|
|
||||||
setSize(800, 500);
|
|
||||||
add(mainPanel);
|
|
||||||
pack();
|
|
||||||
setVisible(true);
|
|
||||||
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
|
||||||
setFocusable(true);
|
|
||||||
setVisible(true);
|
|
||||||
|
|
||||||
traceView.repaint();
|
|
||||||
}
|
|
||||||
} // class TraceViewWindow
|
|
||||||
|
|
||||||
class Interval {
|
|
||||||
public double start;
|
|
||||||
public double stop;
|
|
||||||
public Interval( double begin, double end) {
|
|
||||||
start = begin;
|
|
||||||
stop = end;
|
|
||||||
}
|
|
||||||
public double getDuration() {
|
|
||||||
return stop - start;
|
|
||||||
}
|
|
||||||
} // Interval
|
|
||||||
|
|
||||||
class RunRegistry {
|
|
||||||
ArrayList<Interval> intervalList;
|
|
||||||
|
|
||||||
public RunRegistry() {
|
|
||||||
intervalList = new ArrayList<Interval>();
|
|
||||||
}
|
|
||||||
void addSample(double start, double stop) {
|
|
||||||
Interval interval = new Interval(start, stop);
|
|
||||||
intervalList.add(interval);
|
|
||||||
}
|
|
||||||
double getMeanDuration() {
|
|
||||||
double mean = 0.0;
|
|
||||||
int N = intervalList.size();
|
|
||||||
if (N > 0) {
|
|
||||||
double sum = 0.0;
|
|
||||||
for (Interval interval : intervalList ) {
|
|
||||||
sum += interval.getDuration();
|
|
||||||
}
|
|
||||||
mean = sum / N;
|
|
||||||
}
|
|
||||||
return mean;
|
|
||||||
}
|
|
||||||
double getStdDev() {
|
|
||||||
double stddev = 0.0;
|
|
||||||
int N = intervalList.size();
|
|
||||||
if (N > 0) {
|
|
||||||
double sum = 0.0;
|
|
||||||
double mean = getMeanDuration();
|
|
||||||
for (Interval interval : intervalList ) {
|
|
||||||
double duration = interval.getDuration();
|
|
||||||
double difference = duration - mean;
|
|
||||||
sum += difference * difference;
|
|
||||||
}
|
|
||||||
stddev = Math.sqrt( sum / N );
|
|
||||||
}
|
|
||||||
return stddev;
|
|
||||||
}
|
|
||||||
double getMaxDuration() {
|
|
||||||
double maxDuration = Double.MIN_VALUE;
|
|
||||||
for (Interval interval : intervalList ) {
|
|
||||||
double duration = interval.getDuration();
|
|
||||||
if (duration > maxDuration) {
|
|
||||||
maxDuration = duration;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return maxDuration;
|
|
||||||
}
|
|
||||||
double getMinDuration() {
|
|
||||||
double minDuration = Double.MAX_VALUE;
|
|
||||||
for (Interval interval : intervalList ) {
|
|
||||||
double duration = interval.getDuration();
|
|
||||||
if (duration < minDuration) {
|
|
||||||
minDuration = duration;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return minDuration;
|
|
||||||
}
|
|
||||||
} // RunRegistry
|
|
||||||
|
|
||||||
class StatisticsRecord {
|
|
||||||
public String id;
|
|
||||||
public double meanValue;
|
|
||||||
public double stddev;
|
|
||||||
public double maxValue;
|
|
||||||
public double minValue;
|
|
||||||
public StatisticsRecord( String s, double mean, double sd, double min, double max) {
|
|
||||||
id = s;
|
|
||||||
meanValue = mean;
|
|
||||||
stddev = sd;
|
|
||||||
minValue = min;
|
|
||||||
maxValue = max;
|
|
||||||
}
|
|
||||||
} // StatisticsRecord
|
|
||||||
|
|
||||||
class CompareByID implements Comparator<StatisticsRecord> {
|
|
||||||
public int compare(StatisticsRecord a, StatisticsRecord b) {
|
|
||||||
return a.id.compareTo(b.id);
|
|
||||||
}
|
|
||||||
} // CompareByID
|
|
||||||
|
|
||||||
class CompareByMeanValue implements Comparator<StatisticsRecord> {
|
|
||||||
public int compare(StatisticsRecord a, StatisticsRecord b) {
|
|
||||||
if ( a.meanValue < b.meanValue) return -1;
|
|
||||||
if ( a.meanValue > b.meanValue) return 1;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
} // CompareByMeanValue
|
|
||||||
|
|
||||||
class CompareByStdDev implements Comparator<StatisticsRecord> {
|
|
||||||
public int compare(StatisticsRecord a, StatisticsRecord b) {
|
|
||||||
if ( a.stddev < b.stddev) return -1;
|
|
||||||
if ( a.stddev > b.stddev) return 1;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
} // CompareByStdDev
|
|
||||||
|
|
||||||
class CompareByMaxDuration implements Comparator<StatisticsRecord> {
|
|
||||||
public int compare(StatisticsRecord a, StatisticsRecord b) {
|
|
||||||
if ( a.maxValue < b.maxValue) return -1;
|
|
||||||
if ( a.maxValue > b.maxValue) return 1;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
} // CompareByMaxDuration
|
|
||||||
|
|
||||||
class CompareByMinDuration implements Comparator<StatisticsRecord> {
|
|
||||||
public int compare(StatisticsRecord a, StatisticsRecord b) {
|
|
||||||
if ( a.minValue < b.minValue) return -1;
|
|
||||||
if ( a.minValue > b.minValue) return 1;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
} // CompareByMinDuration
|
|
||||||
|
|
||||||
class JobStats {
|
|
||||||
|
|
||||||
enum SortCriterion {
|
|
||||||
ID {
|
|
||||||
@Override
|
|
||||||
public String toString() { return "Identifier"; }
|
|
||||||
},
|
|
||||||
MEAN {
|
|
||||||
@Override
|
|
||||||
public String toString() { return "Mean Value"; }
|
|
||||||
},
|
|
||||||
STDDEV {
|
|
||||||
@Override
|
|
||||||
public String toString() { return "Standard Deviation"; }
|
|
||||||
},
|
|
||||||
MAX {
|
|
||||||
@Override
|
|
||||||
public String toString() { return "Maximum Value"; }
|
|
||||||
},
|
|
||||||
MIN {
|
|
||||||
@Override
|
|
||||||
public String toString() { return "Minimum Value"; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SortCriterion currentSortCriterion = SortCriterion.MEAN;
|
|
||||||
ArrayList<StatisticsRecord> jobStatisticsList;
|
|
||||||
|
|
||||||
public JobStats( ArrayList<JobExecutionEvent> jobExecList ) {
|
|
||||||
|
|
||||||
Map<String, RunRegistry> runRegistryMap
|
|
||||||
= new HashMap<String, RunRegistry>();
|
|
||||||
|
|
||||||
for (JobExecutionEvent jobExec : jobExecList ) {
|
|
||||||
RunRegistry runRegistry = runRegistryMap.get(jobExec.id);
|
|
||||||
if (runRegistry != null) {
|
|
||||||
runRegistry.addSample(jobExec.start, jobExec.stop);
|
|
||||||
} else {
|
|
||||||
runRegistry = new RunRegistry();
|
|
||||||
runRegistry.addSample(jobExec.start, jobExec.stop);
|
|
||||||
runRegistryMap.put(jobExec.id, runRegistry);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
jobStatisticsList = new ArrayList<StatisticsRecord>();
|
|
||||||
|
|
||||||
for (Map.Entry<String, RunRegistry> entry : runRegistryMap.entrySet()) {
|
|
||||||
String id = entry.getKey();
|
|
||||||
RunRegistry register = entry.getValue();
|
|
||||||
double mean = register.getMeanDuration();
|
|
||||||
double stddev = register.getStdDev();
|
|
||||||
double min = register.getMinDuration();
|
|
||||||
double max = register.getMaxDuration();
|
|
||||||
|
|
||||||
jobStatisticsList.add( new StatisticsRecord(id, mean, stddev, min, max));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sort by MeanDuration in descending order.
|
|
||||||
public void SortByID() {
|
|
||||||
Collections.sort( jobStatisticsList, new CompareByID());
|
|
||||||
currentSortCriterion = SortCriterion.ID;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sort by MeanDuration in descending order.
|
|
||||||
public void SortByMeanValue() {
|
|
||||||
Collections.sort( jobStatisticsList, Collections.reverseOrder( new CompareByMeanValue()));
|
|
||||||
currentSortCriterion = SortCriterion.MEAN;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sort by Standard Deviation of duration in descending order.
|
|
||||||
public void SortByStdDev() {
|
|
||||||
Collections.sort( jobStatisticsList, Collections.reverseOrder( new CompareByStdDev()));
|
|
||||||
currentSortCriterion = SortCriterion.STDDEV;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sort by MaxDuration in descending order.
|
|
||||||
public void SortByMaxValue() {
|
|
||||||
Collections.sort( jobStatisticsList, Collections.reverseOrder( new CompareByMaxDuration()));
|
|
||||||
currentSortCriterion = SortCriterion.MAX;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sort by MinDuration in descending order.
|
|
||||||
public void SortByMinValue() {
|
|
||||||
Collections.sort( jobStatisticsList, Collections.reverseOrder( new CompareByMinDuration()));
|
|
||||||
currentSortCriterion = SortCriterion.MIN;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void write() {
|
|
||||||
System.out.println(" [Job Duration Statistics Sorted by " + currentSortCriterion +"]");
|
|
||||||
System.out.println("----------------------------------------------------------------------");
|
|
||||||
System.out.println(" Job Id Mean Duration Std Dev Min Duration Max Duration");
|
|
||||||
System.out.println("---------- -------------- -------------- -------------- --------------");
|
|
||||||
for (StatisticsRecord jobStatisticsRecord : jobStatisticsList ) {
|
|
||||||
System.out.println( String.format("%10s %14.6f %14.6f %14.6f %14.6f",
|
|
||||||
jobStatisticsRecord.id,
|
|
||||||
jobStatisticsRecord.meanValue,
|
|
||||||
jobStatisticsRecord.stddev,
|
|
||||||
jobStatisticsRecord.minValue,
|
|
||||||
jobStatisticsRecord.maxValue));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} // JobStats
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class JobPerf is an application that renders time line data from a Trick based
|
||||||
|
simulation and generates run-time statistics reports for the simulation jobs.
|
||||||
|
It can be run with or without a GUI.
|
||||||
|
*/
|
||||||
public class JobPerf extends JFrame {
|
public class JobPerf extends JFrame {
|
||||||
ArrayList<JobExecutionEvent> jobExecEvtList;
|
ArrayList<JobExecutionEvent> jobExecEvtList;
|
||||||
JobStats jobStats;
|
JobStats jobStats;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
* @param args the command line arguments.
|
||||||
|
*/
|
||||||
public JobPerf( String[] args ) {
|
public JobPerf( String[] args ) {
|
||||||
TraceViewWindow traceViewWindow;
|
TraceViewWindow traceViewWindow;
|
||||||
boolean interactive = true;
|
boolean interactive = true;
|
||||||
@ -782,7 +68,7 @@ public class JobPerf extends JFrame {
|
|||||||
++ii;
|
++ii;
|
||||||
} // while
|
} // while
|
||||||
|
|
||||||
jobExecEvtList = JobExecutionEventList(fileName);
|
jobExecEvtList = getJobExecutionEventList(fileName);
|
||||||
jobStats = new JobStats(jobExecEvtList);
|
jobStats = new JobStats(jobExecEvtList);
|
||||||
if (printReport) {
|
if (printReport) {
|
||||||
if (sortOrder == JobStats.SortCriterion.ID ) jobStats.SortByID();
|
if (sortOrder == JobStats.SortCriterion.ID ) jobStats.SortByID();
|
||||||
@ -797,33 +83,38 @@ public class JobPerf extends JFrame {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Print the usage instructions to the terminal.
|
||||||
|
*/
|
||||||
private static void printHelpText() {
|
private static void printHelpText() {
|
||||||
System.out.println(
|
System.out.println(
|
||||||
"----------------------------------------------------------------------\n"
|
"----------------------------------------------------------------------\n"
|
||||||
+ "usage: trick-jperf [options] <file-name>\n"
|
+ "usage: trick-jperf [options] <file-name>\n\n"
|
||||||
+ "options: \n"
|
+ "options: \n"
|
||||||
+ "-h, --help\n"
|
+ "-h, --help\n"
|
||||||
+ " Print this help text and exit."
|
+ " Print this help text and exit.\n"
|
||||||
+ "-x, --nogui\n"
|
+ "-x, --nogui\n"
|
||||||
+ " Don't run as a GUI application. Command line only."
|
+ " Don't run as a GUI application. Command line only.\n"
|
||||||
+ "-p, --report\n"
|
+ "-p, --report\n"
|
||||||
+ " Write sorted job statics report to the terminal."
|
+ " Write sorted job statics report to the terminal.\n"
|
||||||
+ "-s0, --sort=id\n"
|
+ "-s0, --sort=id\n"
|
||||||
+ " Sort job statistics by identifier."
|
+ " Sort job statistics by identifier.\n"
|
||||||
+ "-s1, --sort=mean [default]\n"
|
+ "-s1, --sort=mean [default]\n"
|
||||||
+ " Sort job statistics by mean duration."
|
+ " Sort job statistics by mean duration.\n"
|
||||||
+ "-s2, --sort=stddev\n"
|
+ "-s2, --sort=stddev\n"
|
||||||
+ " Sort job statistics by standard deviation of duration."
|
+ " Sort job statistics by standard deviation of duration.\n"
|
||||||
+ "-s3, --sort=min\n"
|
+ "-s3, --sort=min\n"
|
||||||
+ " Sort job statistics by minimum duration."
|
+ " Sort job statistics by minimum duration.\n"
|
||||||
+ "-s4, --sort=max\n"
|
+ "-s4, --sort=max\n"
|
||||||
+ " Sort job statistics by maximum duration."
|
+ " Sort job statistics by maximum duration.\n"
|
||||||
+ "----------------------------------------------------------------------\n"
|
+ "----------------------------------------------------------------------\n"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read the timeline file.
|
/**
|
||||||
private ArrayList<JobExecutionEvent> JobExecutionEventList( String fileName ) {
|
* Read the timeline file, resulting in a ArrayList<JobExecutionEvent>.
|
||||||
|
*/
|
||||||
|
private ArrayList<JobExecutionEvent> getJobExecutionEventList( String fileName ) {
|
||||||
String line;
|
String line;
|
||||||
String field[];
|
String field[];
|
||||||
|
|
||||||
@ -858,8 +149,10 @@ public class JobPerf extends JFrame {
|
|||||||
return jobExecEvtList;
|
return jobExecEvtList;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Entry point for the Java application.
|
||||||
|
*/
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
JobPerf jobPerf = new JobPerf( args );
|
JobPerf jobPerf = new JobPerf( args );
|
||||||
} // main
|
}
|
||||||
|
}
|
||||||
} // class JobPerf
|
|
||||||
|
184
trick_source/java/src/main/java/trick/jobperf/JobStats.java
Normal file
184
trick_source/java/src/main/java/trick/jobperf/JobStats.java
Normal file
@ -0,0 +1,184 @@
|
|||||||
|
package trick.jobperf;
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class CompareByID compares two StatisticsRecord's by id.
|
||||||
|
*/
|
||||||
|
class CompareByID implements Comparator<StatisticsRecord> {
|
||||||
|
public int compare(StatisticsRecord a, StatisticsRecord b) {
|
||||||
|
return a.id.compareTo(b.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Class CompareByMeanValue compares two StatisticsRecord's by meanValue.
|
||||||
|
*/
|
||||||
|
class CompareByMeanValue implements Comparator<StatisticsRecord> {
|
||||||
|
public int compare(StatisticsRecord a, StatisticsRecord b) {
|
||||||
|
if ( a.meanValue < b.meanValue) return -1;
|
||||||
|
if ( a.meanValue > b.meanValue) return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Class CompareByStdDev compares two StatisticsRecord's by stddev.
|
||||||
|
*/
|
||||||
|
class CompareByStdDev implements Comparator<StatisticsRecord> {
|
||||||
|
public int compare(StatisticsRecord a, StatisticsRecord b) {
|
||||||
|
if ( a.stddev < b.stddev) return -1;
|
||||||
|
if ( a.stddev > b.stddev) return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Class CompareByMaxDuration compares two StatisticsRecord's by maxValue.
|
||||||
|
*/
|
||||||
|
class CompareByMaxDuration implements Comparator<StatisticsRecord> {
|
||||||
|
public int compare(StatisticsRecord a, StatisticsRecord b) {
|
||||||
|
if ( a.maxValue < b.maxValue) return -1;
|
||||||
|
if ( a.maxValue > b.maxValue) return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Class CompareByMinDuration compares two StatisticsRecord's by minValue.
|
||||||
|
*/
|
||||||
|
class CompareByMinDuration implements Comparator<StatisticsRecord> {
|
||||||
|
public int compare(StatisticsRecord a, StatisticsRecord b) {
|
||||||
|
if ( a.minValue < b.minValue) return -1;
|
||||||
|
if ( a.minValue > b.minValue) return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class JobStats represents the statistics, i.e., mean, std deviation, max value,
|
||||||
|
* and min value of the run-duration of each of the Trick jobs in jobExecList. The
|
||||||
|
* statistic records can be sorted by any of the statistics, and by the job id,
|
||||||
|
* prior to being written as a report.
|
||||||
|
*/
|
||||||
|
public class JobStats {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enum SortCriterion enumerates the valid ways that JobStats records can be
|
||||||
|
* sorted.
|
||||||
|
*/
|
||||||
|
enum SortCriterion {
|
||||||
|
ID {
|
||||||
|
@Override
|
||||||
|
public String toString() { return "Identifier"; }
|
||||||
|
},
|
||||||
|
MEAN {
|
||||||
|
@Override
|
||||||
|
public String toString() { return "Mean Value"; }
|
||||||
|
},
|
||||||
|
STDDEV {
|
||||||
|
@Override
|
||||||
|
public String toString() { return "Standard Deviation"; }
|
||||||
|
},
|
||||||
|
MAX {
|
||||||
|
@Override
|
||||||
|
public String toString() { return "Maximum Value"; }
|
||||||
|
},
|
||||||
|
MIN {
|
||||||
|
@Override
|
||||||
|
public String toString() { return "Minimum Value"; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SortCriterion currentSortCriterion = SortCriterion.MEAN;
|
||||||
|
ArrayList<StatisticsRecord> jobStatisticsList;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
* @param jobExecList - the timeline data.
|
||||||
|
*/
|
||||||
|
public JobStats( ArrayList<JobExecutionEvent> jobExecList ) {
|
||||||
|
|
||||||
|
Map<String, RunRegistry> runRegistryMap
|
||||||
|
= new HashMap<String, RunRegistry>();
|
||||||
|
|
||||||
|
for (JobExecutionEvent jobExec : jobExecList ) {
|
||||||
|
RunRegistry runRegistry = runRegistryMap.get(jobExec.id);
|
||||||
|
if (runRegistry != null) {
|
||||||
|
runRegistry.addTimeSpan(jobExec.start, jobExec.stop);
|
||||||
|
} else {
|
||||||
|
runRegistry = new RunRegistry();
|
||||||
|
runRegistry.addTimeSpan(jobExec.start, jobExec.stop);
|
||||||
|
runRegistryMap.put(jobExec.id, runRegistry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
jobStatisticsList = new ArrayList<StatisticsRecord>();
|
||||||
|
|
||||||
|
for (Map.Entry<String, RunRegistry> entry : runRegistryMap.entrySet()) {
|
||||||
|
String id = entry.getKey();
|
||||||
|
RunRegistry runRegistry = entry.getValue();
|
||||||
|
double mean = runRegistry.getMeanDuration();
|
||||||
|
double stddev = runRegistry.getStdDev();
|
||||||
|
double min = runRegistry.getMinDuration();
|
||||||
|
double max = runRegistry.getMaxDuration();
|
||||||
|
|
||||||
|
jobStatisticsList.add( new StatisticsRecord(id, mean, stddev, min, max));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sort by mean duration in descending order.
|
||||||
|
*/
|
||||||
|
public void SortByID() {
|
||||||
|
Collections.sort( jobStatisticsList, new CompareByID());
|
||||||
|
currentSortCriterion = SortCriterion.ID;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sort by mean duration in descending order.
|
||||||
|
*/
|
||||||
|
public void SortByMeanValue() {
|
||||||
|
Collections.sort( jobStatisticsList, Collections.reverseOrder( new CompareByMeanValue()));
|
||||||
|
currentSortCriterion = SortCriterion.MEAN;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sort by standard deviation of duration in descending order.
|
||||||
|
*/
|
||||||
|
public void SortByStdDev() {
|
||||||
|
Collections.sort( jobStatisticsList, Collections.reverseOrder( new CompareByStdDev()));
|
||||||
|
currentSortCriterion = SortCriterion.STDDEV;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sort by maximum duration in descending order.
|
||||||
|
*/
|
||||||
|
public void SortByMaxValue() {
|
||||||
|
Collections.sort( jobStatisticsList, Collections.reverseOrder( new CompareByMaxDuration()));
|
||||||
|
currentSortCriterion = SortCriterion.MAX;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sort by minimum duration in descending order.
|
||||||
|
*/
|
||||||
|
public void SortByMinValue() {
|
||||||
|
Collections.sort( jobStatisticsList, Collections.reverseOrder( new CompareByMinDuration()));
|
||||||
|
currentSortCriterion = SortCriterion.MIN;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Write a text report to System.out.
|
||||||
|
*/
|
||||||
|
public void write() {
|
||||||
|
System.out.println(" [Job Duration Statistics Sorted by " + currentSortCriterion +"]");
|
||||||
|
System.out.println("----------------------------------------------------------------------");
|
||||||
|
System.out.println(" Job Id Mean Duration Std Dev Min Duration Max Duration");
|
||||||
|
System.out.println("---------- -------------- -------------- -------------- --------------");
|
||||||
|
for (StatisticsRecord jobStatisticsRecord : jobStatisticsList ) {
|
||||||
|
System.out.println( String.format("%10s %14.6f %14.6f %14.6f %14.6f",
|
||||||
|
jobStatisticsRecord.id,
|
||||||
|
jobStatisticsRecord.meanValue,
|
||||||
|
jobStatisticsRecord.stddev,
|
||||||
|
jobStatisticsRecord.minValue,
|
||||||
|
jobStatisticsRecord.maxValue));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
123
trick_source/java/src/main/java/trick/jobperf/KeyedColorMap.java
Normal file
123
trick_source/java/src/main/java/trick/jobperf/KeyedColorMap.java
Normal file
@ -0,0 +1,123 @@
|
|||||||
|
package trick.jobperf;
|
||||||
|
|
||||||
|
import java.awt.*;
|
||||||
|
import java.io.*;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class KeyedColorMap associates identifiers with unique RGB colors.
|
||||||
|
*/
|
||||||
|
public class KeyedColorMap {
|
||||||
|
private Map<String, Color> colorMap;
|
||||||
|
int minLuminance;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*/
|
||||||
|
public KeyedColorMap() {
|
||||||
|
colorMap = new HashMap<String, Color>();
|
||||||
|
minLuminance = 30;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate a random color, that's not too dark.
|
||||||
|
* @ return the generated color.
|
||||||
|
*/
|
||||||
|
private Color generateColor () {
|
||||||
|
Random rand = new Random();
|
||||||
|
boolean found = false;
|
||||||
|
int R = 0;
|
||||||
|
int G = 0;
|
||||||
|
int B = 0;
|
||||||
|
|
||||||
|
while (!found) {
|
||||||
|
R = rand.nextInt(256);
|
||||||
|
G = rand.nextInt(256);
|
||||||
|
B = rand.nextInt(256);
|
||||||
|
found = true;
|
||||||
|
// Reference: https://www.w3.org/TR/AERT/#color-contrast
|
||||||
|
double luminance = (0.299*R + 0.587*G + 0.114*B);
|
||||||
|
if (luminance < minLuminance ) found = false;
|
||||||
|
}
|
||||||
|
return new Color( R,G,B);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add an identifier, and a generated Color to the KeyedColorMap.
|
||||||
|
* The Color will be generated randomly.
|
||||||
|
* @ param identifier Specifies the key for which a color will be generated.
|
||||||
|
*/
|
||||||
|
public void addKey( String identifier ) {
|
||||||
|
if (!colorMap.containsKey(identifier)) {
|
||||||
|
colorMap.put(identifier, generateColor());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Given an identifier, return its color.
|
||||||
|
* @param identifier the key.
|
||||||
|
* @return the Color associated with the key.
|
||||||
|
*/
|
||||||
|
public Color getColor(String identifier) {
|
||||||
|
return colorMap.get(identifier);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Given a color, return the associated key, otherwise return null.
|
||||||
|
* @param searchColor the Color to search for.
|
||||||
|
* @return the identifier associated with the searchColor.
|
||||||
|
*/
|
||||||
|
public String getKeyOfColor(Color searchColor) {
|
||||||
|
for (Map.Entry<String, Color> entry : colorMap.entrySet()) {
|
||||||
|
String id = entry.getKey();
|
||||||
|
Color color = entry.getValue();
|
||||||
|
if (color.getRGB() == searchColor.getRGB()) {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write the identifier, color key/value pairs of the KeyedColorMap to a file.
|
||||||
|
* @param fileName
|
||||||
|
*/
|
||||||
|
public void writeFile(String fileName) throws IOException {
|
||||||
|
BufferedWriter out = new BufferedWriter( new FileWriter(fileName) );
|
||||||
|
for (Map.Entry<String, Color> entry : colorMap.entrySet()) {
|
||||||
|
String id = entry.getKey();
|
||||||
|
Color color = entry.getValue();
|
||||||
|
String line = String.format(id + "," + color.getRed() +
|
||||||
|
"," + color.getGreen() +
|
||||||
|
"," + color.getBlue() + "\n");
|
||||||
|
out.write(line, 0, line.length());
|
||||||
|
}
|
||||||
|
out.flush();
|
||||||
|
out.close();
|
||||||
|
} // method writeFile
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read identifier, color key-value pairs into the KeyedColorMap from a file.
|
||||||
|
* @param fileName
|
||||||
|
*/
|
||||||
|
public void readFile(String fileName) throws IOException {
|
||||||
|
try {
|
||||||
|
BufferedReader in = new BufferedReader( new FileReader(fileName) );
|
||||||
|
String line;
|
||||||
|
String field[];
|
||||||
|
|
||||||
|
while( (line = in.readLine()) !=null) {
|
||||||
|
field = line.split(",");
|
||||||
|
String id = field[0];
|
||||||
|
int R = Integer.parseInt( field[1]);
|
||||||
|
int G = Integer.parseInt( field[2]);
|
||||||
|
int B = Integer.parseInt( field[3]);
|
||||||
|
colorMap.put(id, new Color(R,G,B));
|
||||||
|
}
|
||||||
|
in.close();
|
||||||
|
} catch ( java.io.FileNotFoundException e ) {
|
||||||
|
System.out.println("File \"" + fileName + "\" not found.\n");
|
||||||
|
}
|
||||||
|
} // method readFile
|
||||||
|
|
||||||
|
} // class KeyedColorMap
|
@ -0,0 +1,73 @@
|
|||||||
|
package trick.jobperf;
|
||||||
|
|
||||||
|
import java.lang.Math;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class RunRegistry represents a list of timeSpan's on which we can calculate
|
||||||
|
* the average (mean), standard deviation, minimum, and maximum of the timeSpans
|
||||||
|
* in the list.
|
||||||
|
*/
|
||||||
|
public class RunRegistry {
|
||||||
|
ArrayList<TimeSpan> timeSpanList;
|
||||||
|
/*
|
||||||
|
* Constructor
|
||||||
|
*/
|
||||||
|
public RunRegistry() {
|
||||||
|
timeSpanList = new ArrayList<TimeSpan>();
|
||||||
|
}
|
||||||
|
void addTimeSpan(double start, double stop) {
|
||||||
|
TimeSpan timeSpan = new TimeSpan(start, stop);
|
||||||
|
timeSpanList.add(timeSpan);
|
||||||
|
}
|
||||||
|
void addTimeSpan(TimeSpan timeSpan) {
|
||||||
|
timeSpanList.add(timeSpan);
|
||||||
|
}
|
||||||
|
double getMeanDuration() {
|
||||||
|
double mean = 0.0;
|
||||||
|
int N = timeSpanList.size();
|
||||||
|
if (N > 0) {
|
||||||
|
double sum = 0.0;
|
||||||
|
for (TimeSpan timeSpan : timeSpanList ) {
|
||||||
|
sum += timeSpan.getDuration();
|
||||||
|
}
|
||||||
|
mean = sum / N;
|
||||||
|
}
|
||||||
|
return mean;
|
||||||
|
}
|
||||||
|
double getStdDev() {
|
||||||
|
double stddev = 0.0;
|
||||||
|
int N = timeSpanList.size();
|
||||||
|
if (N > 0) {
|
||||||
|
double sum = 0.0;
|
||||||
|
double mean = getMeanDuration();
|
||||||
|
for (TimeSpan timeSpan : timeSpanList ) {
|
||||||
|
double duration = timeSpan.getDuration();
|
||||||
|
double difference = duration - mean;
|
||||||
|
sum += difference * difference;
|
||||||
|
}
|
||||||
|
stddev = Math.sqrt( sum / N );
|
||||||
|
}
|
||||||
|
return stddev;
|
||||||
|
}
|
||||||
|
double getMaxDuration() {
|
||||||
|
double maxDuration = Double.MIN_VALUE;
|
||||||
|
for (TimeSpan timeSpan : timeSpanList ) {
|
||||||
|
double duration = timeSpan.getDuration();
|
||||||
|
if (duration > maxDuration) {
|
||||||
|
maxDuration = duration;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return maxDuration;
|
||||||
|
}
|
||||||
|
double getMinDuration() {
|
||||||
|
double minDuration = Double.MAX_VALUE;
|
||||||
|
for (TimeSpan timeSpan : timeSpanList ) {
|
||||||
|
double duration = timeSpan.getDuration();
|
||||||
|
if (duration < minDuration) {
|
||||||
|
minDuration = duration;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return minDuration;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,28 @@
|
|||||||
|
package trick.jobperf;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class StatisticsRecord represents the statistics, i.e., mean, std deviation,
|
||||||
|
* max value, and min value of the run-duration of an identified Trick job.
|
||||||
|
*/
|
||||||
|
public class StatisticsRecord {
|
||||||
|
public String id;
|
||||||
|
public double meanValue;
|
||||||
|
public double stddev;
|
||||||
|
public double maxValue;
|
||||||
|
public double minValue;
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
* @param s - the job identifier.
|
||||||
|
* @param mean - the mean value of job duration.
|
||||||
|
* @param sd - the standard deviation of job duration.
|
||||||
|
* @param min - the minimum value of job duration.
|
||||||
|
* @param max - the maximum value of job duration.
|
||||||
|
*/
|
||||||
|
public StatisticsRecord( String s, double mean, double sd, double min, double max) {
|
||||||
|
id = s;
|
||||||
|
meanValue = mean;
|
||||||
|
stddev = sd;
|
||||||
|
minValue = min;
|
||||||
|
maxValue = max;
|
||||||
|
}
|
||||||
|
}
|
24
trick_source/java/src/main/java/trick/jobperf/TimeSpan.java
Normal file
24
trick_source/java/src/main/java/trick/jobperf/TimeSpan.java
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
package trick.jobperf;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class TimeSpan represents a span of time.
|
||||||
|
*/
|
||||||
|
public class TimeSpan {
|
||||||
|
public double start;
|
||||||
|
public double stop;
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
* @param begin the start time.
|
||||||
|
* @param end the end time.
|
||||||
|
*/
|
||||||
|
public TimeSpan( double begin, double end) {
|
||||||
|
start = begin;
|
||||||
|
stop = end;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @return the stop time minus the start time.
|
||||||
|
*/
|
||||||
|
public double getDuration() {
|
||||||
|
return stop - start;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,281 @@
|
|||||||
|
package trick.jobperf;
|
||||||
|
|
||||||
|
import java.awt.*;
|
||||||
|
import java.awt.event.*;
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
import java.io.*;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.List;
|
||||||
|
import javax.swing.*;
|
||||||
|
import javax.swing.event.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class TraceViewCanvas renders the simulation timeline data stored in
|
||||||
|
* an ArrayList of JobExecutionEvent's [jobExecEvtList]. Information regarding mouse clicks
|
||||||
|
* are sent to the TraceViewOutputToolBar [outputToolBar.]
|
||||||
|
*/
|
||||||
|
public class TraceViewCanvas extends JPanel {
|
||||||
|
|
||||||
|
public static final int MIN_TRACE_WIDTH = 4;
|
||||||
|
public static final int DEFAULT_TRACE_WIDTH = 10;
|
||||||
|
public static final int MAX_TRACE_WIDTH = 30;
|
||||||
|
public static final int LEFT_MARGIN = 100;
|
||||||
|
public static final int RIGHT_MARGIN = 100;
|
||||||
|
public static final int TOP_MARGIN = 20;
|
||||||
|
public static final int BOTTOM_MARGIN = 20;
|
||||||
|
|
||||||
|
private int traceWidth;
|
||||||
|
private double frameDuration;
|
||||||
|
private List<JobExecutionEvent> jobExecList;
|
||||||
|
private KeyedColorMap idToColorMap;
|
||||||
|
private BufferedImage image;
|
||||||
|
private TraceViewOutputToolBar sToolBar;
|
||||||
|
private Cursor crossHairCursor;
|
||||||
|
private Cursor defaultCursor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
* @param jobExecEvtList the job time line data.
|
||||||
|
* @param outputToolBar the toolbar to which data is to be sent for display.
|
||||||
|
*/
|
||||||
|
public TraceViewCanvas( ArrayList<JobExecutionEvent> jobExecEvtList, TraceViewOutputToolBar outputToolBar ) {
|
||||||
|
|
||||||
|
traceWidth = DEFAULT_TRACE_WIDTH;
|
||||||
|
frameDuration = 1.0;
|
||||||
|
image = null;
|
||||||
|
sToolBar = outputToolBar;
|
||||||
|
jobExecList = jobExecEvtList;
|
||||||
|
crossHairCursor = new Cursor( Cursor.CROSSHAIR_CURSOR );
|
||||||
|
defaultCursor = new Cursor( Cursor.DEFAULT_CURSOR );
|
||||||
|
double smallestStart = Double.MAX_VALUE;
|
||||||
|
double largestStop = -Double.MAX_VALUE;
|
||||||
|
|
||||||
|
try {
|
||||||
|
idToColorMap = new KeyedColorMap();
|
||||||
|
File colorfile = new File("IdToColors.txt");
|
||||||
|
if (colorfile.exists()) {
|
||||||
|
idToColorMap.readFile("IdToColors.txt");
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean wasTOF = false;
|
||||||
|
double startOfFrame = 0.0;
|
||||||
|
double lastStartOfFrame = 0.0;
|
||||||
|
double frameSizeSum = 0.0;
|
||||||
|
int frameNumber = 0;
|
||||||
|
int frameSizeCount = 0;
|
||||||
|
|
||||||
|
for (JobExecutionEvent jobExec : jobExecList ) {
|
||||||
|
if (jobExec.start < smallestStart) smallestStart = jobExec.start;
|
||||||
|
if (jobExec.stop > largestStop) largestStop = jobExec.stop;
|
||||||
|
// Calculate the average frame size.
|
||||||
|
if (!wasTOF && jobExec.isTOF) {
|
||||||
|
startOfFrame = jobExec.start;
|
||||||
|
if (frameNumber > 0) {
|
||||||
|
double frameSize = (startOfFrame - lastStartOfFrame);
|
||||||
|
frameSizeSum += frameSize;
|
||||||
|
frameSizeCount ++;
|
||||||
|
}
|
||||||
|
lastStartOfFrame = startOfFrame;
|
||||||
|
frameNumber++;
|
||||||
|
}
|
||||||
|
wasTOF = jobExec.isTOF;
|
||||||
|
idToColorMap.addKey(jobExec.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculate the average frame size.
|
||||||
|
frameDuration = frameSizeSum / frameSizeCount;
|
||||||
|
idToColorMap.writeFile("IdToColors.txt");
|
||||||
|
|
||||||
|
System.out.println("File loaded.\n");
|
||||||
|
} catch ( java.io.FileNotFoundException e ) {
|
||||||
|
System.out.println("File not found.\n");
|
||||||
|
System.exit(0);
|
||||||
|
} catch ( java.io.IOException e ) {
|
||||||
|
System.out.println("IO Exception.\n");
|
||||||
|
System.exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int preferredHeight = traceWidth * (int)((largestStop - smallestStart) / frameDuration) + TOP_MARGIN;
|
||||||
|
setPreferredSize(new Dimension(500, preferredHeight));
|
||||||
|
|
||||||
|
ViewListener viewListener = new ViewListener();
|
||||||
|
addMouseListener(viewListener);
|
||||||
|
addMouseMotionListener(viewListener);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the current working frame size used for rendering. Initially this
|
||||||
|
* is estimated from the timeline data, but it can be set to the actual
|
||||||
|
* realtime frame size of the user's sim.
|
||||||
|
*/
|
||||||
|
public double getFrameDuration() {
|
||||||
|
return frameDuration;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Set the frame size to be used for rendering the timeline data.
|
||||||
|
* @param duration the frame size.
|
||||||
|
*/
|
||||||
|
public void setFrameDuration(double duration) {
|
||||||
|
frameDuration = duration;
|
||||||
|
repaint();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Increment the width to be used to render the job traces if the current
|
||||||
|
* trace width is less than MAX_TRACE_WIDTH.
|
||||||
|
*/
|
||||||
|
public void increaseTraceWidth() {
|
||||||
|
if (traceWidth < MAX_TRACE_WIDTH) {
|
||||||
|
traceWidth ++;
|
||||||
|
repaint();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decrement the width to be used to render the job traces if the current
|
||||||
|
* trace width is greater than MIN_TRACE_WIDTH.
|
||||||
|
*/
|
||||||
|
public void decreaseTraceWidth() {
|
||||||
|
if (traceWidth > MIN_TRACE_WIDTH) {
|
||||||
|
traceWidth --;
|
||||||
|
repaint();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return true if the trace rectangle contains the point <x,y>, otherwise
|
||||||
|
* false.
|
||||||
|
*/
|
||||||
|
private boolean traceRectContains(int x, int y) {
|
||||||
|
int traceRectXMax = getWidth() - RIGHT_MARGIN;
|
||||||
|
if ( x < (LEFT_MARGIN)) return false;
|
||||||
|
if ( x > (traceRectXMax)) return false;
|
||||||
|
if ( y < TOP_MARGIN) return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @return true if the time rectangle contains the point <x,y>, otherwise
|
||||||
|
* false.
|
||||||
|
*/
|
||||||
|
private boolean timeRectContains(int x, int y) {
|
||||||
|
int timeRectXMin = 30;
|
||||||
|
int timeRectXMax = LEFT_MARGIN;
|
||||||
|
if ( x < 30 ) return false;
|
||||||
|
if ( x > LEFT_MARGIN) return false;
|
||||||
|
if ( y < TOP_MARGIN) return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class ViewListener monitors mouse activity within the TraceViewCanvas.
|
||||||
|
*/
|
||||||
|
private class ViewListener extends MouseInputAdapter {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseReleased(MouseEvent e) {
|
||||||
|
int x = e.getX();
|
||||||
|
int y = e.getY();
|
||||||
|
Color color = new Color ( image.getRGB(x,y) );
|
||||||
|
|
||||||
|
String id = idToColorMap.getKeyOfColor( color );
|
||||||
|
sToolBar.setJobID(id);
|
||||||
|
|
||||||
|
if ( y > TOP_MARGIN) {
|
||||||
|
int frameNumber = (y - TOP_MARGIN) / traceWidth;
|
||||||
|
sToolBar.setFrameNumber(frameNumber);
|
||||||
|
}
|
||||||
|
if ( traceRectContains(x, y)) {
|
||||||
|
double pixelsPerSecond = (double)calcTraceRectWidth() / frameDuration;
|
||||||
|
double subFrameTime = (x - LEFT_MARGIN) / pixelsPerSecond;
|
||||||
|
sToolBar.setSubFrameTime(subFrameTime);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseMoved(MouseEvent e) {
|
||||||
|
int x = e.getX();
|
||||||
|
int y = e.getY();
|
||||||
|
if ( traceRectContains(x, y)) {
|
||||||
|
setCursor(crossHairCursor);
|
||||||
|
} else {
|
||||||
|
setCursor(defaultCursor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the height of the trace rectangle.
|
||||||
|
*/
|
||||||
|
private int calcTraceRectHeight() {
|
||||||
|
return ( getHeight() - TOP_MARGIN - BOTTOM_MARGIN);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the width of the trace rectangle.
|
||||||
|
*/
|
||||||
|
private int calcTraceRectWidth() {
|
||||||
|
return ( getWidth() - LEFT_MARGIN - RIGHT_MARGIN);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Render the job execution traces in the jobExecEvtList.
|
||||||
|
*/
|
||||||
|
private void doDrawing(Graphics g) {
|
||||||
|
Graphics2D g2d = (Graphics2D) g;
|
||||||
|
|
||||||
|
RenderingHints rh = new RenderingHints(
|
||||||
|
RenderingHints.KEY_ANTIALIASING,
|
||||||
|
RenderingHints.VALUE_ANTIALIAS_ON);
|
||||||
|
|
||||||
|
rh.put(RenderingHints.KEY_RENDERING,
|
||||||
|
RenderingHints.VALUE_RENDER_QUALITY);
|
||||||
|
|
||||||
|
int traceRectHeight = calcTraceRectHeight();
|
||||||
|
int traceRectWidth = calcTraceRectWidth();
|
||||||
|
double pixelsPerSecond = (double)traceRectWidth / frameDuration;
|
||||||
|
|
||||||
|
// Panel Background Color Fill
|
||||||
|
g2d.setPaint(Color.WHITE);
|
||||||
|
g2d.fillRect(0, 0, getWidth(), getHeight());
|
||||||
|
|
||||||
|
// Frame Trace Rectangle Fill
|
||||||
|
g2d.setPaint(Color.BLACK);
|
||||||
|
g2d.fillRect(LEFT_MARGIN, TOP_MARGIN, traceRectWidth, traceRectHeight);
|
||||||
|
|
||||||
|
boolean wasEOF = false;
|
||||||
|
boolean wasTOF = false;
|
||||||
|
double startOfFrame = 0.0;
|
||||||
|
int frameNumber = 0;
|
||||||
|
|
||||||
|
for (JobExecutionEvent jobExec : jobExecList ) {
|
||||||
|
|
||||||
|
if (!wasTOF && jobExec.isTOF) {
|
||||||
|
startOfFrame = jobExec.start;
|
||||||
|
frameNumber ++;
|
||||||
|
}
|
||||||
|
|
||||||
|
wasTOF = jobExec.isTOF;
|
||||||
|
wasEOF = jobExec.isEOF;
|
||||||
|
|
||||||
|
int jobY = TOP_MARGIN + frameNumber * traceWidth;
|
||||||
|
int jobStartX = LEFT_MARGIN + (int)((jobExec.start - startOfFrame) * pixelsPerSecond);
|
||||||
|
int jobWidth = (int)( (jobExec.stop - jobExec.start) * pixelsPerSecond);
|
||||||
|
|
||||||
|
g2d.setPaint(Color.BLACK);
|
||||||
|
g2d.drawString ( String.format("%8.3f", startOfFrame), 30, jobY + traceWidth/2);
|
||||||
|
g2d.setPaint( idToColorMap.getColor( jobExec.id ) );
|
||||||
|
g2d.fillRect(jobStartX, jobY, jobWidth, traceWidth-2);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void paintComponent(Graphics g) {
|
||||||
|
super.paintComponent(g);
|
||||||
|
image = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_RGB);
|
||||||
|
Graphics2D g2 = image.createGraphics();
|
||||||
|
doDrawing(g2);
|
||||||
|
g.drawImage(image, 0, 0, this);
|
||||||
|
g2.dispose();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,59 @@
|
|||||||
|
package trick.jobperf;
|
||||||
|
|
||||||
|
import java.awt.*;
|
||||||
|
import java.awt.event.*;
|
||||||
|
import java.io.*;
|
||||||
|
import javax.swing.*;
|
||||||
|
import java.net.URL;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class TraceViewInputToolBar initially displays an estimate of the frame size
|
||||||
|
* for the JobPerf input timeline data. A user may also enter the intended frame
|
||||||
|
* size into the JTextField, and pressing the "Set" button, which calls
|
||||||
|
* traceView.setFrameDuration( newFrameSize );
|
||||||
|
*/
|
||||||
|
public class TraceViewInputToolBar extends JToolBar implements ActionListener {
|
||||||
|
|
||||||
|
private TraceViewCanvas traceView;
|
||||||
|
private JTextField frameDurationField;
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
* @param tvc TraceViewCanvas to be controlled.
|
||||||
|
*/
|
||||||
|
public TraceViewInputToolBar (TraceViewCanvas tvc) {
|
||||||
|
traceView = tvc;
|
||||||
|
add( new JLabel(" Frame Size: "));
|
||||||
|
frameDurationField = new JTextField(15);
|
||||||
|
frameDurationField.setText( String.format("%8.4f", traceView.getFrameDuration()) );
|
||||||
|
add(frameDurationField);
|
||||||
|
|
||||||
|
JButton setButton = new JButton("Set");
|
||||||
|
setButton.addActionListener(this);
|
||||||
|
setButton.setActionCommand("setFrameSize");
|
||||||
|
setButton.setToolTipText("Set frame size in seconds.");
|
||||||
|
add(setButton);
|
||||||
|
|
||||||
|
// Add Trick LOGO here.
|
||||||
|
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent event) {
|
||||||
|
String s = event.getActionCommand();
|
||||||
|
switch (s) {
|
||||||
|
case "setFrameSize":
|
||||||
|
double newFrameSize = 0.0;
|
||||||
|
try {
|
||||||
|
newFrameSize = Double.parseDouble( frameDurationField.getText() );
|
||||||
|
} catch ( NumberFormatException e) {
|
||||||
|
frameDurationField.setText( String.format("%8.4f", traceView.getFrameDuration()) );
|
||||||
|
}
|
||||||
|
if ( newFrameSize > 0.0) {
|
||||||
|
traceView.setFrameDuration( newFrameSize );
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
System.out.println("Unknown Action Command:" + s);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,72 @@
|
|||||||
|
package trick.jobperf;
|
||||||
|
|
||||||
|
import java.awt.*;
|
||||||
|
import java.awt.event.*;
|
||||||
|
import java.io.*;
|
||||||
|
import javax.swing.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class TraceViewMenuBar represents the menu bar of the JobPerf application.
|
||||||
|
* It aggregates the following GUI components:
|
||||||
|
* JMenuBar [this]
|
||||||
|
* JMenu [fileMenu]
|
||||||
|
* JMenuItem [fileMenuExit], Action: Call System.exit(0);
|
||||||
|
* JMenu [optionsMenu]
|
||||||
|
* JMenu [traceSizeMenu]
|
||||||
|
* JMenuItem [traceSizeMenuIncrease], Action: Call traceView.increaseTraceWidth().
|
||||||
|
* JMenuItem [traceSizeMenuDecrease], Action: Call traceView.decreaseTraceWidth()
|
||||||
|
*/
|
||||||
|
public class TraceViewMenuBar extends JMenuBar implements ActionListener {
|
||||||
|
|
||||||
|
private TraceViewCanvas traceView;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
* @param tvc the TraceViewCanvas to be controlled by this menu bar.
|
||||||
|
*/
|
||||||
|
public TraceViewMenuBar(TraceViewCanvas tvc) {
|
||||||
|
traceView = tvc;
|
||||||
|
|
||||||
|
JMenu fileMenu = new JMenu("File");
|
||||||
|
JMenuItem fileMenuExit = new JMenuItem("Exit");
|
||||||
|
fileMenuExit.setActionCommand("exit");
|
||||||
|
fileMenuExit.addActionListener(this);
|
||||||
|
fileMenu.add(fileMenuExit);
|
||||||
|
add(fileMenu);
|
||||||
|
|
||||||
|
JMenu optionsMenu = new JMenu("Options");
|
||||||
|
JMenu traceSizeMenu = new JMenu("TraceSize");
|
||||||
|
JMenuItem traceSizeMenuIncrease = new JMenuItem("Increase Trace Width");
|
||||||
|
traceSizeMenuIncrease.setActionCommand("increase-trace_width");
|
||||||
|
KeyStroke ctrlPlus = KeyStroke.getKeyStroke('P', InputEvent.CTRL_MASK );
|
||||||
|
traceSizeMenuIncrease.setAccelerator(ctrlPlus);
|
||||||
|
traceSizeMenuIncrease.addActionListener(this);
|
||||||
|
traceSizeMenu.add(traceSizeMenuIncrease);
|
||||||
|
JMenuItem traceSizeMenuDecrease = new JMenuItem("Decrease Trace Width");
|
||||||
|
traceSizeMenuDecrease.setActionCommand("decrease-trace_width");
|
||||||
|
KeyStroke ctrlMinus = KeyStroke.getKeyStroke('-', InputEvent.CTRL_MASK);
|
||||||
|
traceSizeMenuDecrease.setAccelerator(ctrlMinus);
|
||||||
|
traceSizeMenuDecrease.addActionListener(this);
|
||||||
|
traceSizeMenu.add(traceSizeMenuDecrease);
|
||||||
|
optionsMenu.add(traceSizeMenu);
|
||||||
|
add(optionsMenu);
|
||||||
|
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
String s = e.getActionCommand();
|
||||||
|
switch (s) {
|
||||||
|
case "increase-trace_width":
|
||||||
|
traceView.increaseTraceWidth();
|
||||||
|
break;
|
||||||
|
case "decrease-trace_width":
|
||||||
|
traceView.decreaseTraceWidth();
|
||||||
|
break;
|
||||||
|
case "exit":
|
||||||
|
System.exit(0);
|
||||||
|
default:
|
||||||
|
System.out.println("Unknown Action Command:" + s);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,56 @@
|
|||||||
|
package trick.jobperf;
|
||||||
|
|
||||||
|
import javax.swing.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class TraceViewOutputToolBar displays information output from a
|
||||||
|
* TraceViewCanvas. Specifically, this displays the Job ID, frame number, and
|
||||||
|
* subFrame Time associated with a mouse click position on the TraceViewCanvas.
|
||||||
|
*/
|
||||||
|
class TraceViewOutputToolBar extends JToolBar {
|
||||||
|
private JTextField IDField;
|
||||||
|
private JTextField frameNumberField;
|
||||||
|
private JTextField subFrameTimeField;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*/
|
||||||
|
public TraceViewOutputToolBar () {
|
||||||
|
|
||||||
|
add( new JLabel(" Job ID: "));
|
||||||
|
IDField = new JTextField(15);
|
||||||
|
IDField.setEditable(false);
|
||||||
|
IDField.setText( "");
|
||||||
|
add(IDField);
|
||||||
|
|
||||||
|
add( new JLabel(" Frame Number: "));
|
||||||
|
frameNumberField = new JTextField(15);
|
||||||
|
frameNumberField.setEditable(false);
|
||||||
|
frameNumberField.setText( "0");
|
||||||
|
add(frameNumberField);
|
||||||
|
|
||||||
|
add( new JLabel(" Subframe Time: "));
|
||||||
|
subFrameTimeField = new JTextField(15);
|
||||||
|
subFrameTimeField.setEditable(false);
|
||||||
|
subFrameTimeField.setText( "0.00");
|
||||||
|
add(subFrameTimeField);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @param id job identifier to display.
|
||||||
|
*/
|
||||||
|
public void setJobID(String id) {
|
||||||
|
IDField.setText( id );
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @param fn frame number to display.
|
||||||
|
*/
|
||||||
|
public void setFrameNumber(int fn) {
|
||||||
|
frameNumberField.setText( String.format("%d", fn));
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @param time subframe time to display.
|
||||||
|
*/
|
||||||
|
public void setSubFrameTime(double time) {
|
||||||
|
subFrameTimeField.setText( String.format("%8.4f", time));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,60 @@
|
|||||||
|
package trick.jobperf;
|
||||||
|
|
||||||
|
import java.awt.*;
|
||||||
|
import java.util.*;
|
||||||
|
import javax.swing.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class TraceViewWindow represents the main window of the JobPerf application.
|
||||||
|
* It aggregates the following GUI components:
|
||||||
|
*
|
||||||
|
* - TraceViewMenuBar [menuBar]
|
||||||
|
* - TraceViewInputToolBar [toolbar]
|
||||||
|
* - JPanel [mainPanel]
|
||||||
|
* - JPanel [tracePanel]
|
||||||
|
* - JScrollPane [scrollPane]
|
||||||
|
* - TraceViewCanvas [traceView]
|
||||||
|
* - TraceViewOutputToolBar [outputToolBar]
|
||||||
|
*/
|
||||||
|
public class TraceViewWindow extends JFrame {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
* @param jobExecList an ArrayList of JobExecutionEvent, i.e., the job timeline data.
|
||||||
|
*/
|
||||||
|
public TraceViewWindow( ArrayList<JobExecutionEvent> jobExecList ) {
|
||||||
|
TraceViewOutputToolBar outputToolBar = new TraceViewOutputToolBar();
|
||||||
|
TraceViewCanvas traceView = new TraceViewCanvas( jobExecList, outputToolBar);
|
||||||
|
|
||||||
|
TraceViewMenuBar menuBar = new TraceViewMenuBar(traceView);
|
||||||
|
setJMenuBar(menuBar);
|
||||||
|
|
||||||
|
TraceViewInputToolBar nToolBar = new TraceViewInputToolBar( traceView );
|
||||||
|
add(nToolBar, BorderLayout.NORTH);
|
||||||
|
|
||||||
|
JScrollPane scrollPane = new JScrollPane( traceView );
|
||||||
|
scrollPane.setPreferredSize(new Dimension(800, 400));
|
||||||
|
|
||||||
|
JPanel tracePanel = new JPanel();
|
||||||
|
tracePanel.setPreferredSize(new Dimension(800, 400));
|
||||||
|
tracePanel.add(scrollPane);
|
||||||
|
tracePanel.setLayout(new BoxLayout(tracePanel, BoxLayout.X_AXIS));
|
||||||
|
|
||||||
|
JPanel mainPanel = new JPanel();
|
||||||
|
mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.Y_AXIS));
|
||||||
|
mainPanel.add(tracePanel);
|
||||||
|
|
||||||
|
add(outputToolBar, BorderLayout.SOUTH);
|
||||||
|
|
||||||
|
setTitle("JobPerf");
|
||||||
|
setSize(800, 500);
|
||||||
|
add(mainPanel);
|
||||||
|
pack();
|
||||||
|
setVisible(true);
|
||||||
|
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||||
|
setFocusable(true);
|
||||||
|
setVisible(true);
|
||||||
|
|
||||||
|
traceView.repaint();
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user