tmf : introducing the mipmap
[deliverable/tracecompass.git] / org.eclipse.linuxtools.tmf.core / src / org / eclipse / linuxtools / tmf / core / statesystem / TmfStateSystemOperations.java
CommitLineData
8e364f8e
PT
1/*******************************************************************************
2 * Copyright (c) 2013 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
14package org.eclipse.linuxtools.tmf.core.statesystem;
15
16import java.util.ArrayList;
17import java.util.List;
18
19import org.eclipse.linuxtools.internal.tmf.core.statesystem.mipmap.AbstractTmfMipmapStateProvider;
20import org.eclipse.linuxtools.tmf.core.exceptions.AttributeNotFoundException;
21import org.eclipse.linuxtools.tmf.core.exceptions.StateSystemDisposedException;
22import org.eclipse.linuxtools.tmf.core.exceptions.StateValueTypeException;
23import org.eclipse.linuxtools.tmf.core.exceptions.TimeRangeException;
24import org.eclipse.linuxtools.tmf.core.interval.ITmfStateInterval;
25import org.eclipse.linuxtools.tmf.core.statevalue.ITmfStateValue;
26import org.eclipse.linuxtools.tmf.core.statevalue.ITmfStateValue.Type;
27import org.eclipse.linuxtools.tmf.core.statevalue.TmfStateValue;
28import org.eclipse.linuxtools.tmf.core.util.Pair;
29
30/**
31 * This class implements additional statistical operations that can be
32 * performed on attributes of the state system.
33 */
34public class TmfStateSystemOperations {
35
36 private final ITmfStateSystem ss;
37
38 /**
39 * Constructor
40 *
41 * @param ss
42 * The state system on which to perform operations
43 */
44 public TmfStateSystemOperations(ITmfStateSystem ss) {
45 this.ss = ss;
46 }
47
48 /**
49 * Return the maximum value of an attribute over a time range
50 *
51 * @param t1
52 * The start time of the range
53 * @param t2
54 * The end time of the range
55 * @param quark
56 * The quark of the attribute
57 * @return The maximum value of the attribute in this range
58 */
59 public ITmfStateValue queryRangeMax(long t1, long t2, int quark) {
60 ITmfStateValue max = TmfStateValue.nullValue();
61 try {
62 List<ITmfStateInterval> intervals = queryAttributeRange(t1, t2, quark, AbstractTmfMipmapStateProvider.MAX_STRING);
63 if (intervals.size() == 0) {
64 return TmfStateValue.nullValue();
65 }
66 for (ITmfStateInterval si : intervals) {
67 ITmfStateValue value = si.getStateValue();
68 if (value.getType() == Type.DOUBLE) {
69 if (max.isNull() || si.getStateValue().unboxDouble() > max.unboxDouble()) {
70 max = si.getStateValue();
71 }
72 } else {
73 if (max.isNull() || si.getStateValue().unboxLong() > max.unboxLong()) {
74 max = si.getStateValue();
75 }
76 }
77 }
78 } catch (StateValueTypeException e) {
79 e.printStackTrace();
80 }
81 return max;
82 }
83
84 /**
85 * Return the minimum value of an attribute over a time range
86 *
87 * @param t1
88 * The start time of the range
89 * @param t2
90 * The end time of the range
91 * @param quark
92 * The quark of the attribute
93 * @return The minimum value of the attribute in this range
94 */
95 public ITmfStateValue queryRangeMin(long t1, long t2, int quark) {
96 ITmfStateValue min = TmfStateValue.nullValue();
97 try {
98 List<ITmfStateInterval> intervals = queryAttributeRange(t1, t2, quark, AbstractTmfMipmapStateProvider.MIN_STRING);
99 if (intervals.size() == 0) {
100 return TmfStateValue.nullValue();
101 }
102 for (ITmfStateInterval si : intervals) {
103 ITmfStateValue value = si.getStateValue();
104 if (value.getType() == Type.DOUBLE) {
105 if (min.isNull() || si.getStateValue().unboxDouble() < min.unboxDouble()) {
106 min = si.getStateValue();
107 }
108 } else {
109 if (min.isNull() || si.getStateValue().unboxLong() < min.unboxLong()) {
110 min = si.getStateValue();
111 }
112 }
113 }
114 } catch (StateValueTypeException e) {
115 e.printStackTrace();
116 }
117 return min;
118 }
119
120 /**
121 * Return the weighted average value of an attribute over a time range
122 *
123 * @param t1
124 * The start time of the range
125 * @param t2
126 * The end time of the range
127 * @param quark
128 * The quark of the attribute
129 * @return The weighted average value of the attribute in this range
130 */
131 public double queryRangeAverage(long t1, long t2, int quark) {
132 double avg = 0.0;
133 try {
134 List<ITmfStateInterval> intervals = queryAttributeRange(t1, t2, quark, AbstractTmfMipmapStateProvider.AVG_STRING);
135 if (intervals.size() == 0) {
136 return 0;
137 } else if (t1 == t2) {
138 ITmfStateValue value = intervals.get(0).getStateValue();
139 if (value.getType() == Type.DOUBLE) {
140 return value.unboxDouble();
141 }
142 return value.unboxLong();
143 }
144 for (ITmfStateInterval si : intervals) {
145 long startTime = Math.max(t1, si.getStartTime());
146 long endTime = Math.min(t2, si.getEndTime() + 1);
147 long delta = endTime - startTime;
148 if (delta > 0) {
149 ITmfStateValue value = si.getStateValue();
150 if (value.getType() == Type.DOUBLE) {
151 avg += si.getStateValue().unboxDouble() * ((double) delta / (double) (t2 - t1));
152 } else {
153 avg += si.getStateValue().unboxLong() * ((double) delta / (double) (t2 - t1));
154 }
155 }
156 }
157 } catch (StateValueTypeException e) {
158 e.printStackTrace();
159 }
160 return avg;
161 }
162
163 private List<ITmfStateInterval> queryAttributeRange(long t1, long t2, int baseQuark, String featureString) {
164 Pair<Long, Long> timeRange = new Pair<Long, Long>(t1, t2);
165 int mipmapQuark = -1;
166 List<ITmfStateInterval> intervals = new ArrayList<ITmfStateInterval>();
167 try {
168 try {
169 mipmapQuark = ss.getQuarkRelative(baseQuark, featureString);
170 } catch (AttributeNotFoundException e) {
171 /* Not a mipmap attribute, query the base attribute */
172 if (t1 == t2) {
173 ITmfStateInterval interval = ss.querySingleState(t1, baseQuark);
174 if (!interval.getStateValue().isNull()) {
175 intervals.add(interval);
176 }
177 } else {
178 for (ITmfStateInterval interval : ss.queryHistoryRange(baseQuark, t1, t2)) {
179 if (!interval.getStateValue().isNull()) {
180 intervals.add(interval);
181 }
182 }
183 }
184 return intervals;
185 }
186 ITmfStateInterval maxLevelInterval = ss.querySingleState(timeRange.getSecond(), mipmapQuark);
187 int levelMax = maxLevelInterval.getStateValue().unboxInt();
188 queryMipmapAttributeRange(0, levelMax, baseQuark, mipmapQuark, timeRange, intervals);
189 return intervals;
190 } catch (AttributeNotFoundException e) {
191 e.printStackTrace();
192 } catch (TimeRangeException e) {
193 e.printStackTrace();
194 } catch (StateValueTypeException e) {
195 e.printStackTrace();
196 } catch (StateSystemDisposedException e) {
197 /* Ignored */
198 }
199 return intervals;
200 }
201
202 private void queryMipmapAttributeRange(int currentLevel, int levelMax, int baseQuark, int mipmapQuark, Pair<Long, Long> timeRange, List<ITmfStateInterval> intervals) {
203 int level = currentLevel;
204 Pair<Long, Long> range = timeRange;
205 ITmfStateInterval currentLevelInterval = null, nextLevelInterval = null;
206 if (range == null || range.getFirst() > range.getSecond()) {
207 return;
208 }
209 if (level > levelMax || level < 0) {
210 return;
211 }
212 try {
213 if (range.getFirst().longValue() == range.getSecond().longValue()) {
214 level = 0;
215 currentLevelInterval = ss.querySingleState(range.getFirst(), baseQuark);
216 if (!currentLevelInterval.getStateValue().isNull()) {
217 intervals.add(currentLevelInterval);
218 }
219 return;
220 }
221 if (level < levelMax) {
222 int levelQuark = ss.getQuarkRelative(mipmapQuark, String.valueOf(level + 1));
223 nextLevelInterval = ss.querySingleState(range.getFirst(), levelQuark);
224 }
225
226 if (nextLevelInterval != null && isFullyOverlapped(range, nextLevelInterval)) {
227 if (nextLevelInterval.getStateValue().isNull()) {
228 range = updateTimeRange(range, nextLevelInterval);
229 } else {
230 level++;
231 }
232 queryMipmapAttributeRange(level, levelMax, baseQuark, mipmapQuark, range, intervals);
233 return;
234 }
235
236 if (level == 0) {
237 currentLevelInterval = ss.querySingleState(range.getFirst(), baseQuark);
238 } else {
239 int levelQuark = ss.getQuarkRelative(mipmapQuark, String.valueOf(level));
240 currentLevelInterval = ss.querySingleState(range.getFirst(), levelQuark);
241 }
242
243 if (currentLevelInterval != null && isFullyOverlapped(range, currentLevelInterval)) {
244 if (!currentLevelInterval.getStateValue().isNull()) {
245 intervals.add(currentLevelInterval);
246 }
247 range = updateTimeRange(range, currentLevelInterval);
248 } else {
249 if (level == 0) {
250 if (currentLevelInterval == null) {
251 return;
252 }
253 if (!currentLevelInterval.getStateValue().isNull()) {
254 intervals.add(currentLevelInterval);
255 }
256 range = updateTimeRange(range, currentLevelInterval);
257 } else {
258 level--;
259 }
260 }
261
262 queryMipmapAttributeRange(level, levelMax, baseQuark, mipmapQuark, range, intervals);
263
264 } catch (AttributeNotFoundException e) {
265 e.printStackTrace();
266 } catch (TimeRangeException e) {
267 e.printStackTrace();
268 } catch (StateSystemDisposedException e) {
269 /* Ignored */
270 }
271 }
272
273 private static Pair<Long, Long> updateTimeRange(Pair<Long, Long> timeRange, ITmfStateInterval currentLevelInterval) {
274 if (currentLevelInterval.getEndTime() >= timeRange.getSecond()) {
275 return null;
276 }
277 long startTime = Math.max(timeRange.getFirst(), Math.min(currentLevelInterval.getEndTime() + 1, timeRange.getSecond()));
278 return new Pair<Long, Long>(startTime, timeRange.getSecond());
279 }
280
281 private static boolean isFullyOverlapped(Pair<Long, Long> range, ITmfStateInterval interval) {
282 if (range.getFirst() >= range.getSecond() || interval.getStartTime() >= interval.getEndTime()) {
283 return false;
284 }
285 if (range.getFirst() <= interval.getStartTime() && range.getSecond() >= interval.getEndTime()) {
286 return true;
287 }
288 return false;
289 }
290
291}
This page took 0.050547 seconds and 5 git commands to generate.