tmf: Move plugins to their own sub-directory
[deliverable/tracecompass.git] / tmf / org.eclipse.tracecompass.tmf.core / src / org / eclipse / tracecompass / internal / tmf / core / statesystem / mipmap / TmfStateSystemOperations.java
1 /*******************************************************************************
2 * Copyright (c) 2013, 2015 Ericsson
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 * Jean-Christian Kouamé - Initial API and implementation
11 * Patrick Tasse - Updates to mipmap feature
12 ******************************************************************************/
13
14 package org.eclipse.tracecompass.internal.tmf.core.statesystem.mipmap;
15
16 import java.util.ArrayList;
17 import java.util.List;
18
19 import org.eclipse.tracecompass.statesystem.core.ITmfStateSystem;
20 import org.eclipse.tracecompass.statesystem.core.StateSystemUtils;
21 import org.eclipse.tracecompass.statesystem.core.exceptions.AttributeNotFoundException;
22 import org.eclipse.tracecompass.statesystem.core.exceptions.StateSystemDisposedException;
23 import org.eclipse.tracecompass.statesystem.core.exceptions.StateValueTypeException;
24 import org.eclipse.tracecompass.statesystem.core.exceptions.TimeRangeException;
25 import org.eclipse.tracecompass.statesystem.core.interval.ITmfStateInterval;
26 import org.eclipse.tracecompass.statesystem.core.statevalue.ITmfStateValue;
27 import org.eclipse.tracecompass.statesystem.core.statevalue.ITmfStateValue.Type;
28 import org.eclipse.tracecompass.statesystem.core.statevalue.TmfStateValue;
29
30
31 /**
32 * This class implements additional statistical operations that can be
33 * performed on attributes of the state system.
34 *
35 * @author Patrick Tassé
36 */
37 public final class TmfStateSystemOperations {
38
39 private TmfStateSystemOperations() {}
40
41 /**
42 * Return the maximum value of an attribute over a time range
43 *
44 * @param ss
45 * The state system to query
46 * @param t1
47 * The start time of the range
48 * @param t2
49 * The end time of the range
50 * @param quark
51 * The quark of the attribute
52 * @return The maximum value of the attribute in this range
53 * @throws TimeRangeException
54 * If an invalid time range is specified
55 * @throws AttributeNotFoundException
56 * If the specified quark doesn't match an attribute
57 * @throws StateValueTypeException
58 * If the state value type of the attribute does not support the
59 * "Max" operation
60 */
61 public static ITmfStateValue queryRangeMax(ITmfStateSystem ss, long t1, long t2, int quark)
62 throws AttributeNotFoundException, TimeRangeException, StateValueTypeException {
63 ITmfStateValue max = TmfStateValue.nullValue();
64
65 List<ITmfStateInterval> intervals = queryAttributeRange(ss, t1, t2, quark, AbstractTmfMipmapStateProvider.MAX_STRING);
66 if (intervals.size() == 0) {
67 return TmfStateValue.nullValue();
68 }
69 for (ITmfStateInterval si : intervals) {
70 ITmfStateValue value = si.getStateValue();
71
72 switch (value.getType()) {
73 case DOUBLE:
74 if (max.isNull() || si.getStateValue().unboxDouble() > max.unboxDouble()) {
75 max = si.getStateValue();
76 }
77 break;
78
79 case INTEGER:
80 case LONG:
81 if (max.isNull() || si.getStateValue().unboxLong() > max.unboxLong()) {
82 max = si.getStateValue();
83 }
84 break;
85
86 case NULL:
87 case STRING:
88 default:
89 throw new StateValueTypeException(ss.getSSID() + " Quark:" + quark + ", Type:" + value.getType()); //$NON-NLS-1$ //$NON-NLS-2$
90 }
91 }
92 return max;
93 }
94
95 /**
96 * Return the minimum value of an attribute over a time range
97 *
98 * @param ss
99 * The state system to query
100 * @param t1
101 * The start time of the range
102 * @param t2
103 * The end time of the range
104 * @param quark
105 * The quark of the attribute
106 * @return The minimum value of the attribute in this range
107 * @throws TimeRangeException
108 * If an invalid time range is specified
109 * @throws AttributeNotFoundException
110 * If the specified quark doesn't match an attribute
111 * @throws StateValueTypeException
112 * If the state value type of the attribute does not support the
113 * "Min" operation
114 */
115 public static ITmfStateValue queryRangeMin(ITmfStateSystem ss,
116 long t1, long t2, int quark)
117 throws AttributeNotFoundException, TimeRangeException, StateValueTypeException {
118 ITmfStateValue min = TmfStateValue.nullValue();
119
120 List<ITmfStateInterval> intervals = queryAttributeRange(ss, t1, t2, quark, AbstractTmfMipmapStateProvider.MIN_STRING);
121 if (intervals.size() == 0) {
122 return TmfStateValue.nullValue();
123 }
124 for (ITmfStateInterval si : intervals) {
125 ITmfStateValue value = si.getStateValue();
126
127 switch (value.getType()) {
128 case DOUBLE:
129 if (min.isNull() || si.getStateValue().unboxDouble() < min.unboxDouble()) {
130 min = si.getStateValue();
131 }
132 break;
133
134 case INTEGER:
135 case LONG:
136 if (min.isNull() || si.getStateValue().unboxLong() < min.unboxLong()) {
137 min = si.getStateValue();
138 }
139 break;
140
141 case NULL:
142 case STRING:
143 default:
144 throw new StateValueTypeException(ss.getSSID() + " Quark:" + quark + ", Type:" + value.getType()); //$NON-NLS-1$ //$NON-NLS-2$
145 }
146 }
147 return min;
148 }
149
150 /**
151 * Return the weighted average value of an attribute over a time range
152 *
153 * @param ss
154 * The state system to query
155 * @param t1
156 * The start time of the range
157 * @param t2
158 * The end time of the range
159 * @param quark
160 * The quark of the attribute
161 * @return The weighted average value of the attribute in this range
162 * @throws TimeRangeException
163 * If an invalid time range is specified
164 * @throws AttributeNotFoundException
165 * If the specified quark doesn't match an attribute
166 * @throws StateValueTypeException
167 * If the state value type of the attribute does not support the
168 * "Average" operation
169 */
170 public static double queryRangeAverage(ITmfStateSystem ss, long t1, long t2, int quark)
171 throws AttributeNotFoundException, TimeRangeException, StateValueTypeException {
172 double avg = 0.0;
173 List<ITmfStateInterval> intervals = queryAttributeRange(ss, t1, t2, quark, AbstractTmfMipmapStateProvider.AVG_STRING);
174 if (intervals.size() == 0) {
175 return 0;
176 } else if (t1 == t2) {
177 ITmfStateValue value = intervals.get(0).getStateValue();
178 if (value.getType() == Type.DOUBLE) {
179 return value.unboxDouble();
180 }
181 return value.unboxLong();
182 }
183 for (ITmfStateInterval si : intervals) {
184 long startTime = Math.max(t1, si.getStartTime());
185 long endTime = Math.min(t2, si.getEndTime() + 1);
186 long delta = endTime - startTime;
187 if (delta > 0) {
188 ITmfStateValue value = si.getStateValue();
189 if (value.getType() == Type.DOUBLE) {
190 avg += si.getStateValue().unboxDouble() * ((double) delta / (double) (t2 - t1));
191 } else {
192 avg += si.getStateValue().unboxLong() * ((double) delta / (double) (t2 - t1));
193 }
194 }
195 }
196 return avg;
197 }
198
199 private static List<ITmfStateInterval> queryAttributeRange(ITmfStateSystem ss,
200 long t1, long t2, int baseQuark, String featureString)
201 throws AttributeNotFoundException, TimeRangeException, StateValueTypeException {
202 TimeRange timeRange = new TimeRange(t1, t2);
203 int mipmapQuark = -1;
204 List<ITmfStateInterval> intervals = new ArrayList<>();
205 try {
206 try {
207 mipmapQuark = ss.getQuarkRelative(baseQuark, featureString);
208 } catch (AttributeNotFoundException e) {
209 /* Not a mipmap attribute, query the base attribute */
210 if (t1 == t2) {
211 ITmfStateInterval interval = ss.querySingleState(t1, baseQuark);
212 if (!interval.getStateValue().isNull()) {
213 intervals.add(interval);
214 }
215 } else {
216 for (ITmfStateInterval interval : StateSystemUtils.queryHistoryRange(ss, baseQuark, t1, t2)) {
217 if (!interval.getStateValue().isNull()) {
218 intervals.add(interval);
219 }
220 }
221 }
222 return intervals;
223 }
224 ITmfStateInterval maxLevelInterval = ss.querySingleState(timeRange.getSecond(), mipmapQuark);
225 int levelMax = maxLevelInterval.getStateValue().unboxInt();
226 queryMipmapAttributeRange(ss, 0, levelMax, baseQuark, mipmapQuark, timeRange, intervals);
227 return intervals;
228
229 } catch (StateValueTypeException e) {
230 /* This is a special case, so we'll add a message to the exception */
231 throw new StateValueTypeException("State system advertises mipmaps," + //$NON-NLS-1$
232 " but doesn't actually have them.", e); //$NON-NLS-1$
233 } catch (StateSystemDisposedException e) {
234 /* We are shutting down, ignore the operation */
235 }
236 return intervals;
237 }
238
239 private static void queryMipmapAttributeRange(ITmfStateSystem ss,
240 int currentLevel, int levelMax, int baseQuark, int mipmapQuark,
241 TimeRange timeRange, List<ITmfStateInterval> intervals)
242 throws AttributeNotFoundException, TimeRangeException {
243 int level = currentLevel;
244 TimeRange range = timeRange;
245 ITmfStateInterval currentLevelInterval = null, nextLevelInterval = null;
246 if (range == null || range.getFirst() > range.getSecond()) {
247 return;
248 }
249 if (level > levelMax || level < 0) {
250 return;
251 }
252 try {
253 if (range.getFirst() == range.getSecond()) {
254 level = 0;
255 currentLevelInterval = ss.querySingleState(range.getFirst(), baseQuark);
256 if (!currentLevelInterval.getStateValue().isNull()) {
257 intervals.add(currentLevelInterval);
258 }
259 return;
260 }
261 if (level < levelMax) {
262 int levelQuark = ss.getQuarkRelative(mipmapQuark, String.valueOf(level + 1));
263 nextLevelInterval = ss.querySingleState(range.getFirst(), levelQuark);
264 }
265
266 if (nextLevelInterval != null && isFullyOverlapped(range, nextLevelInterval)) {
267 if (nextLevelInterval.getStateValue().isNull()) {
268 range = updateTimeRange(range, nextLevelInterval);
269 } else {
270 level++;
271 }
272 queryMipmapAttributeRange(ss, level, levelMax, baseQuark, mipmapQuark, range, intervals);
273 return;
274 }
275
276 if (level == 0) {
277 currentLevelInterval = ss.querySingleState(range.getFirst(), baseQuark);
278 } else {
279 int levelQuark = ss.getQuarkRelative(mipmapQuark, String.valueOf(level));
280 currentLevelInterval = ss.querySingleState(range.getFirst(), levelQuark);
281 }
282
283 if (isFullyOverlapped(range, currentLevelInterval)) {
284 if (!currentLevelInterval.getStateValue().isNull()) {
285 intervals.add(currentLevelInterval);
286 }
287 range = updateTimeRange(range, currentLevelInterval);
288 } else {
289 if (level == 0) {
290 if (!currentLevelInterval.getStateValue().isNull()) {
291 intervals.add(currentLevelInterval);
292 }
293 range = updateTimeRange(range, currentLevelInterval);
294 } else {
295 level--;
296 }
297 }
298
299 queryMipmapAttributeRange(ss, level, levelMax, baseQuark,
300 mipmapQuark, range, intervals);
301
302 } catch (StateSystemDisposedException e) {
303 /* We are shutting down, ignore the operation */
304 }
305 }
306
307 private static TimeRange updateTimeRange(TimeRange timeRange,
308 ITmfStateInterval currentLevelInterval) {
309 if (currentLevelInterval.getEndTime() >= timeRange.getSecond()) {
310 return null;
311 }
312 long startTime = Math.max(timeRange.getFirst(),
313 Math.min(currentLevelInterval.getEndTime() + 1, timeRange.getSecond()));
314 return new TimeRange(startTime, timeRange.getSecond());
315 }
316
317 private static boolean isFullyOverlapped(TimeRange range,
318 ITmfStateInterval interval) {
319 if (range.getFirst() >= range.getSecond() ||
320 interval.getStartTime() >= interval.getEndTime()) {
321 return false;
322 }
323 if (range.getFirst() <= interval.getStartTime() &&
324 range.getSecond() >= interval.getEndTime()) {
325 return true;
326 }
327 return false;
328 }
329 }
330
331 class TimeRange {
332
333 private final long a;
334 private final long b;
335
336 public TimeRange(long first, long second) {
337 a = first;
338 b = second;
339 }
340
341 public long getFirst() {
342 return a;
343 }
344
345 public long getSecond() {
346 return b;
347 }
348 }
This page took 0.04019 seconds and 5 git commands to generate.