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>
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
11 *******************************************************************************/
13 package org
.eclipse
.linuxtools
.internal
.tmf
.core
.statesystem
;
15 import java
.io
.IOException
;
17 import org
.eclipse
.jdt
.annotation
.NonNull
;
18 import org
.eclipse
.linuxtools
.internal
.tmf
.core
.statesystem
.backends
.IStateHistoryBackend
;
19 import org
.eclipse
.linuxtools
.tmf
.core
.component
.TmfComponent
;
20 import org
.eclipse
.linuxtools
.tmf
.core
.event
.ITmfEvent
;
21 import org
.eclipse
.linuxtools
.tmf
.core
.request
.ITmfEventRequest
;
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
.ITmfStateProvider
;
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
.statesystem
.TmfStateSystemAnalysisModule
;
31 import org
.eclipse
.linuxtools
.tmf
.core
.timestamp
.TmfTimeRange
;
32 import org
.eclipse
.linuxtools
.tmf
.core
.trace
.ITmfTrace
;
33 import org
.eclipse
.linuxtools
.tmf
.core
.trace
.TmfExperiment
;
36 * This is the high-level wrapper around the State History and its provider and
37 * storage plugins. Just create the object using the constructor then .run()
39 * You can use one HistoryBuilder and it will instantiate everything underneath.
40 * If you need more fine-grained control you can still ignore this and
41 * instantiate everything manually.
45 * @deprecated Building state systems should now be done via
46 * {@link TmfStateSystemAnalysisModule}
49 public class HistoryBuilder
extends TmfComponent
{
51 private final ITmfStateProvider sp
;
52 private final StateSystem ss
;
53 private final IStateHistoryBackend hb
;
54 private boolean started
= true; /* Don't handle signals until we're ready */
57 * Instantiate a new HistoryBuilder helper. The provider -> ss -> backend
58 * relationships should have been set up already.
60 * @param stateProvider
61 * The state provider plugin to use
63 * The state system object that will receive the state changes
66 * The back-end storage to use, which will receive the intervals
68 * @param buildManually
69 * Should we build this history in-band or not. True means we
70 * will start the building ourselves and block the caller until
71 * construction is done. False (out-of-band) means we will start
72 * listening for the signal and return immediately.
74 public HistoryBuilder(ITmfStateProvider stateProvider
, StateSystem ss
,
75 IStateHistoryBackend backend
, boolean buildManually
) {
76 if (stateProvider
== null || backend
== null || ss
== null) {
77 throw new IllegalArgumentException();
79 if (stateProvider
.getAssignedStateSystem() != ss
) {
80 /* Logic check to make sure the provider is setup properly */
81 throw new IllegalArgumentException();
89 TmfSignalManager
.deregister(this);
93 /* We'll now wait for the signal to start building */
98 * Factory-style method to open an existing history, you only have to
99 * provide the already-instantiated IStateHistoryBackend object.
102 * The history-backend object
103 * @return A IStateSystemBuilder reference to the new state system. If you
104 * will only run queries on this history, you should *definitely*
105 * cast it to IStateSystemQuerier.
106 * @throws IOException
107 * If there was something wrong.
109 public static ITmfStateSystemBuilder
openExistingHistory(
110 @NonNull IStateHistoryBackend hb
) throws IOException
{
111 return new StateSystem(hb
, false);
115 * Return a read/write reference to the state system object that was
118 * @return Reference to the state system, with access to everything.
120 public ITmfStateSystemBuilder
getStateSystemBuilder() {
125 * Return a read-only reference to the state system object that was created.
127 * @return Reference to the state system, but only with the query methods
130 public ITmfStateSystem
getStateSystemQuerier() {
135 * Build the state history without waiting for signals or anything
137 private void buildManually() {
138 StateSystemBuildRequest request
= new StateSystemBuildRequest(this);
140 /* Send the request to the trace here, since there is probably no
142 sp
.getTrace().sendRequest(request
);
144 request
.waitForCompletion();
145 } catch (InterruptedException e
) {
151 // ------------------------------------------------------------------------
153 // ------------------------------------------------------------------------
156 * Listen to the "trace range updated" signal to start the state history
160 * The "trace range updated" signal. Listening to this
161 * signal will coalesce this request with the one from the
162 * indexer and histogram.
165 public void traceRangeUpdated(final TmfTraceRangeUpdatedSignal signal
) {
166 ITmfTrace sender
= signal
.getTrace();
168 if (!signalIsForUs(sender
)) {
174 StateSystemBuildRequest request
= new StateSystemBuildRequest(this);
175 sender
.sendRequest(request
);
180 * Listen to the "trace closed" signal to clean up if necessary.
183 * The "trace closed" signal.
186 public void traceClosed(TmfTraceClosedSignal signal
) {
187 ITmfTrace sender
= signal
.getTrace();
189 if (signalIsForUs(sender
) && !started
) {
195 * Check if this signal is for this trace, or for an experiment containing
198 private boolean signalIsForUs(ITmfTrace sender
) {
199 if (sender
instanceof TmfExperiment
) {
200 /* Yeah doing a lazy instanceof check here, but it's a special case! */
201 TmfExperiment exp
= (TmfExperiment
) sender
;
202 for (ITmfTrace childTrace
: exp
.getTraces()) {
203 if (childTrace
== sp
.getTrace()) {
207 } else if (sender
== sp
.getTrace()) {
213 // ------------------------------------------------------------------------
214 // Methods reserved for the request object below
215 // ------------------------------------------------------------------------
217 /** Get the state provider object */
218 ITmfStateProvider
getStateProvider() {
222 void close(boolean deleteFiles
) {
231 class StateSystemBuildRequest
extends TmfEventRequest
{
232 private final HistoryBuilder builder
;
233 private final ITmfStateProvider sci
;
234 private final ITmfTrace trace
;
236 StateSystemBuildRequest(HistoryBuilder builder
) {
237 super(builder
.getStateProvider().getExpectedEventType(),
238 TmfTimeRange
.ETERNITY
,
240 ITmfEventRequest
.ALL_DATA
,
241 ITmfEventRequest
.ExecutionType
.BACKGROUND
);
242 this.builder
= builder
;
243 this.sci
= builder
.getStateProvider();
244 this.trace
= sci
.getTrace();
248 public void handleData(final ITmfEvent event
) {
249 super.handleData(event
);
250 if (event
!= null && event
.getTrace() == trace
) {
251 sci
.processEvent(event
);
256 public void handleSuccess() {
257 super.handleSuccess();
258 builder
.close(false);
262 public void handleCancel() {
263 super.handleCancel();
268 public void handleFailure() {
269 super.handleFailure();