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