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