3c832ead2122c2e9c05dd370e238af74e040ff74
[deliverable/tracecompass.git] / tmf / org.eclipse.tracecompass.tmf.core / src / org / eclipse / tracecompass / internal / tmf / core / statesystem / mipmap / TmfMipmapFeature.java
1 /*******************************************************************************
2 * Copyright (c) 2013, 2014 Ericsson
3 *
4 * All rights reserved. This program and the accompanying materials are made
5 * 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 package org.eclipse.tracecompass.internal.tmf.core.statesystem.mipmap;
14
15 import java.util.ArrayList;
16 import java.util.List;
17
18 import org.eclipse.jdt.annotation.NonNull;
19 import org.eclipse.tracecompass.internal.tmf.core.Activator;
20 import org.eclipse.tracecompass.statesystem.core.ITmfStateSystemBuilder;
21 import org.eclipse.tracecompass.statesystem.core.exceptions.AttributeNotFoundException;
22 import org.eclipse.tracecompass.statesystem.core.exceptions.StateValueTypeException;
23 import org.eclipse.tracecompass.statesystem.core.exceptions.TimeRangeException;
24 import org.eclipse.tracecompass.statesystem.core.interval.ITmfStateInterval;
25 import org.eclipse.tracecompass.statesystem.core.interval.TmfStateInterval;
26 import org.eclipse.tracecompass.statesystem.core.statevalue.ITmfStateValue;
27 import org.eclipse.tracecompass.statesystem.core.statevalue.TmfStateValue;
28
29 /**
30 * The mipmap feature base implementation.
31 *
32 * @author Jean-Christian Kouamé
33 * @author Patrick Tasse
34 *
35 */
36 public abstract class TmfMipmapFeature implements ITmfMipmapFeature {
37
38 /** The current state value */
39 protected @NonNull ITmfStateValue currentValue = TmfStateValue.nullValue();
40 /** The current start time for the state value */
41 protected long currentStartTime;
42 /** The list of ongoing state intervals per mipmap level */
43 protected List<List<ITmfStateInterval>> intervals = new ArrayList<>();
44 /** The state system used to store the mipmap attributes */
45 protected ITmfStateSystemBuilder ss;
46
47 private int mipmapResolution;
48 private int mipmapQuark;
49 private List<Integer> levelQuarks = new ArrayList<>();
50
51 /**
52 * Constructor
53 *
54 * @param baseQuark
55 * The quark of the attribute we want to mipmap
56 * @param mipmapQuark
57 * The quark of the mipmap feature attribute
58 * @param mipmapResolution
59 * The resolution that will be used for the mipmap
60 * @param ss
61 * The state system in which to insert the state changes
62 */
63 public TmfMipmapFeature(int baseQuark, int mipmapQuark, int mipmapResolution, ITmfStateSystemBuilder ss) {
64 this.mipmapQuark = mipmapQuark;
65 this.mipmapResolution = mipmapResolution;
66 this.ss = ss;
67
68 /* store the base attribute quark at level 0 */
69 this.levelQuarks.add(baseQuark);
70
71 /* create the level 0 list */
72 intervals.add(new ArrayList<ITmfStateInterval>(mipmapResolution));
73 }
74
75 @Override
76 public void updateMipmap(ITmfStateValue value, long ts) {
77 /* if the value did not change, ignore it */
78 if (currentValue.equals(value)) {
79 return;
80 }
81
82 /* if the ongoing state value is not null, create and store a state interval */
83 if (!currentValue.isNull()) {
84 ITmfStateInterval interval = new TmfStateInterval(currentStartTime, ts, getLevelQuark(0), currentValue);
85 intervals.get(0).add(interval);
86 }
87
88 /* if the new value is not null, update the mipmap levels that are full */
89 if (!value.isNull()) {
90 int level = 0;
91 while (intervals.get(level).size() == getMipmapResolution()) {
92 updateMipmapLevel(++level, ts);
93 }
94 }
95
96 /* store the new value as the ongoing state value */
97 currentValue = value;
98 currentStartTime = ts;
99 }
100
101 @Override
102 public void updateAndCloseMipmap() {
103 if (!currentValue.isNull()) {
104 ITmfStateInterval interval = new TmfStateInterval(currentStartTime, currentStartTime, getLevelQuark(0), currentValue);
105 intervals.get(0).add(interval);
106 }
107 for (int level = 1; level <= getNbLevels(); level++) {
108 updateMipmapLevel(level, currentStartTime);
109 }
110 }
111
112 /**
113 * Compute and update the mipmap level attribute from the lower-level
114 * state interval list
115 *
116 * @param level
117 * The mipmap level to update
118 * @param endTime
119 * The end timestamp to use for the mipmap interval
120 */
121 protected void updateMipmapLevel(int level, long endTime) {
122 try {
123 /* get the lower-level interval list */
124 List<ITmfStateInterval> lowerIntervals = intervals.get(level - 1);
125 if (lowerIntervals.size() == 0) {
126 return;
127 }
128
129 /* get the start time from the first interval in the lower-level list */
130 long startTime = lowerIntervals.get(0).getStartTime();
131
132 /* compute the mipmap value */
133 ITmfStateValue value = computeMipmapValue(lowerIntervals, startTime, endTime);
134
135 /* clear the lower-level list */
136 lowerIntervals.clear();
137
138 /* get or create the current-level quark */
139 int levelQuark = ss.getQuarkRelativeAndAdd(mipmapQuark, String.valueOf(level));
140 if (!checkLevelExists(level)) {
141 addLevelQuark(levelQuark);
142 ss.updateOngoingState(TmfStateValue.newValueInt(level), mipmapQuark);
143 intervals.add(new ArrayList<ITmfStateInterval>(getMipmapResolution()));
144 }
145
146 /* add new interval to current-level list */
147 ITmfStateInterval interval = new TmfStateInterval(startTime, endTime, levelQuark, value);
148 intervals.get(level).add(interval);
149
150 /* update the current-level attribute */
151 ss.modifyAttribute(startTime, value, levelQuark);
152 } catch (StateValueTypeException e) {
153 Activator.logError("TmfMipmapFeature : Bad state value type", e); //$NON-NLS-1$
154 } catch (AttributeNotFoundException e) {
155 Activator.logError("TmfMipmapFeature : Attribute not found", e); //$NON-NLS-1$
156 } catch (TimeRangeException e) {
157 Activator.logError("TmfMipmapFeature : Time stamp is out of range", e); //$NON-NLS-1$
158 }
159 }
160
161 /**
162 * Compute the mipmap value from a list of lower-level state intervals
163 *
164 * @param lowerIntervals
165 * The list of lower-level state intervals
166 * @param startTime
167 * The start time of the mipmap interval
168 * @param endTime
169 * The end time of the mipmap interval
170 * @return A state value to be stored in the mipmap level attribute
171 */
172 protected abstract @NonNull ITmfStateValue computeMipmapValue(List<ITmfStateInterval> lowerIntervals, long startTime, long endTime);
173
174 /**
175 * Get the mipmap resolution
176 *
177 * @return The mipmap resolution for this feature
178 */
179 protected int getMipmapResolution() {
180 return mipmapResolution;
181 }
182
183 /**
184 * Get the mipmap feature quark. The state value
185 * of this attribute is the mipmap number of levels.
186 * This is the parent attribute of the mipmap level quarks.
187 *
188 * @return The attribute quark for this mipmap feature
189 */
190 protected int getMipmapQuark() {
191 return mipmapQuark;
192 }
193
194 /**
195 * Get the mipmap quark for the specified level.
196 * For level 0 the base attribute quark is returned.
197 *
198 * @param level
199 * The mipmap level (0 for the base attribute)
200 * @return The attribute quark for this mipmap level
201 */
202 protected int getLevelQuark(int level) {
203 return levelQuarks.get(level);
204 }
205
206 /**
207 * Add a new mipmap level quark.
208 *
209 * @param quark
210 * The attribute quark for the new mipmap level
211 */
212 protected void addLevelQuark(int quark) {
213 levelQuarks.add(quark);
214 }
215
216 /**
217 * Get the mipmap number of levels.
218 *
219 * @return The current number of mipmap levels for this feature
220 * (excluding the base attribute)
221 */
222 protected int getNbLevels() {
223 return levelQuarks.size() - 1;
224 }
225
226 /**
227 * Checks if a mipmap level exists.
228 *
229 * @param level
230 * The mipmap level to check
231 * @return true if this level exists, false otherwise
232 */
233 protected boolean checkLevelExists(int level) {
234 if (level >= levelQuarks.size() || level < 0) {
235 return false;
236 }
237 return true;
238 }
239
240 }
This page took 0.038935 seconds and 5 git commands to generate.