Add Iterator support to TMF traces
[deliverable/tracecompass.git] / org.eclipse.linuxtools.tmf.core / src / org / eclipse / linuxtools / internal / tmf / core / statesystem / HistoryBuilder.java
1 /*******************************************************************************
2 * Copyright (c) 2012 Ericsson
3 * Copyright (c) 2010, 2011 École Polytechnique de Montréal
4 * Copyright (c) 2010, 2011 Alexandre Montplaisir <alexandre.montplaisir@gmail.com>
5 *
6 * All rights reserved. This program and the accompanying materials are
7 * made available under the terms of the Eclipse Public License v1.0 which
8 * accompanies this distribution, and is available at
9 * http://www.eclipse.org/legal/epl-v10.html
10 *
11 *******************************************************************************/
12
13 package org.eclipse.linuxtools.internal.tmf.core.statesystem;
14
15 import java.io.IOException;
16
17 import org.eclipse.linuxtools.tmf.core.component.TmfComponent;
18 import org.eclipse.linuxtools.tmf.core.event.ITmfEvent;
19 import org.eclipse.linuxtools.tmf.core.event.TmfTimeRange;
20 import org.eclipse.linuxtools.tmf.core.request.ITmfDataRequest;
21 import org.eclipse.linuxtools.tmf.core.request.TmfDataRequest;
22 import org.eclipse.linuxtools.tmf.core.request.TmfEventRequest;
23 import org.eclipse.linuxtools.tmf.core.signal.TmfSignalHandler;
24 import org.eclipse.linuxtools.tmf.core.signal.TmfSignalManager;
25 import org.eclipse.linuxtools.tmf.core.signal.TmfTraceClosedSignal;
26 import org.eclipse.linuxtools.tmf.core.signal.TmfTraceRangeUpdatedSignal;
27 import org.eclipse.linuxtools.tmf.core.statesystem.IStateChangeInput;
28 import org.eclipse.linuxtools.tmf.core.statesystem.ITmfStateSystem;
29 import org.eclipse.linuxtools.tmf.core.statesystem.ITmfStateSystemBuilder;
30 import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace;
31 import org.eclipse.linuxtools.tmf.core.trace.TmfExperiment;
32
33 /**
34 * This is the high-level wrapper around the State History and its input and
35 * storage plugins. Just create the object using the constructor then .run()
36 *
37 * You can use one HistoryBuilder and it will instantiate everything underneath.
38 * If you need more fine-grained control you can still ignore this and
39 * instantiate everything manually.
40 *
41 * @author alexmont
42 *
43 */
44 @SuppressWarnings("deprecation")
45 public class HistoryBuilder extends TmfComponent {
46
47 private final IStateChangeInput sci;
48 private final StateSystem ss;
49 private final IStateHistoryBackend hb;
50 private boolean started = true; /* Don't handle signals until we're ready */
51
52 /**
53 * Instantiate a new HistoryBuilder helper.
54 *
55 * @param stateChangeInput
56 * The input plugin to use. This is required.
57 * @param backend
58 * The backend storage to use.
59 * @param buildManually
60 * Should we build this history in-band or not. True means we
61 * will start the building ourselves and block the caller until
62 * construction is done. False (out-of-band) means we will start
63 * listening for the signal and return immediately. Another
64 * signal will be sent when finished.
65 * @throws IOException
66 * Is thrown if anything went wrong (usually with the storage
67 * backend)
68 */
69 public HistoryBuilder(IStateChangeInput stateChangeInput,
70 IStateHistoryBackend backend, boolean buildManually)
71 throws IOException {
72 if (stateChangeInput == null || backend == null) {
73 throw new IllegalArgumentException();
74 }
75 sci = stateChangeInput;
76 hb = backend;
77 ss = new StateSystem(hb, true);
78
79 sci.assignTargetStateSystem(ss);
80
81 if (buildManually) {
82 TmfSignalManager.deregister(this);
83 this.buildManually();
84 } else {
85 started = false;
86 /* We'll now wait for the signal to start building */
87 }
88 }
89
90 /**
91 * Factory-style method to open an existing history, you only have to
92 * provide the already-instantiated IStateHistoryBackend object.
93 *
94 * @param hb
95 * The history-backend object
96 * @return A IStateSystemBuilder reference to the new state system. If you
97 * will only run queries on this history, you should *definitely*
98 * cast it to IStateSystemQuerier.
99 * @throws IOException
100 * If there was something wrong.
101 */
102 public static ITmfStateSystemBuilder openExistingHistory(
103 IStateHistoryBackend hb) throws IOException {
104 return new StateSystem(hb, false);
105 }
106
107 /**
108 * Return a read/write reference to the state system object that was
109 * created.
110 *
111 * @return Reference to the state system, with access to everything.
112 */
113 public ITmfStateSystemBuilder getStateSystemBuilder() {
114 return ss;
115 }
116
117 /**
118 * Return a read-only reference to the state system object that was created.
119 *
120 * @return Reference to the state system, but only with the query methods
121 * available.
122 */
123 public ITmfStateSystem getStateSystemQuerier() {
124 return ss;
125 }
126
127 /**
128 * Build the state history without waiting for signals or anything
129 */
130 private void buildManually() {
131 StateSystemBuildRequest request = new StateSystemBuildRequest(this);
132
133 /* Send the request to the trace here, since there is probably no
134 * experiment. */
135 sci.getTrace().sendRequest(request);
136 try {
137 request.waitForCompletion();
138 } catch (InterruptedException e) {
139 e.printStackTrace();
140 }
141 }
142
143
144 // ------------------------------------------------------------------------
145 // Signal handlers
146 // ------------------------------------------------------------------------
147
148 /**
149 * Listen to the "trace range updated" signal to start the state history
150 * construction.
151 *
152 * @param signal
153 * The "trace range updated" signal. Listening to this
154 * signal will coalesce this request with the one from the
155 * indexer and histogram.
156 */
157 @TmfSignalHandler
158 public void traceRangeUpdated(final TmfTraceRangeUpdatedSignal signal) {
159 ITmfTrace trace = signal.getTrace();
160 if (signal.getTrace() instanceof TmfExperiment) {
161 TmfExperiment experiment = (TmfExperiment) signal.getTrace();
162 for (ITmfTrace expTrace : experiment.getTraces()) {
163 if (expTrace == sci.getTrace()) {
164 trace = expTrace;
165 break;
166 }
167 }
168 }
169 if (trace != sci.getTrace()) {
170 return;
171 }
172 /* the signal is for this trace or for an experiment containing this trace */
173
174 if (!started) {
175 started = true;
176 StateSystemBuildRequest request = new StateSystemBuildRequest(this);
177 trace = signal.getTrace();
178 trace.sendRequest(request);
179 }
180 }
181
182 /**
183 * Listen to the "trace closed" signal to clean up if necessary.
184 *
185 * @param signal
186 * The "trace closed" signal.
187 */
188 @TmfSignalHandler
189 public void traceClosed(TmfTraceClosedSignal signal) {
190 ITmfTrace trace = signal.getTrace();
191 if (signal.getTrace() instanceof TmfExperiment) {
192 TmfExperiment experiment = (TmfExperiment) signal.getTrace();
193 for (ITmfTrace expTrace : experiment.getTraces()) {
194 if (expTrace == sci.getTrace()) {
195 trace = expTrace;
196 break;
197 }
198 }
199 }
200 if (trace != sci.getTrace()) {
201 return;
202 }
203 /* the signal is for this trace or for an experiment containing this trace */
204
205 if (!started) {
206 close(true);
207 }
208 }
209
210 // ------------------------------------------------------------------------
211 // Methods reserved for the request object below
212 // ------------------------------------------------------------------------
213
214 /** Get the input plugin object */
215 IStateChangeInput getInputPlugin() {
216 return sci;
217 }
218
219 void close(boolean deleteFiles) {
220 sci.dispose();
221 if (deleteFiles) {
222 hb.removeFiles();
223 }
224 dispose();
225 }
226 }
227
228 class StateSystemBuildRequest extends TmfEventRequest {
229
230 /** The amount of events queried at a time through the requests */
231 private final static int chunkSize = 50000;
232
233 private final HistoryBuilder builder;
234 private final IStateChangeInput sci;
235 private final ITmfTrace trace;
236
237 @SuppressWarnings("deprecation")
238 StateSystemBuildRequest(HistoryBuilder builder) {
239 super(builder.getInputPlugin().getExpectedEventType(),
240 TmfTimeRange.ETERNITY,
241 TmfDataRequest.ALL_DATA,
242 chunkSize,
243 ITmfDataRequest.ExecutionType.BACKGROUND);
244 this.builder = builder;
245 this.sci = builder.getInputPlugin();
246 this.trace = sci.getTrace();
247 }
248
249 @Override
250 @SuppressWarnings("deprecation")
251 public void handleData(final ITmfEvent event) {
252 super.handleData(event);
253 if (event != null) {
254 if (event.getTrace() == trace) {
255 sci.processEvent(event);
256 }
257 }
258 }
259
260 @Override
261 public void handleSuccess() {
262 super.handleSuccess();
263 builder.close(false);
264 }
265
266 @Override
267 public void handleCancel() {
268 super.handleCancel();
269 builder.close(true);
270 }
271
272 @Override
273 public void handleFailure() {
274 super.handleFailure();
275 builder.close(true);
276 }
277 }
This page took 0.035537 seconds and 5 git commands to generate.