Commit | Line | Data |
---|---|---|
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 | 13 | package org.eclipse.linuxtools.internal.tmf.core.statesystem; |
a52fde77 AM |
14 | |
15 | import java.io.IOException; | |
16 | ||
83134537 AM |
17 | import org.eclipse.linuxtools.tmf.core.component.TmfComponent; |
18 | import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; | |
2c2f900e AM |
19 | import org.eclipse.linuxtools.tmf.core.event.TmfTimeRange; |
20 | import org.eclipse.linuxtools.tmf.core.request.ITmfDataRequest; | |
2c2f900e AM |
21 | import org.eclipse.linuxtools.tmf.core.request.TmfDataRequest; |
22 | import org.eclipse.linuxtools.tmf.core.request.TmfEventRequest; | |
47242394 | 23 | import org.eclipse.linuxtools.tmf.core.signal.TmfExperimentRangeUpdatedSignal; |
83134537 AM |
24 | import org.eclipse.linuxtools.tmf.core.signal.TmfSignal; |
25 | import org.eclipse.linuxtools.tmf.core.signal.TmfSignalHandler; | |
26 | import org.eclipse.linuxtools.tmf.core.signal.TmfSignalManager; | |
27 | import org.eclipse.linuxtools.tmf.core.signal.TmfStateSystemBuildCompleted; | |
2ab9afbc AM |
28 | import org.eclipse.linuxtools.tmf.core.statesystem.IStateChangeInput; |
29 | import org.eclipse.linuxtools.tmf.core.statesystem.IStateSystemBuilder; | |
30 | import org.eclipse.linuxtools.tmf.core.statesystem.IStateSystemQuerier; | |
83134537 AM |
31 | import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; |
32 | import 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 | 45 | public 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 | |
5df842b3 AM |
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 | |
63 | * start listening for the signal and return immediately. Another | |
64 | * signal will be sent when finished. | |
a52fde77 AM |
65 | * @throws IOException |
66 | * Is thrown if anything went wrong (usually with the storage | |
67 | * backend) | |
68 | */ | |
69 | public HistoryBuilder(IStateChangeInput stateChangeInput, | |
e34f7caa AM |
70 | IStateHistoryBackend backend, boolean buildManually) |
71 | throws IOException { | |
36bf82a2 AM |
72 | if (stateChangeInput == null || backend == null) { |
73 | throw new IllegalArgumentException(); | |
74 | } | |
d26f90fd AM |
75 | sci = stateChangeInput; |
76 | hb = backend; | |
8d1346f0 | 77 | ss = new StateSystem(hb, true); |
a52fde77 | 78 | |
8d1346f0 | 79 | sci.assignTargetStateSystem(ss); |
e34f7caa AM |
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 | } | |
a52fde77 AM |
88 | } |
89 | ||
d26f90fd AM |
90 | /** |
91 | * Factory-style method to open an existing history, you only have to | |
92 | * provide the already-instantiated IStateHistoryBackend object. | |
83134537 | 93 | * |
d26f90fd AM |
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 IStateSystemBuilder openExistingHistory( | |
103 | IStateHistoryBackend hb) throws IOException { | |
8d1346f0 | 104 | return new StateSystem(hb, false); |
d26f90fd AM |
105 | } |
106 | ||
a52fde77 | 107 | /** |
d26f90fd AM |
108 | * Return a read/write reference to the state system object that was |
109 | * created. | |
83134537 | 110 | * |
d26f90fd AM |
111 | * @return Reference to the state system, with access to everything. |
112 | */ | |
113 | public IStateSystemBuilder getStateSystemBuilder() { | |
8d1346f0 | 114 | return ss; |
d26f90fd AM |
115 | } |
116 | ||
117 | /** | |
118 | * Return a read-only reference to the state system object that was created. | |
83134537 | 119 | * |
d26f90fd AM |
120 | * @return Reference to the state system, but only with the query methods |
121 | * available. | |
a52fde77 | 122 | */ |
d26f90fd | 123 | public IStateSystemQuerier getStateSystemQuerier() { |
8d1346f0 | 124 | return ss; |
a52fde77 | 125 | } |
36bf82a2 | 126 | |
e34f7caa AM |
127 | /** |
128 | * Build the state history without waiting for signals or anything | |
129 | */ | |
e34f7caa AM |
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 | ||
83134537 AM |
143 | |
144 | // ------------------------------------------------------------------------ | |
145 | // Signal handlers | |
146 | // ------------------------------------------------------------------------ | |
147 | ||
148 | /** | |
149 | * Listen to the "experiment selected" signal to start the state history | |
150 | * construction. | |
151 | * | |
152 | * @param signal | |
5df842b3 AM |
153 | * The "experiment range updated" signal. Listening to this |
154 | * signal will coalesce this request with the one from the | |
155 | * indexer and histogram. | |
83134537 | 156 | */ |
83134537 | 157 | @TmfSignalHandler |
47242394 | 158 | public void experimentRangeUpdated(final TmfExperimentRangeUpdatedSignal signal) { |
83134537 | 159 | StateSystemBuildRequest request; |
6256d8ad | 160 | TmfExperiment exp; |
83134537 AM |
161 | |
162 | if (!started) { | |
163 | started = true; | |
164 | request = new StateSystemBuildRequest(this); | |
6256d8ad | 165 | exp = TmfExperiment.getCurrentExperiment(); |
83134537 AM |
166 | if (exp == null) { |
167 | return; | |
168 | } | |
169 | exp.sendRequest(request); | |
855a1bfb AM |
170 | } |
171 | } | |
172 | ||
83134537 | 173 | |
855a1bfb AM |
174 | // ------------------------------------------------------------------------ |
175 | // Methods reserved for the request object below | |
176 | // ------------------------------------------------------------------------ | |
177 | ||
36bf82a2 AM |
178 | /** Get the input plugin object */ |
179 | IStateChangeInput getInputPlugin() { | |
180 | return sci; | |
181 | } | |
83134537 AM |
182 | |
183 | void close(boolean deleteFiles) { | |
c6e5dfa0 AM |
184 | TmfSignal doneSig; |
185 | ||
83134537 AM |
186 | sci.dispose(); |
187 | if (deleteFiles) { | |
188 | hb.removeFiles(); | |
c6e5dfa0 AM |
189 | /* We won't broadcast the signal if the request was cancelled */ |
190 | } else { | |
191 | /* Broadcast the signal saying the history is done building */ | |
192 | doneSig = new TmfStateSystemBuildCompleted(this, sci.getTrace()); | |
193 | TmfSignalManager.dispatchSignal(doneSig); | |
83134537 AM |
194 | } |
195 | ||
83134537 AM |
196 | TmfSignalManager.deregister(this); |
197 | } | |
2c2f900e AM |
198 | } |
199 | ||
6256d8ad | 200 | class StateSystemBuildRequest extends TmfEventRequest { |
2c2f900e AM |
201 | |
202 | /** The amount of events queried at a time through the requests */ | |
203 | private final static int chunkSize = 50000; | |
204 | ||
83134537 | 205 | private final HistoryBuilder builder; |
2c2f900e | 206 | private final IStateChangeInput sci; |
6256d8ad | 207 | private final ITmfTrace trace; |
2c2f900e | 208 | |
36bf82a2 | 209 | StateSystemBuildRequest(HistoryBuilder builder) { |
79044a66 | 210 | super(builder.getInputPlugin().getExpectedEventType(), |
83134537 AM |
211 | TmfTimeRange.ETERNITY, |
212 | TmfDataRequest.ALL_DATA, | |
213 | chunkSize, | |
2c2f900e | 214 | ITmfDataRequest.ExecutionType.BACKGROUND); |
83134537 | 215 | this.builder = builder; |
36bf82a2 | 216 | this.sci = builder.getInputPlugin(); |
83134537 | 217 | this.trace = sci.getTrace(); |
2c2f900e | 218 | } |
a52fde77 | 219 | |
2c2f900e | 220 | @Override |
83134537 | 221 | public void handleData(final ITmfEvent event) { |
2c2f900e AM |
222 | super.handleData(event); |
223 | if (event != null) { | |
83134537 AM |
224 | if (event.getTrace() == trace) { |
225 | sci.processEvent(event); | |
226 | } | |
2c2f900e AM |
227 | } |
228 | } | |
229 | ||
230 | @Override | |
231 | public void handleSuccess() { | |
855a1bfb | 232 | super.handleSuccess(); |
83134537 | 233 | builder.close(false); |
2c2f900e AM |
234 | } |
235 | ||
36bf82a2 AM |
236 | @Override |
237 | public void handleCancel() { | |
855a1bfb | 238 | super.handleCancel(); |
83134537 | 239 | builder.close(true); |
36bf82a2 AM |
240 | } |
241 | ||
2c2f900e | 242 | @Override |
855a1bfb AM |
243 | public void handleFailure() { |
244 | super.handleFailure(); | |
83134537 | 245 | builder.close(true); |
2c2f900e | 246 | } |
a52fde77 | 247 | } |