Commit | Line | Data |
---|---|---|
6e71ce46 | 1 | /******************************************************************************* |
61759503 | 2 | * Copyright (c) 2012, 2013 Ericsson |
6e71ce46 AM |
3 | * Copyright (c) 2010, 2011 École Polytechnique de Montréal |
4 | * Copyright (c) 2010, 2011 Alexandre Montplaisir <alexandre.montplaisir@gmail.com> | |
83134537 | 5 | * |
6e71ce46 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 | * |
6e71ce46 AM |
11 | *******************************************************************************/ |
12 | ||
13 | package org.eclipse.linuxtools.tmf.core.statesystem; | |
14 | ||
15 | import java.io.File; | |
16 | import java.io.IOException; | |
17 | ||
2ab9afbc | 18 | import org.eclipse.linuxtools.internal.tmf.core.statesystem.HistoryBuilder; |
7e634be6 | 19 | import org.eclipse.linuxtools.internal.tmf.core.statesystem.StateSystem; |
f9a76cac AM |
20 | import org.eclipse.linuxtools.internal.tmf.core.statesystem.backends.IStateHistoryBackend; |
21 | import org.eclipse.linuxtools.internal.tmf.core.statesystem.backends.InMemoryBackend; | |
22 | import org.eclipse.linuxtools.internal.tmf.core.statesystem.backends.NullBackend; | |
23 | import org.eclipse.linuxtools.internal.tmf.core.statesystem.backends.historytree.HistoryTreeBackend; | |
24 | import org.eclipse.linuxtools.internal.tmf.core.statesystem.backends.historytree.ThreadedHistoryTreeBackend; | |
1b9d3765 AM |
25 | import org.eclipse.linuxtools.internal.tmf.core.statesystem.backends.partial.PartialHistoryBackend; |
26 | import org.eclipse.linuxtools.internal.tmf.core.statesystem.backends.partial.PartialStateSystem; | |
6e71ce46 AM |
27 | import org.eclipse.linuxtools.tmf.core.component.TmfComponent; |
28 | import org.eclipse.linuxtools.tmf.core.exceptions.TmfTraceException; | |
6e71ce46 AM |
29 | |
30 | /** | |
3f436e7c AM |
31 | * This class handles loading or creating state history files for use in TMF's |
32 | * generic state system. | |
83134537 | 33 | * |
2cb26548 | 34 | * @author Alexandre Montplaisir |
3f436e7c | 35 | * @since 2.0 |
cf564892 AM |
36 | * |
37 | * @deprecated Building state systems should now be done via | |
38 | * {@link TmfStateSystemAnalysisModule} | |
6e71ce46 | 39 | */ |
cf564892 | 40 | @Deprecated |
3f436e7c AM |
41 | public final class TmfStateSystemFactory extends TmfComponent { |
42 | ||
43 | /** "static" class */ | |
44 | private TmfStateSystemFactory() {} | |
6e71ce46 AM |
45 | |
46 | /** Size of the blocking queue to use when building a state history */ | |
cb42195c | 47 | private static final int QUEUE_SIZE = 10000; |
6e71ce46 AM |
48 | |
49 | /** | |
50 | * Load the history file matching the target trace. If the file already | |
51 | * exists, it will be opened directly. If not, it will be created from | |
52 | * scratch. In the case the history has to be built, it's possible to block | |
53 | * the calling thread until construction is complete. | |
83134537 | 54 | * |
6e71ce46 AM |
55 | * @param htFile |
56 | * The target name of the history file we want to use. If it | |
57 | * exists it will be opened. If it doesn't, a new file will be | |
58 | * created with this name/path. | |
0fe46f2a AM |
59 | * @param stateProvider |
60 | * The {@link ITmfStateProvider} to use for building the history | |
61 | * file. It may be required even if we are opening an | |
62 | * already-existing history (ie, for partial histories). | |
e34f7caa AM |
63 | * @param buildManually |
64 | * If false, the construction will wait for a signal before | |
65 | * starting. If true, it will build everything right now and | |
66 | * block the caller. It has no effect if the file already exists. | |
6e71ce46 AM |
67 | * @return A IStateSystemQuerier handler to the state system, with which you |
68 | * can then run queries on the history. | |
69 | * @throws TmfTraceException | |
5df842b3 AM |
70 | * If there was a problem reading or writing one of the files. |
71 | * See the contents of this exception for more info. | |
f1f86dfb | 72 | * @since 2.0 |
6e71ce46 | 73 | */ |
3f436e7c | 74 | public static ITmfStateSystem newFullHistory(File htFile, |
0fe46f2a | 75 | ITmfStateProvider stateProvider, boolean buildManually) |
51e216bd | 76 | throws TmfTraceException { |
6e71ce46 | 77 | IStateHistoryBackend htBackend; |
51e216bd | 78 | |
6e71ce46 AM |
79 | /* If the target file already exists, do not rebuild it uselessly */ |
80 | // TODO for now we assume it's complete. Might be a good idea to check | |
81 | // at least if its range matches the trace's range. | |
82 | if (htFile.exists()) { | |
83 | /* Load an existing history */ | |
0fe46f2a AM |
84 | final int version = (stateProvider == null) ? |
85 | ITmfStateProvider.IGNORE_PROVIDER_VERSION : | |
86 | stateProvider.getVersion(); | |
6e71ce46 | 87 | try { |
a96cc6be | 88 | htBackend = new HistoryTreeBackend(htFile, version); |
cb42195c | 89 | return HistoryBuilder.openExistingHistory(htBackend); |
6e71ce46 AM |
90 | } catch (IOException e) { |
91 | /* | |
92 | * There was an error opening the existing file. Perhaps it was | |
93 | * corrupted, perhaps it's an old version? We'll just | |
94 | * fall-through and try to build a new one from scratch instead. | |
95 | */ | |
96 | } | |
97 | } | |
98 | ||
99 | /* Create a new state history from scratch */ | |
100 | HistoryBuilder builder; | |
51e216bd | 101 | |
0fe46f2a | 102 | if (stateProvider == null) { |
6e71ce46 AM |
103 | return null; |
104 | } | |
105 | try { | |
a96cc6be | 106 | htBackend = new ThreadedHistoryTreeBackend(htFile, |
0fe46f2a | 107 | stateProvider.getStartTime(), stateProvider.getVersion(), QUEUE_SIZE); |
7e634be6 | 108 | StateSystem ss = new StateSystem(htBackend); |
0fe46f2a AM |
109 | stateProvider.assignTargetStateSystem(ss); |
110 | builder = new HistoryBuilder(stateProvider, ss, htBackend, buildManually); | |
6e71ce46 | 111 | } catch (IOException e) { |
51e216bd AM |
112 | /* |
113 | * If it fails here however, it means there was a problem writing to | |
114 | * the disk, so throw a real exception this time. | |
6e71ce46 AM |
115 | */ |
116 | throw new TmfTraceException(e.toString(), e); | |
117 | } | |
118 | return builder.getStateSystemQuerier(); | |
119 | } | |
f9a76cac AM |
120 | |
121 | /** | |
122 | * Create a new state system using a null history back-end. This means that | |
123 | * no history intervals will be saved anywhere, and as such only | |
124 | * {@link ITmfStateSystem#queryOngoingState} will be available. | |
125 | * | |
126 | * This has to be built "manually" (which means you should call | |
0fe46f2a | 127 | * stateProvider.processEvent() to update the ongoing state of the state system). |
f9a76cac | 128 | * |
0fe46f2a AM |
129 | * @param stateProvider |
130 | * The state provider plugin to build the history | |
f9a76cac AM |
131 | * @return Reference to the history-less state system that got built |
132 | * @since 2.0 | |
133 | */ | |
0fe46f2a | 134 | public static ITmfStateSystem newNullHistory(ITmfStateProvider stateProvider) { |
f9a76cac | 135 | IStateHistoryBackend backend = new NullBackend(); |
7e634be6 | 136 | StateSystem ss = new StateSystem(backend); |
0fe46f2a | 137 | stateProvider.assignTargetStateSystem(ss); |
7e634be6 | 138 | |
0fe46f2a | 139 | HistoryBuilder builder = new HistoryBuilder(stateProvider, ss, backend, true); |
7e634be6 | 140 | return builder.getStateSystemQuerier(); |
f9a76cac AM |
141 | } |
142 | ||
143 | /** | |
144 | * Create a new state system using in-memory interval storage. This should | |
145 | * only be done for very small state system, and will be naturally limited | |
146 | * to 2^31 intervals. | |
147 | * | |
148 | * This will block the caller while the construction is ongoing. | |
149 | * | |
0fe46f2a AM |
150 | * @param stateProvider |
151 | * The sstateProvider to use | |
f9a76cac AM |
152 | * @param buildManually |
153 | * Set to true to block the caller and build without using TMF | |
154 | * signals (for test programs most of the time). Use false if you | |
155 | * are using the TMF facilities (experiments, etc.) | |
156 | * @return Reference to the state system that just got built | |
157 | * @since 2.0 | |
158 | */ | |
0fe46f2a | 159 | public static ITmfStateSystem newInMemHistory(ITmfStateProvider stateProvider, |
f9a76cac | 160 | boolean buildManually) { |
0fe46f2a | 161 | IStateHistoryBackend backend = new InMemoryBackend(stateProvider.getStartTime()); |
7e634be6 | 162 | StateSystem ss = new StateSystem(backend); |
0fe46f2a | 163 | stateProvider.assignTargetStateSystem(ss); |
7e634be6 | 164 | |
0fe46f2a | 165 | HistoryBuilder builder = new HistoryBuilder(stateProvider, ss, backend, buildManually); |
f9a76cac AM |
166 | return builder.getStateSystemQuerier(); |
167 | } | |
1b9d3765 AM |
168 | |
169 | /** | |
170 | * Create a new state system backed with a partial history. A partial | |
171 | * history is similar to a "full" one (which you get with | |
3f436e7c | 172 | * {@link #newFullHistory}), except that the file on disk is much smaller, |
1b9d3765 AM |
173 | * but queries are a bit slower. |
174 | * | |
175 | * Also note that single-queries are implemented using a full-query | |
176 | * underneath, (which are much slower), so this might not be a good fit for | |
177 | * a use case where you have to do lots of single queries. | |
178 | * | |
179 | * @param htFile | |
180 | * The target file of the history. Since they are usually quick | |
181 | * to build, it will overwrite any existing file, without trying | |
182 | * to re-open it. | |
0fe46f2a AM |
183 | * @param realStateProvider |
184 | * The state provider to use to build this history. | |
1b9d3765 AM |
185 | * @param buildManually |
186 | * Indicates if you want to build the state system in-band | |
187 | * ('true', for unit tests for example), or to not block the | |
188 | * caller and start the build once the RangeUpdated signal. | |
189 | * @return Reference to the newly constructed state system | |
190 | * @throws TmfTraceException | |
191 | * If the history file could not be created | |
192 | * @since 2.0 | |
193 | */ | |
194 | public static ITmfStateSystem newPartialHistory(File htFile, | |
0fe46f2a AM |
195 | ITmfStateProvider realStateProvider, boolean buildManually) |
196 | throws TmfTraceException { | |
1b9d3765 AM |
197 | /* |
198 | * The order of initializations is very tricky (but very important!) | |
199 | * here. We need to follow this pattern: | |
200 | * (1 is done before the call to this method) | |
201 | * | |
0fe46f2a | 202 | * 1- Instantiate realStateProvider |
1b9d3765 AM |
203 | * 2- Instantiate realBackend |
204 | * 3- Instantiate partialBackend, whith prereqs: | |
0fe46f2a | 205 | * 3a- Instantiate partialProvider, via realProvider.getNew() |
1b9d3765 AM |
206 | * 3b- Instantiate nullBackend (partialSS's backend) |
207 | * 3c- Instantiate partialSS | |
0fe46f2a | 208 | * 3d- partialProvider.assignSS(partialSS) |
1b9d3765 AM |
209 | * 4- Instantiate realSS |
210 | * 5- partialSS.assignUpstream(realSS) | |
0fe46f2a AM |
211 | * 6- realProvider.assignSS(realSS) |
212 | * 7- Call HistoryBuilder(realProvider, realSS, partialBackend) to build the thing. | |
1b9d3765 AM |
213 | */ |
214 | ||
215 | final long granularity = 50000; | |
216 | ||
217 | /* 2 */ | |
218 | IStateHistoryBackend realBackend = null; | |
219 | try { | |
220 | realBackend = new ThreadedHistoryTreeBackend(htFile, | |
0fe46f2a | 221 | realStateProvider.getStartTime(), realStateProvider.getVersion(), QUEUE_SIZE); |
1b9d3765 AM |
222 | } catch (IOException e) { |
223 | throw new TmfTraceException(e.toString(), e); | |
224 | } | |
225 | ||
226 | /* 3a */ | |
0fe46f2a | 227 | ITmfStateProvider partialProvider = realStateProvider.getNewInstance(); |
1b9d3765 AM |
228 | |
229 | /* 3b-3c, constructor automatically uses a NullBackend */ | |
230 | PartialStateSystem pss = new PartialStateSystem(); | |
231 | ||
232 | /* 3d */ | |
0fe46f2a | 233 | partialProvider.assignTargetStateSystem(pss); |
1b9d3765 AM |
234 | |
235 | /* 3 */ | |
236 | IStateHistoryBackend partialBackend = | |
0fe46f2a | 237 | new PartialHistoryBackend(partialProvider, pss, realBackend, granularity); |
1b9d3765 AM |
238 | |
239 | /* 4 */ | |
240 | StateSystem realSS = new StateSystem(partialBackend); | |
241 | ||
242 | /* 5 */ | |
243 | pss.assignUpstream(realSS); | |
244 | ||
245 | /* 6 */ | |
0fe46f2a | 246 | realStateProvider.assignTargetStateSystem(realSS); |
1b9d3765 AM |
247 | |
248 | /* 7 */ | |
0fe46f2a | 249 | HistoryBuilder builder = new HistoryBuilder(realStateProvider, realSS, partialBackend, buildManually); |
1b9d3765 AM |
250 | return builder.getStateSystemQuerier(); |
251 | } | |
6e71ce46 | 252 | } |