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
.tmf
.core
.statesystem
;
16 import java
.io
.IOException
;
18 import org
.eclipse
.linuxtools
.internal
.tmf
.core
.statesystem
.HistoryBuilder
;
19 import org
.eclipse
.linuxtools
.internal
.tmf
.core
.statesystem
.StateSystem
;
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
;
25 import org
.eclipse
.linuxtools
.internal
.tmf
.core
.statesystem
.backends
.partial
.PartialHistoryBackend
;
26 import org
.eclipse
.linuxtools
.internal
.tmf
.core
.statesystem
.backends
.partial
.PartialStateSystem
;
27 import org
.eclipse
.linuxtools
.tmf
.core
.component
.TmfComponent
;
28 import org
.eclipse
.linuxtools
.tmf
.core
.exceptions
.TmfTraceException
;
31 * This class handles loading or creating state history files for use in TMF's
32 * generic state system.
34 * @author Alexandre Montplaisir
37 * @deprecated Building state systems should now be done via
38 * {@link TmfStateSystemAnalysisModule}
41 public final class TmfStateSystemFactory
extends TmfComponent
{
44 private TmfStateSystemFactory() {}
46 /** Size of the blocking queue to use when building a state history */
47 private static final int QUEUE_SIZE
= 10000;
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.
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.
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).
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.
67 * @return A IStateSystemQuerier handler to the state system, with which you
68 * can then run queries on the history.
69 * @throws TmfTraceException
70 * If there was a problem reading or writing one of the files.
71 * See the contents of this exception for more info.
74 public static ITmfStateSystem
newFullHistory(File htFile
,
75 ITmfStateProvider stateProvider
, boolean buildManually
)
76 throws TmfTraceException
{
77 IStateHistoryBackend htBackend
;
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 */
84 final int version
= (stateProvider
== null) ?
85 ITmfStateProvider
.IGNORE_PROVIDER_VERSION
:
86 stateProvider
.getVersion();
88 htBackend
= new HistoryTreeBackend(htFile
, version
);
89 return HistoryBuilder
.openExistingHistory(htBackend
);
90 } catch (IOException e
) {
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.
99 /* Create a new state history from scratch */
100 HistoryBuilder builder
;
102 if (stateProvider
== null) {
106 htBackend
= new ThreadedHistoryTreeBackend(htFile
,
107 stateProvider
.getStartTime(), stateProvider
.getVersion(), QUEUE_SIZE
);
108 StateSystem ss
= new StateSystem(htBackend
);
109 stateProvider
.assignTargetStateSystem(ss
);
110 builder
= new HistoryBuilder(stateProvider
, ss
, htBackend
, buildManually
);
111 } catch (IOException e
) {
113 * If it fails here however, it means there was a problem writing to
114 * the disk, so throw a real exception this time.
116 throw new TmfTraceException(e
.toString(), e
);
118 return builder
.getStateSystemQuerier();
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.
126 * This has to be built "manually" (which means you should call
127 * stateProvider.processEvent() to update the ongoing state of the state system).
129 * @param stateProvider
130 * The state provider plugin to build the history
131 * @return Reference to the history-less state system that got built
134 public static ITmfStateSystem
newNullHistory(ITmfStateProvider stateProvider
) {
135 IStateHistoryBackend backend
= new NullBackend();
136 StateSystem ss
= new StateSystem(backend
);
137 stateProvider
.assignTargetStateSystem(ss
);
139 HistoryBuilder builder
= new HistoryBuilder(stateProvider
, ss
, backend
, true);
140 return builder
.getStateSystemQuerier();
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
148 * This will block the caller while the construction is ongoing.
150 * @param stateProvider
151 * The sstateProvider to use
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
159 public static ITmfStateSystem
newInMemHistory(ITmfStateProvider stateProvider
,
160 boolean buildManually
) {
161 IStateHistoryBackend backend
= new InMemoryBackend(stateProvider
.getStartTime());
162 StateSystem ss
= new StateSystem(backend
);
163 stateProvider
.assignTargetStateSystem(ss
);
165 HistoryBuilder builder
= new HistoryBuilder(stateProvider
, ss
, backend
, buildManually
);
166 return builder
.getStateSystemQuerier();
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
172 * {@link #newFullHistory}), except that the file on disk is much smaller,
173 * but queries are a bit slower.
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.
180 * The target file of the history. Since they are usually quick
181 * to build, it will overwrite any existing file, without trying
183 * @param realStateProvider
184 * The state provider to use to build this history.
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
194 public static ITmfStateSystem
newPartialHistory(File htFile
,
195 ITmfStateProvider realStateProvider
, boolean buildManually
)
196 throws TmfTraceException
{
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)
202 * 1- Instantiate realStateProvider
203 * 2- Instantiate realBackend
204 * 3- Instantiate partialBackend, whith prereqs:
205 * 3a- Instantiate partialProvider, via realProvider.getNew()
206 * 3b- Instantiate nullBackend (partialSS's backend)
207 * 3c- Instantiate partialSS
208 * 3d- partialProvider.assignSS(partialSS)
209 * 4- Instantiate realSS
210 * 5- partialSS.assignUpstream(realSS)
211 * 6- realProvider.assignSS(realSS)
212 * 7- Call HistoryBuilder(realProvider, realSS, partialBackend) to build the thing.
215 final long granularity
= 50000;
218 IStateHistoryBackend realBackend
= null;
220 realBackend
= new ThreadedHistoryTreeBackend(htFile
,
221 realStateProvider
.getStartTime(), realStateProvider
.getVersion(), QUEUE_SIZE
);
222 } catch (IOException e
) {
223 throw new TmfTraceException(e
.toString(), e
);
227 ITmfStateProvider partialProvider
= realStateProvider
.getNewInstance();
229 /* 3b-3c, constructor automatically uses a NullBackend */
230 PartialStateSystem pss
= new PartialStateSystem();
233 partialProvider
.assignTargetStateSystem(pss
);
236 IStateHistoryBackend partialBackend
=
237 new PartialHistoryBackend(partialProvider
, pss
, realBackend
, granularity
);
240 StateSystem realSS
= new StateSystem(partialBackend
);
243 pss
.assignUpstream(realSS
);
246 realStateProvider
.assignTargetStateSystem(realSS
);
249 HistoryBuilder builder
= new HistoryBuilder(realStateProvider
, realSS
, partialBackend
, buildManually
);
250 return builder
.getStateSystemQuerier();