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