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