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>
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
.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 import org
.eclipse
.linuxtools
.tmf
.core
.trace
.TmfExperiment
;
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()
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.
45 public class HistoryBuilder
extends TmfComponent
{
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 */
53 * Instantiate a new HistoryBuilder helper. The input -> ss -> backend
54 * relationships should have been set up already.
56 * @param stateChangeInput
57 * The input plugin to use
59 * The state system object that will receive the state changes
62 * The back-end storage to use, which will receive the intervals
64 * @param buildManually
65 * Should we build this history in-band or not. True means we
66 * will start the building ourselves and block the caller until
67 * construction is done. False (out-of-band) means we will start
68 * listening for the signal and return immediately.
70 public HistoryBuilder(IStateChangeInput stateChangeInput
, StateSystem ss
,
71 IStateHistoryBackend backend
, boolean buildManually
) {
72 if (stateChangeInput
== null || backend
== null || ss
== null) {
73 throw new IllegalArgumentException();
75 if (stateChangeInput
.getAssignedStateSystem() != ss
) {
76 /* Logic check to make sure the input is setup properly */
77 throw new RuntimeException();
80 sci
= stateChangeInput
;
85 TmfSignalManager
.deregister(this);
89 /* We'll now wait for the signal to start building */
94 * Factory-style method to open an existing history, you only have to
95 * provide the already-instantiated IStateHistoryBackend object.
98 * The history-backend object
99 * @return A IStateSystemBuilder reference to the new state system. If you
100 * will only run queries on this history, you should *definitely*
101 * cast it to IStateSystemQuerier.
102 * @throws IOException
103 * If there was something wrong.
105 public static ITmfStateSystemBuilder
openExistingHistory(
106 IStateHistoryBackend hb
) throws IOException
{
107 return new StateSystem(hb
, false);
111 * Return a read/write reference to the state system object that was
114 * @return Reference to the state system, with access to everything.
116 public ITmfStateSystemBuilder
getStateSystemBuilder() {
121 * Return a read-only reference to the state system object that was created.
123 * @return Reference to the state system, but only with the query methods
126 public ITmfStateSystem
getStateSystemQuerier() {
131 * Build the state history without waiting for signals or anything
133 private void buildManually() {
134 StateSystemBuildRequest request
= new StateSystemBuildRequest(this);
136 /* Send the request to the trace here, since there is probably no
138 sci
.getTrace().sendRequest(request
);
140 request
.waitForCompletion();
141 } catch (InterruptedException e
) {
147 // ------------------------------------------------------------------------
149 // ------------------------------------------------------------------------
152 * Listen to the "trace range updated" signal to start the state history
156 * The "trace range updated" signal. Listening to this
157 * signal will coalesce this request with the one from the
158 * indexer and histogram.
161 public void traceRangeUpdated(final TmfTraceRangeUpdatedSignal signal
) {
162 ITmfTrace trace
= signal
.getTrace();
163 if (signal
.getTrace() instanceof TmfExperiment
) {
164 TmfExperiment experiment
= (TmfExperiment
) signal
.getTrace();
165 for (ITmfTrace expTrace
: experiment
.getTraces()) {
166 if (expTrace
== sci
.getTrace()) {
172 if (trace
!= sci
.getTrace()) {
175 /* the signal is for this trace or for an experiment containing this trace */
179 StateSystemBuildRequest request
= new StateSystemBuildRequest(this);
180 trace
= signal
.getTrace();
181 trace
.sendRequest(request
);
186 * Listen to the "trace closed" signal to clean up if necessary.
189 * The "trace closed" signal.
192 public void traceClosed(TmfTraceClosedSignal signal
) {
193 ITmfTrace trace
= signal
.getTrace();
194 if (signal
.getTrace() instanceof TmfExperiment
) {
195 TmfExperiment experiment
= (TmfExperiment
) signal
.getTrace();
196 for (ITmfTrace expTrace
: experiment
.getTraces()) {
197 if (expTrace
== sci
.getTrace()) {
203 if (trace
!= sci
.getTrace()) {
206 /* the signal is for this trace or for an experiment containing this trace */
213 // ------------------------------------------------------------------------
214 // Methods reserved for the request object below
215 // ------------------------------------------------------------------------
217 /** Get the input plugin object */
218 IStateChangeInput
getInputPlugin() {
222 void close(boolean deleteFiles
) {
231 class StateSystemBuildRequest
extends TmfEventRequest
{
233 /** The amount of events queried at a time through the requests */
234 private final static int chunkSize
= 50000;
236 private final HistoryBuilder builder
;
237 private final IStateChangeInput sci
;
238 private final ITmfTrace trace
;
240 StateSystemBuildRequest(HistoryBuilder builder
) {
241 super(builder
.getInputPlugin().getExpectedEventType(),
242 TmfTimeRange
.ETERNITY
,
243 TmfDataRequest
.ALL_DATA
,
245 ITmfDataRequest
.ExecutionType
.BACKGROUND
);
246 this.builder
= builder
;
247 this.sci
= builder
.getInputPlugin();
248 this.trace
= sci
.getTrace();
252 public void handleData(final ITmfEvent event
) {
253 super.handleData(event
);
255 if (event
.getTrace() == trace
) {
256 sci
.processEvent(event
);
262 public void handleSuccess() {
263 super.handleSuccess();
264 builder
.close(false);
268 public void handleCancel() {
269 super.handleCancel();
274 public void handleFailure() {
275 super.handleFailure();