tmf: Expose TmfExperiment.getTraces() up to ITmfTrace
[deliverable/tracecompass.git] / org.eclipse.linuxtools.tmf.core / src / org / eclipse / linuxtools / internal / tmf / core / statesystem / HistoryBuilder.java
1 /*******************************************************************************
2 * Copyright (c) 2012, 2013 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.internal.tmf.core.statesystem.backends.IStateHistoryBackend;
18 import org.eclipse.linuxtools.tmf.core.component.TmfComponent;
19 import org.eclipse.linuxtools.tmf.core.event.ITmfEvent;
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.timestamp.TmfTimeRange;
31 import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace;
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 public class HistoryBuilder extends TmfComponent {
45
46 private final IStateChangeInput sci;
47 private final StateSystem ss;
48 private final IStateHistoryBackend hb;
49 private boolean started = true; /* Don't handle signals until we're ready */
50
51 /**
52 * Instantiate a new HistoryBuilder helper. The input -> ss -> backend
53 * relationships should have been set up already.
54 *
55 * @param stateChangeInput
56 * The input plugin to use
57 * @param ss
58 * The state system object that will receive the state changes
59 * from the input
60 * @param backend
61 * The back-end storage to use, which will receive the intervals
62 * from the ss
63 * @param buildManually
64 * Should we build this history in-band or not. True means we
65 * will start the building ourselves and block the caller until
66 * construction is done. False (out-of-band) means we will start
67 * listening for the signal and return immediately.
68 */
69 public HistoryBuilder(IStateChangeInput stateChangeInput, StateSystem ss,
70 IStateHistoryBackend backend, boolean buildManually) {
71 if (stateChangeInput == null || backend == null || ss == null) {
72 throw new IllegalArgumentException();
73 }
74 if (stateChangeInput.getAssignedStateSystem() != ss) {
75 /* Logic check to make sure the input is setup properly */
76 throw new RuntimeException();
77 }
78
79 sci = stateChangeInput;
80 hb = backend;
81 this.ss = ss;
82
83 if (buildManually) {
84 TmfSignalManager.deregister(this);
85 this.buildManually();
86 } else {
87 started = false;
88 /* We'll now wait for the signal to start building */
89 }
90 }
91
92 /**
93 * Factory-style method to open an existing history, you only have to
94 * provide the already-instantiated IStateHistoryBackend object.
95 *
96 * @param hb
97 * The history-backend object
98 * @return A IStateSystemBuilder reference to the new state system. If you
99 * will only run queries on this history, you should *definitely*
100 * cast it to IStateSystemQuerier.
101 * @throws IOException
102 * If there was something wrong.
103 */
104 public static ITmfStateSystemBuilder openExistingHistory(
105 IStateHistoryBackend hb) throws IOException {
106 return new StateSystem(hb, false);
107 }
108
109 /**
110 * Return a read/write reference to the state system object that was
111 * created.
112 *
113 * @return Reference to the state system, with access to everything.
114 */
115 public ITmfStateSystemBuilder getStateSystemBuilder() {
116 return ss;
117 }
118
119 /**
120 * Return a read-only reference to the state system object that was created.
121 *
122 * @return Reference to the state system, but only with the query methods
123 * available.
124 */
125 public ITmfStateSystem getStateSystemQuerier() {
126 return ss;
127 }
128
129 /**
130 * Build the state history without waiting for signals or anything
131 */
132 private void buildManually() {
133 StateSystemBuildRequest request = new StateSystemBuildRequest(this);
134
135 /* Send the request to the trace here, since there is probably no
136 * experiment. */
137 sci.getTrace().sendRequest(request);
138 try {
139 request.waitForCompletion();
140 } catch (InterruptedException e) {
141 e.printStackTrace();
142 }
143 }
144
145
146 // ------------------------------------------------------------------------
147 // Signal handlers
148 // ------------------------------------------------------------------------
149
150 /**
151 * Listen to the "trace range updated" signal to start the state history
152 * construction.
153 *
154 * @param signal
155 * The "trace range updated" signal. Listening to this
156 * signal will coalesce this request with the one from the
157 * indexer and histogram.
158 */
159 @TmfSignalHandler
160 public void traceRangeUpdated(final TmfTraceRangeUpdatedSignal signal) {
161 /*
162 * Check if this signal is for this trace, or for an experiment
163 * containing this trace.
164 */
165 ITmfTrace sender = signal.getTrace();
166 ITmfTrace target = null;
167 for (ITmfTrace trace : sender.getTraces()) {
168 if (trace == sci.getTrace()) {
169 target = trace;
170 break;
171 }
172 }
173
174 if (target == null) {
175 return;
176 }
177
178 if (!started) {
179 started = true;
180 StateSystemBuildRequest request = new StateSystemBuildRequest(this);
181 sender.sendRequest(request);
182 }
183 }
184
185 /**
186 * Listen to the "trace closed" signal to clean up if necessary.
187 *
188 * @param signal
189 * The "trace closed" signal.
190 */
191 @TmfSignalHandler
192 public void traceClosed(TmfTraceClosedSignal signal) {
193 /*
194 * Check if this signal is for this trace, or for an experiment
195 * containing this trace.
196 */
197 boolean found = false;
198 for (ITmfTrace trace : signal.getTrace().getTraces()) {
199 if (trace == sci.getTrace()) {
200 found = true;
201 break;
202 }
203 }
204
205 if (found && !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 StateSystemBuildRequest(HistoryBuilder builder) {
238 super(builder.getInputPlugin().getExpectedEventType(),
239 TmfTimeRange.ETERNITY,
240 TmfDataRequest.ALL_DATA,
241 chunkSize,
242 ITmfDataRequest.ExecutionType.BACKGROUND);
243 this.builder = builder;
244 this.sci = builder.getInputPlugin();
245 this.trace = sci.getTrace();
246 }
247
248 @Override
249 public void handleData(final ITmfEvent event) {
250 super.handleData(event);
251 if (event != null) {
252 if (event.getTrace() == trace) {
253 sci.processEvent(event);
254 }
255 }
256 }
257
258 @Override
259 public void handleSuccess() {
260 super.handleSuccess();
261 builder.close(false);
262 }
263
264 @Override
265 public void handleCancel() {
266 super.handleCancel();
267 builder.close(true);
268 }
269
270 @Override
271 public void handleFailure() {
272 super.handleFailure();
273 builder.close(true);
274 }
275 }
This page took 0.035984 seconds and 5 git commands to generate.