693a309e3e6a687e44218e08bdf5b42730fee2d2
[deliverable/tracecompass.git] / org.eclipse.tracecompass.statesystem.core / src / org / eclipse / tracecompass / statesystem / core / StateSystemUtils.java
1 /*******************************************************************************
2 * Copyright (c) 2014 École Polytechnique de Montréal
3 *
4 * All rights reserved. This program and the accompanying materials are
5 * made available under the terms of the Eclipse Public License v1.0 which
6 * accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
8 *
9 * Contributors:
10 * Geneviève Bastien - Initial API and implementation
11 * Alexandre Montplaisir - Initial API and implementation
12 *******************************************************************************/
13
14 package org.eclipse.tracecompass.statesystem.core;
15
16 import java.util.ArrayList;
17 import java.util.LinkedList;
18 import java.util.List;
19
20 import org.eclipse.core.runtime.IProgressMonitor;
21 import org.eclipse.core.runtime.NullProgressMonitor;
22 import org.eclipse.jdt.annotation.NonNullByDefault;
23 import org.eclipse.jdt.annotation.Nullable;
24 import org.eclipse.tracecompass.statesystem.core.exceptions.AttributeNotFoundException;
25 import org.eclipse.tracecompass.statesystem.core.exceptions.StateSystemDisposedException;
26 import org.eclipse.tracecompass.statesystem.core.exceptions.StateValueTypeException;
27 import org.eclipse.tracecompass.statesystem.core.exceptions.TimeRangeException;
28 import org.eclipse.tracecompass.statesystem.core.interval.ITmfStateInterval;
29 import org.eclipse.tracecompass.statesystem.core.statevalue.ITmfStateValue;
30
31 /**
32 * Provide utility methods for the state system
33 *
34 * @author Geneviève Bastien
35 */
36 @NonNullByDefault
37 public final class StateSystemUtils {
38
39 private StateSystemUtils() {
40 }
41
42 /**
43 * Convenience method to query attribute stacks (created with
44 * pushAttribute()/popAttribute()). This will return the interval that is
45 * currently at the top of the stack, or 'null' if that stack is currently
46 * empty. It works similarly to querySingleState().
47 *
48 * To retrieve the other values in a stack, you can query the sub-attributes
49 * manually.
50 *
51 * @param ss
52 * The state system to query
53 * @param t
54 * The timestamp of the query
55 * @param stackAttributeQuark
56 * The top-level stack-attribute (that was the target of
57 * pushAttribute() at creation time)
58 * @return The interval that was at the top of the stack, or 'null' if the
59 * stack was empty.
60 * @throws StateValueTypeException
61 * If the target attribute is not a valid stack attribute (if it
62 * has a string value for example)
63 * @throws AttributeNotFoundException
64 * If the attribute was simply not found
65 * @throws TimeRangeException
66 * If the given timestamp is invalid
67 * @throws StateSystemDisposedException
68 * If the query is sent after the state system has been disposed
69 */
70 public static @Nullable ITmfStateInterval querySingleStackTop(ITmfStateSystem ss,
71 long t, int stackAttributeQuark)
72 throws AttributeNotFoundException, StateSystemDisposedException {
73 ITmfStateValue curStackStateValue = ss.querySingleState(t, stackAttributeQuark).getStateValue();
74
75 if (curStackStateValue.isNull()) {
76 /* There is nothing stored in this stack at this moment */
77 return null;
78 }
79 int curStackDepth = curStackStateValue.unboxInt();
80 if (curStackDepth <= 0) {
81 /*
82 * This attribute is an integer attribute, but it doesn't seem like
83 * it's used as a stack-attribute...
84 */
85 throw new StateValueTypeException();
86 }
87
88 int subAttribQuark = ss.getQuarkRelative(stackAttributeQuark, String.valueOf(curStackDepth));
89 return ss.querySingleState(t, subAttribQuark);
90 }
91
92 /**
93 * Return a list of state intervals, containing the "history" of a given
94 * attribute between timestamps t1 and t2. The list will be ordered by
95 * ascending time.
96 *
97 * Note that contrary to queryFullState(), the returned list here is in the
98 * "direction" of time (and not in the direction of attributes, as is the
99 * case with queryFullState()).
100 *
101 * @param ss
102 * The state system to query
103 * @param attributeQuark
104 * Which attribute this query is interested in
105 * @param t1
106 * Start time of the range query
107 * @param t2
108 * Target end time of the query. If t2 is greater than the end of
109 * the trace, we will return what we have up to the end of the
110 * history.
111 * @return The List of state intervals that happened between t1 and t2
112 * @throws TimeRangeException
113 * If t1 is invalid, or if t2 <= t1
114 * @throws AttributeNotFoundException
115 * If the requested quark does not exist in the model.
116 * @throws StateSystemDisposedException
117 * If the query is sent after the state system has been disposed
118 */
119 public static List<ITmfStateInterval> queryHistoryRange(ITmfStateSystem ss,
120 int attributeQuark, long t1, long t2)
121 throws AttributeNotFoundException, StateSystemDisposedException {
122
123 List<ITmfStateInterval> intervals;
124 ITmfStateInterval currentInterval;
125 long ts, tEnd;
126
127 /* Make sure the time range makes sense */
128 if (t2 < t1) {
129 throw new TimeRangeException();
130 }
131
132 /* Set the actual, valid end time of the range query */
133 if (t2 > ss.getCurrentEndTime()) {
134 tEnd = ss.getCurrentEndTime();
135 } else {
136 tEnd = t2;
137 }
138
139 /* Get the initial state at time T1 */
140 intervals = new ArrayList<>();
141 currentInterval = ss.querySingleState(t1, attributeQuark);
142 intervals.add(currentInterval);
143
144 /* Get the following state changes */
145 ts = currentInterval.getEndTime();
146 while (ts != -1 && ts < tEnd) {
147 ts++; /* To "jump over" to the next state in the history */
148 currentInterval = ss.querySingleState(ts, attributeQuark);
149 intervals.add(currentInterval);
150 ts = currentInterval.getEndTime();
151 }
152 return intervals;
153 }
154
155 /**
156 * Return the state history of a given attribute, but with at most one
157 * update per "resolution". This can be useful for populating views (where
158 * it's useless to have more than one query per pixel, for example). A
159 * progress monitor can be used to cancel the query before completion.
160 *
161 * @param ss
162 * The state system to query
163 * @param attributeQuark
164 * Which attribute this query is interested in
165 * @param t1
166 * Start time of the range query
167 * @param t2
168 * Target end time of the query. If t2 is greater than the end of
169 * the trace, we will return what we have up to the end of the
170 * history.
171 * @param resolution
172 * The "step" of this query
173 * @param monitor
174 * A progress monitor. If the monitor is canceled during a query,
175 * we will return what has been found up to that point. You can
176 * use "null" if you do not want to use one.
177 * @return The List of states that happened between t1 and t2
178 * @throws TimeRangeException
179 * If t1 is invalid, if t2 <= t1, or if the resolution isn't
180 * greater than zero.
181 * @throws AttributeNotFoundException
182 * If the attribute doesn't exist
183 * @throws StateSystemDisposedException
184 * If the query is sent after the state system has been disposed
185 */
186 public static List<ITmfStateInterval> queryHistoryRange(ITmfStateSystem ss,
187 int attributeQuark, long t1, long t2, long resolution,
188 @Nullable IProgressMonitor monitor)
189 throws AttributeNotFoundException, StateSystemDisposedException {
190 List<ITmfStateInterval> intervals = new LinkedList<>();
191 ITmfStateInterval currentInterval = null;
192 long ts, tEnd;
193
194 /* Make sure the time range makes sense */
195 if (t2 < t1 || resolution <= 0) {
196 throw new TimeRangeException();
197 }
198
199 /* Set the actual, valid end time of the range query */
200 if (t2 > ss.getCurrentEndTime()) {
201 tEnd = ss.getCurrentEndTime();
202 } else {
203 tEnd = t2;
204 }
205
206 IProgressMonitor mon = monitor;
207 if (mon == null) {
208 mon = new NullProgressMonitor();
209 }
210
211 /*
212 * Iterate over the "resolution points". We skip unneeded queries in the
213 * case the current interval is longer than the resolution.
214 */
215 for (ts = t1; ts <= tEnd; ts += ((currentInterval.getEndTime() - ts) / resolution + 1) * resolution) {
216 if (mon.isCanceled()) {
217 return intervals;
218 }
219 currentInterval = ss.querySingleState(ts, attributeQuark);
220 intervals.add(currentInterval);
221 }
222
223 /* Add the interval at t2, if it wasn't included already. */
224 if (currentInterval != null && currentInterval.getEndTime() < tEnd) {
225 currentInterval = ss.querySingleState(tEnd, attributeQuark);
226 intervals.add(currentInterval);
227 }
228 return intervals;
229 }
230
231 /**
232 * Queries intervals in the state system for a given attribute, starting at
233 * time t1, until we obtain a non-null value.
234 *
235 * @param ss
236 * The state system on which to query intervals
237 * @param attributeQuark
238 * The attribute quark to query
239 * @param t1
240 * Start time of the query
241 * @param t2
242 * Time limit of the query. Use {@link Long#MAX_VALUE} for no
243 * limit.
244 * @return The first interval from t1 for which the value is not a null
245 * value, or <code>null</code> if no interval was found once we
246 * reach either t2 or the end time of the state system.
247 */
248 public static @Nullable ITmfStateInterval queryUntilNonNullValue(ITmfStateSystem ss,
249 int attributeQuark, long t1, long t2) {
250
251 long current = t1;
252 /* Make sure the range is ok */
253 if (t1 < ss.getStartTime()) {
254 current = ss.getStartTime();
255 }
256 long end = t2;
257 if (end < ss.getCurrentEndTime()) {
258 end = ss.getCurrentEndTime();
259 }
260 /* Make sure the time range makes sense */
261 if (end < current) {
262 return null;
263 }
264
265 try {
266 while (current < t2) {
267 ITmfStateInterval currentInterval = ss.querySingleState(current, attributeQuark);
268 ITmfStateValue value = currentInterval.getStateValue();
269
270 if (!value.isNull()) {
271 return currentInterval;
272 }
273 current = currentInterval.getEndTime() + 1;
274 }
275 } catch (AttributeNotFoundException | StateSystemDisposedException | TimeRangeException e) {
276 /* Nothing to do */
277 }
278 return null;
279 }
280
281 }
This page took 0.040863 seconds and 4 git commands to generate.