Get rid of uses of gnu.trove2
[simantics/platform.git] / bundles / org.simantics.threadlog / src / org / simantics / threadlog / ui / ThreadLogVisualizer.java
1 /*******************************************************************************
2  * Copyright (c) 2007, 2010 Association for Decentralized Information Management
3  * in Industry THTH ry.
4  * All rights reserved. This program and the accompanying materials
5  * are made available under the terms of the Eclipse Public License v1.0
6  * which accompanies this distribution, and is available at
7  * http://www.eclipse.org/legal/epl-v10.html
8  *
9  * Contributors:
10  *     VTT Technical Research Centre of Finland - initial API and implementation
11  *******************************************************************************/
12 package org.simantics.threadlog.ui;
13
14 import java.awt.BorderLayout;
15 import java.awt.event.ActionEvent;
16 import java.awt.event.KeyEvent;
17 import java.io.IOException;
18 import java.util.ArrayList;
19 import java.util.Collections;
20
21 import javax.swing.AbstractAction;
22 import javax.swing.JButton;
23 import javax.swing.JFileChooser;
24 import javax.swing.JFrame;
25 import javax.swing.JToolBar;
26 import javax.swing.filechooser.FileNameExtensionFilter;
27
28 import org.simantics.threadlog.Task;
29 import org.simantics.threadlog.ThreadLog;
30
31 import gnu.trove.map.hash.TLongObjectHashMap;
32 import gnu.trove.procedure.TObjectProcedure;
33
34 public class ThreadLogVisualizer extends JFrame {
35
36     private static final long serialVersionUID = 6250996509358338304L;
37     
38     TimeLineViewer viewer = new TimeLineViewer();
39     JToolBar toolbar = new JToolBar("Thread Log Visualizer Tools");
40     JButton saveButton = new JButton(new SaveAction());
41
42     ThreadLog currentLog;
43
44     public ThreadLogVisualizer() {
45         super("Thread log visualizer");
46         setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
47         setSize(800, 600);
48
49         getContentPane().setLayout(new BorderLayout());
50         getContentPane().add(toolbar, BorderLayout.NORTH);
51         getContentPane().add(viewer, BorderLayout.CENTER);
52
53         toolbar.add(saveButton);
54     }
55
56     class SaveAction extends AbstractAction {
57         private static final long serialVersionUID = 1L;
58
59         public SaveAction() {
60             super("Save");
61             putValue(SHORT_DESCRIPTION, "Save the Current Log");
62             putValue(MNEMONIC_KEY, KeyEvent.VK_S);
63         }
64
65         @Override
66         public void actionPerformed(ActionEvent e) {
67             JFileChooser chooser = new JFileChooser();
68             FileNameExtensionFilter filter = new FileNameExtensionFilter(
69                     "Thread Logs (*.tlog)", "tlog", "tlog");
70             chooser.setFileFilter(filter);
71             int returnVal = chooser.showSaveDialog(ThreadLogVisualizer.this);
72             if (returnVal != JFileChooser.APPROVE_OPTION)
73                 return;
74
75             try {
76                 currentLog.serialize(chooser.getSelectedFile());
77             } catch (IOException ex) {
78                 ex.printStackTrace();
79             }
80         }
81     }
82
83     public void setLog(ThreadLog log) {
84         this.currentLog = log;
85
86         String[] tasks = log.getTasks();
87         double[] times = log.getTimes();
88
89         // Relativize to the first task
90         double minTime = Double.POSITIVE_INFINITY;
91         double maxTime = Double.NEGATIVE_INFINITY;
92
93         for(int i=0;i<times.length;i+=2) {
94             double temp = times[i];
95             if(temp < minTime)
96                 minTime = temp;
97
98             temp = times[i+1];
99             if(temp > maxTime)
100                 maxTime = temp;
101         }
102         for(int i=0;i<times.length;++i)
103             times[i] -= minTime;
104         maxTime -= minTime;
105
106         // Group intervals by thread
107         TLongObjectHashMap<ArrayList<Interval>> intervals = new TLongObjectHashMap<ArrayList<Interval>>();
108         long[] threads = log.getThreads();
109         for(int i=0;i<tasks.length;++i) {
110             long thread = threads[i];
111             ArrayList<Interval> in = intervals.get(thread);
112             if(in == null) {
113                 in = new ArrayList<Interval>();
114                 intervals.put(thread, in);
115             }
116             in.add(new Interval(tasks[i], times[i*2], times[i*2+1]));
117         }
118
119         // Create lanes
120         viewer.clear();
121         intervals.forEachValue(new TObjectProcedure<ArrayList<Interval>>() {
122
123             @Override
124             public boolean execute(ArrayList<Interval> intervals) {
125                 Collections.sort(intervals);
126                 ArrayList<Lane> lanes = new ArrayList<Lane>();
127
128                 int curLaneId = -1;
129                 Lane curLane = null;
130                 for(Interval in : intervals) {
131                     if(curLane == null || in.begin < curLane.getEnd()) {
132                         ++curLaneId;
133                         if(curLaneId < lanes.size())
134                             curLane = lanes.get(curLaneId);
135                         else {
136                             curLane = new Lane();
137                             lanes.add(curLane);
138                         }
139                     }
140                     else {
141                         while(curLaneId > 0) {
142                             Lane prevLane = lanes.get(curLaneId-1);
143                             if(prevLane.getEnd() > in.begin)
144                                 break;
145                             --curLaneId;
146                             curLane = prevLane;
147                         }
148                     }
149                     curLane.addInterval(in);
150                 }
151
152                 for(Lane lane : lanes)
153                     viewer.addLane(lane);
154                 return true;
155             }
156
157         });
158
159         // update viewer
160         viewer.repaint();
161     }
162
163     public void saveImage() {
164
165     }
166
167     public static void main(String[] args) throws Exception {
168         ThreadLog.setDefaultThreadLog(new ThreadLog());
169
170         {
171             Task A = ThreadLog.BEGIN("A");
172             Thread.sleep(200);
173             Task B = ThreadLog.BEGIN("B");
174             Thread.sleep(100);
175             B.end();
176             Thread.sleep(100);
177             Task C = ThreadLog.BEGIN("C");
178             Thread.sleep(100);
179             C.end();
180             A.end();
181         }
182
183         ThreadLogVisualizer vis = new ThreadLogVisualizer();
184         vis.setLog(ThreadLog.setDefaultThreadLog(null));
185         vis.setVisible(true);
186     }
187 }