tmf RCP: Rename extracted folder of the trace viewer
[deliverable/tracecompass.git] / org.eclipse.linuxtools.tmf.core / src / org / eclipse / linuxtools / internal / tmf / core / statesystem / TransientState.java
CommitLineData
a52fde77 1/*******************************************************************************
61759503 2 * Copyright (c) 2012, 2013 Ericsson
a52fde77
AM
3 * Copyright (c) 2010, 2011 École Polytechnique de Montréal
4 * Copyright (c) 2010, 2011 Alexandre Montplaisir <alexandre.montplaisir@gmail.com>
97042f0a 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
97042f0a 10 *
a52fde77
AM
11 *******************************************************************************/
12
18ab1d18 13package org.eclipse.linuxtools.internal.tmf.core.statesystem;
a52fde77
AM
14
15import java.io.PrintWriter;
16import java.util.ArrayList;
17import java.util.List;
18
f9a76cac 19import org.eclipse.linuxtools.internal.tmf.core.statesystem.backends.IStateHistoryBackend;
6d08acca
AM
20import org.eclipse.linuxtools.tmf.core.exceptions.AttributeNotFoundException;
21import org.eclipse.linuxtools.tmf.core.exceptions.StateValueTypeException;
22import org.eclipse.linuxtools.tmf.core.exceptions.TimeRangeException;
a52fde77
AM
23import org.eclipse.linuxtools.tmf.core.interval.ITmfStateInterval;
24import org.eclipse.linuxtools.tmf.core.interval.TmfStateInterval;
a52fde77
AM
25import org.eclipse.linuxtools.tmf.core.statevalue.ITmfStateValue;
26import org.eclipse.linuxtools.tmf.core.statevalue.TmfStateValue;
b67a2540 27import org.eclipse.linuxtools.tmf.core.statevalue.ITmfStateValue.Type;
a52fde77
AM
28
29/**
7e0b2b56 30 * The Transient State is used to build intervals from punctual state changes. It
a52fde77
AM
31 * contains a "state info" vector similar to the "current state", except here we
32 * also record the start time of every state stored in it.
97042f0a 33 *
a52fde77
AM
34 * We can then build StateInterval's, to be inserted in the State History when
35 * we detect state changes : the "start time" of the interval will be the
36 * recorded time we have here, and the "end time" will be the timestamp of the
37 * new state-changing event we just read.
97042f0a 38 *
a52fde77 39 * @author alexmont
97042f0a 40 *
a52fde77
AM
41 */
42class TransientState {
43
44 /* Indicates where to insert state changes that we generate */
45 private final IStateHistoryBackend backend;
46
47 private boolean isActive;
48 private long latestTime;
49
66866869
AM
50 private List<ITmfStateValue> ongoingStateInfo;
51 private List<Long> ongoingStateStartTimes;
b67a2540 52 private List<Type> stateValueTypes;
a52fde77
AM
53
54 TransientState(IStateHistoryBackend backend) {
55 this.backend = backend;
56 isActive = true;
a4524c1b
AM
57 ongoingStateInfo = new ArrayList<>();
58 ongoingStateStartTimes = new ArrayList<>();
59 stateValueTypes = new ArrayList<>();
a52fde77
AM
60
61 if (backend != null) {
62 latestTime = backend.getStartTime();
63 } else {
64 latestTime = 0;
65 }
66 }
67
68 long getLatestTime() {
69 return latestTime;
70 }
71
602c0697 72 ITmfStateValue getOngoingStateValue(int index) throws AttributeNotFoundException {
a52fde77
AM
73 checkValidAttribute(index);
74 return ongoingStateInfo.get(index);
75 }
76
602c0697
AM
77 long getOngoingStartTime(int index) throws AttributeNotFoundException {
78 checkValidAttribute(index);
79 return ongoingStateStartTimes.get(index);
80 }
81
a52fde77
AM
82 void changeOngoingStateValue(int index, ITmfStateValue newValue)
83 throws AttributeNotFoundException {
a52fde77
AM
84 checkValidAttribute(index);
85 ongoingStateInfo.set(index, newValue);
86 }
87
88 /**
89 * Return the "ongoing" value for a given attribute as a dummy interval
90 * whose end time = -1 (since we don't know its real end time yet).
97042f0a 91 *
a52fde77
AM
92 * @param quark
93 * @throws AttributeNotFoundException
94 */
602c0697 95 ITmfStateInterval getOngoingInterval(int quark) throws AttributeNotFoundException {
a52fde77
AM
96 checkValidAttribute(quark);
97 return new TmfStateInterval(ongoingStateStartTimes.get(quark), -1, quark,
98 ongoingStateInfo.get(quark));
99 }
100
602c0697 101 private void checkValidAttribute(int quark) throws AttributeNotFoundException {
a52fde77
AM
102 if (quark > ongoingStateInfo.size() - 1 || quark < 0) {
103 throw new AttributeNotFoundException();
104 }
105 }
106
107 /**
66866869
AM
108 * More advanced version of {@link #changeOngoingStateValue}. Replaces the
109 * complete {@link #ongoingStateInfo} in one go, and updates the
110 * {@link #ongoingStateStartTimes} and {@link #stateValuesTypes}
111 * accordingly. BE VERY CAREFUL WITH THIS!
97042f0a 112 *
66866869
AM
113 * @param newStateIntervals
114 * The List of intervals that will represent the new
115 * "ongoing state". Their end times don't matter, we will only
116 * check their value and start times.
a52fde77 117 */
66866869
AM
118 synchronized void replaceOngoingState(List<ITmfStateInterval> newStateIntervals) {
119 int size = newStateIntervals.size();
a4524c1b
AM
120 ongoingStateInfo = new ArrayList<>(size);
121 ongoingStateStartTimes = new ArrayList<>(size);
122 stateValueTypes = new ArrayList<>(size);
66866869
AM
123
124 for (ITmfStateInterval interval : newStateIntervals) {
125 ongoingStateInfo.add(interval.getStateValue());
126 ongoingStateStartTimes.add(interval.getStartTime());
127 stateValueTypes.add(interval.getStateValue().getType());
128 }
a52fde77
AM
129 }
130
131 /**
132 * Add an "empty line" to both "ongoing..." vectors. This is needed so the
133 * Ongoing... tables can stay in sync with the number of attributes in the
134 * attribute tree, namely when we add sub-path attributes.
135 */
136 synchronized void addEmptyEntry() {
137 /*
138 * Since this is a new attribute, we suppose it was in the "null state"
139 * since the beginning (so we can have intervals covering for all
140 * timestamps). A null interval will then get added at the first state
141 * change.
142 */
143 ongoingStateInfo.add(TmfStateValue.nullValue());
b67a2540 144 stateValueTypes.add(Type.NULL);
a52fde77
AM
145
146 if (backend == null) {
147 ongoingStateStartTimes.add(0L);
148 } else {
149 ongoingStateStartTimes.add(backend.getStartTime());
150 }
151 }
152
153 /**
154 * Ask if the state information about attribute 'quark' at time 'time' is
155 * present in the Builder as it is right now. If it's not, it's either in
156 * the History Tree, or not in the system at all.
97042f0a 157 *
a52fde77
AM
158 * Note that this method does not return the value itself (we don't even
159 * look for it, we can know by just looking at the timestamp)
97042f0a 160 *
a52fde77
AM
161 * @param time
162 * The timestamp to look for
163 * @param quark
164 * The quark of the attribute to look for
165 * @return True if the value is present in the Transient State at this
166 * moment in time, false if it's not
167 */
168 boolean hasInfoAboutStateOf(long time, int quark) {
169 return (this.isActive() && time >= ongoingStateStartTimes.get(quark));
170 }
171
172 /**
173 * This is the lower-level method that will be called by the
174 * StateHistorySystem (with already-built StateValues and timestamps)
97042f0a 175 *
a52fde77
AM
176 * @param index
177 * The index in the vectors (== the quark of the attribute)
178 * @param value
179 * The new StateValue associated to this attribute
180 * @param eventTime
181 * The timestamp associated with this state change
182 * @throws TimeRangeException
183 * @throws AttributeNotFoundException
97042f0a 184 * @throws StateValueTypeException
a52fde77
AM
185 */
186 synchronized void processStateChange(long eventTime,
187 ITmfStateValue value, int index) throws TimeRangeException,
7e0b2b56 188 AttributeNotFoundException, StateValueTypeException {
a52fde77 189 assert (this.isActive);
97042f0a 190
b67a2540 191 Type expectedSvType = stateValueTypes.get(index);
a52fde77 192 checkValidAttribute(index);
97042f0a
AM
193
194 /*
7e0b2b56
AM
195 * Make sure the state value type we're inserting is the same as the
196 * one registered for this attribute.
197 */
b67a2540 198 if (expectedSvType == Type.NULL) {
97042f0a 199 /*
7e0b2b56
AM
200 * The value hasn't been used yet, set it to the value
201 * we're currently inserting (which might be null/-1 again).
202 */
203 stateValueTypes.set(index, value.getType());
b67a2540 204 } else if ((value.getType() != Type.NULL) && (value.getType() != expectedSvType)) {
97042f0a 205 /*
7e0b2b56
AM
206 * We authorize inserting null values in any type of attribute,
207 * but for every other types, it needs to match our expectations!
208 */
209 throw new StateValueTypeException();
210 }
a52fde77 211
7e0b2b56 212 /* Update the Transient State's lastestTime, if needed */
a52fde77
AM
213 if (latestTime < eventTime) {
214 latestTime = eventTime;
215 }
216
217 if (ongoingStateInfo.get(index).equals(value)) {
218 /*
219 * This is the case where the new value and the one already present
220 * in the Builder are the same. We do not need to create an
221 * interval, we'll just keep the current one going.
222 */
223 return;
224 }
225
226 if (backend != null && ongoingStateStartTimes.get(index) < eventTime) {
227 /*
228 * These two conditions are necessary to create an interval and
229 * update ongoingStateInfo.
230 */
7e0b2b56 231 backend.insertPastState(ongoingStateStartTimes.get(index),
a52fde77
AM
232 eventTime - 1, /* End Time */
233 index, /* attribute quark */
234 ongoingStateInfo.get(index)); /* StateValue */
235
236 ongoingStateStartTimes.set(index, eventTime);
237 }
238 ongoingStateInfo.set(index, value);
239 return;
240 }
241
242 /**
243 * Run a "get state at time" query on the Transient State only.
97042f0a 244 *
a52fde77
AM
245 * @param stateInfo
246 * The stateInfo object in which we will put our relevant
247 * information
248 * @param t
249 * The requested timestamp
250 */
251 void doQuery(List<ITmfStateInterval> stateInfo, long t) {
252 ITmfStateInterval interval;
253
254 if (!this.isActive) {
255 return;
256 }
257 assert (stateInfo.size() == ongoingStateInfo.size());
258
259 for (int i = 0; i < ongoingStateInfo.size(); i++) {
260 /*
261 * We build a dummy interval with end time = -1 to put in the answer
262 * to the query.
263 */
264 if (this.hasInfoAboutStateOf(t, i)) {
265 interval = new TmfStateInterval(ongoingStateStartTimes.get(i), -1,
266 i, ongoingStateInfo.get(i));
267 stateInfo.set(i, interval);
268 }
269 }
270 }
271
272 /**
273 * Close off the Transient State, used for example when we are done reading a
274 * static trace file. All the information currently contained in it will be
275 * converted to intervals and "flushed" to the State History.
276 */
277 void closeTransientState(long endTime) {
278 assert (this.isActive);
279
280 for (int i = 0; i < ongoingStateInfo.size(); i++) {
e1c43333 281 if (ongoingStateStartTimes.get(i) > endTime) {
a52fde77 282 /*
faa38350 283 * Handle the cases where trace end > timestamp of last state
97042f0a 284 * change. This can happen when inserting "future" changes.
a52fde77
AM
285 */
286 continue;
287 }
288 try {
7e0b2b56 289 backend.insertPastState(ongoingStateStartTimes.get(i),
a52fde77
AM
290 endTime, /* End Time */
291 i, /* attribute quark */
292 ongoingStateInfo.get(i)); /* StateValue */
293
294 } catch (TimeRangeException e) {
295 /*
296 * This shouldn't happen, since we control where the interval's
297 * start time comes from
298 */
cb42195c 299 throw new IllegalStateException(e);
a52fde77
AM
300 }
301 }
302
303 ongoingStateInfo.clear();
304 ongoingStateStartTimes.clear();
305 this.isActive = false;
306 return;
307 }
308
309 /**
310 * Simply returns if this Transient State is currently being used or not
97042f0a 311 *
a52fde77
AM
312 * @return
313 */
314 boolean isActive() {
315 return this.isActive;
316 }
317
318 void setInactive() {
319 isActive = false;
320 }
321
322 /**
323 * Debugging method that prints the contents of both 'ongoing...' vectors
97042f0a 324 *
a52fde77
AM
325 * @param writer
326 */
327 void debugPrint(PrintWriter writer) {
328 /* Only used for debugging, shouldn't be externalized */
329 writer.println("------------------------------"); //$NON-NLS-1$
330 writer.println("Info stored in the Builder:"); //$NON-NLS-1$
331 if (!this.isActive) {
332 writer.println("Builder is currently inactive"); //$NON-NLS-1$
333 writer.println('\n');
334 return;
335 }
336 writer.println("\nAttribute\tStateValue\tValid since time"); //$NON-NLS-1$
337 for (int i = 0; i < ongoingStateInfo.size(); i++) {
338 writer.format("%d\t\t", i); //$NON-NLS-1$
339 writer.print(ongoingStateInfo.get(i).toString() + "\t\t"); //$NON-NLS-1$
340 writer.println(ongoingStateStartTimes.get(i).toString());
341 }
342 writer.println('\n');
343 return;
344 }
345
faa38350 346}
This page took 0.054046 seconds and 5 git commands to generate.