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