tmf: Start counting at zero when using incrementAttribute
[deliverable/tracecompass.git] / org.eclipse.linuxtools.tmf.core / src / org / eclipse / linuxtools / internal / tmf / core / statesystem / StateSystem.java
CommitLineData
a52fde77
AM
1/*******************************************************************************
2 * Copyright (c) 2012 Ericsson
3 * Copyright (c) 2010, 2011 École Polytechnique de Montréal
4 * Copyright (c) 2010, 2011 Alexandre Montplaisir <alexandre.montplaisir@gmail.com>
5 *
6 * All rights reserved. This program and the accompanying materials are
7 * made available under the terms of the Eclipse Public License v1.0 which
8 * accompanies this distribution, and is available at
9 * http://www.eclipse.org/legal/epl-v10.html
10 *
11 *******************************************************************************/
12
18ab1d18 13package org.eclipse.linuxtools.internal.tmf.core.statesystem;
a52fde77
AM
14
15import java.io.PrintWriter;
f94a0bac 16import java.util.LinkedList;
a52fde77
AM
17import java.util.List;
18
6d08acca
AM
19import org.eclipse.linuxtools.tmf.core.exceptions.AttributeNotFoundException;
20import org.eclipse.linuxtools.tmf.core.exceptions.StateValueTypeException;
21import org.eclipse.linuxtools.tmf.core.exceptions.TimeRangeException;
a52fde77 22import org.eclipse.linuxtools.tmf.core.statevalue.ITmfStateValue;
a52fde77
AM
23import org.eclipse.linuxtools.tmf.core.statevalue.TmfStateValue;
24
25/**
26 * This is the base class for the StateHistorySystem. It contains all the
27 * current-state-updating methods.
28 *
29 * It's not abstract, as it can be used by itself: in this case, no History tree
30 * will be built underneath (no information will be saved to disk) and it will
31 * only be able to respond to queries to the current, latest time.
32 *
d26f90fd
AM
33 * (See IStateSystemQuerier and IStateSystemBuilder for the Javadoc.)
34 *
a52fde77
AM
35 * @author alexmont
36 *
37 */
38public class StateSystem {
39
40 /* References to the inner structures */
41 protected AttributeTree attributeTree;
42 protected TransientState transState;
43
44 /**
45 * Constructor. No configuration needed!
46 */
47 public StateSystem() {
48 attributeTree = new AttributeTree(this);
49
50 /* This will tell the builder to discard the intervals */
51 transState = new TransientState(null);
52 }
53
4623f57f
AM
54 public int getNbAttributes() {
55 return attributeTree.getNbAttributes();
56 }
57
a52fde77
AM
58 /**
59 * @name Quark-retrieving methods
60 */
61
a52fde77
AM
62 public int getQuarkAbsolute(String... attribute)
63 throws AttributeNotFoundException {
64 return attributeTree.getQuarkDontAdd(-1, attribute);
65 }
66
a52fde77
AM
67 public int getQuarkAbsoluteAndAdd(String... attribute) {
68 return attributeTree.getQuarkAndAdd(-1, attribute);
69 }
70
a52fde77
AM
71 public int getQuarkRelative(int startingNodeQuark, String... subPath)
72 throws AttributeNotFoundException {
73 return attributeTree.getQuarkDontAdd(startingNodeQuark, subPath);
74 }
75
a52fde77
AM
76 public int getQuarkRelativeAndAdd(int startingNodeQuark, String... subPath) {
77 return attributeTree.getQuarkAndAdd(startingNodeQuark, subPath);
78 }
79
c66426fd 80 public List<Integer> getSubAttributes(int quark, boolean recursive)
0a9de3d2 81 throws AttributeNotFoundException {
c66426fd 82 return attributeTree.getSubAttributes(quark, recursive);
0a9de3d2
AM
83 }
84
f94a0bac
AM
85 public List<Integer> getQuarks(String... pattern) {
86 List<Integer> quarks = new LinkedList<Integer>();
87 List<String> prefix = new LinkedList<String>();
88 List<String> suffix = new LinkedList<String>();
89 boolean split = false;
90 String[] prefixStr;
91 String[] suffixStr;
92 List<Integer> directChildren;
93 int startingAttribute;
94
95 /* Fill the "prefix" and "suffix" parts of the pattern around the '*' */
96 for (String entry : pattern) {
97 if (entry.equals("*")) { //$NON-NLS-1$
98 if (split) {
99 /*
100 * Split was already true? This means there was more than
101 * one wildcard. This is not supported, return an empty
102 * list.
103 */
104 return quarks;
105 }
106 split = true;
107 continue;
108 }
109
110 if (split) {
111 suffix.add(entry);
112 } else {
113 prefix.add(entry);
114 }
115 }
116 prefixStr = prefix.toArray(new String[prefix.size()]);
117 suffixStr = suffix.toArray(new String[suffix.size()]);
118
119 /*
120 * If there was no wildcard, we'll only return the one matching
121 * attribute, if there is one.
122 */
123 if (split == false) {
124 int quark;
125 try {
126 quark = getQuarkAbsolute(prefixStr);
127 } catch (AttributeNotFoundException e) {
128 /* It's fine, we'll just return the empty List */
129 return quarks;
130 }
131 quarks.add(quark);
132 return quarks;
133 }
134
135 try {
136 if (prefix.size() == 0) {
137 /*
138 * If 'prefix' is empty, this means the wildcard was the first
139 * element. Look for the root node's sub-attributes.
140 */
141 startingAttribute = -1;
142 } else {
143 startingAttribute = getQuarkAbsolute(prefixStr);
144 }
145 directChildren = attributeTree.getSubAttributes(startingAttribute,
146 false);
147 } catch (AttributeNotFoundException e) {
148 /* That attribute path did not exist, return the empty array */
149 return quarks;
150 }
151
152 /*
153 * Iterate of all the sub-attributes, and only keep those who match the
154 * 'suffix' part of the initial pattern.
155 */
156 for (int childQuark : directChildren) {
157 int matchingQuark;
158 try {
159 matchingQuark = getQuarkRelative(childQuark, suffixStr);
160 } catch (AttributeNotFoundException e) {
161 continue;
162 }
163 quarks.add(matchingQuark);
164 }
165
166 return quarks;
167 }
168
a52fde77
AM
169 /**
170 * @name External methods related to insertions in the history -
171 */
172
a52fde77 173 public void modifyAttribute(long t, ITmfStateValue value, int attributeQuark)
7e0b2b56
AM
174 throws TimeRangeException, AttributeNotFoundException,
175 StateValueTypeException {
a52fde77
AM
176 transState.processStateChange(t, value, attributeQuark);
177 }
178
a52fde77
AM
179 public void incrementAttribute(long t, int attributeQuark)
180 throws StateValueTypeException, TimeRangeException,
181 AttributeNotFoundException {
182 int prevValue = queryOngoingState(attributeQuark).unboxInt();
280bbdbb
AM
183 if (prevValue == -1) {
184 /* if the attribute was previously null, start counting at 0 */
185 prevValue = 0;
186 }
a52fde77
AM
187 modifyAttribute(t, TmfStateValue.newValueInt(prevValue + 1),
188 attributeQuark);
189 }
190
a52fde77
AM
191 public void pushAttribute(long t, ITmfStateValue value, int attributeQuark)
192 throws TimeRangeException, AttributeNotFoundException,
193 StateValueTypeException {
a52fde77
AM
194 Integer stackDepth = 0;
195 int subAttributeQuark;
196 ITmfStateValue previousSV = transState.getOngoingStateValue(attributeQuark);
197
198 if (previousSV.isNull()) {
199 /*
200 * If the StateValue was null, this means this is the first time we
201 * use this attribute. Leave stackDepth at 0.
202 */
203 } else if (previousSV.getType() == 0) {
204 /* Previous value was an integer, all is good, use it */
205 stackDepth = previousSV.unboxInt();
a52fde77
AM
206 } else {
207 /* Previous state of this attribute was another type? Not good! */
90a25ebe
AM
208 throw new StateValueTypeException();
209 }
210
211 if (stackDepth >= 10) {
212 /*
213 * Limit stackDepth to 10, to avoid having Attribute Trees grow out
214 * of control due to buggy insertions
215 */
216 String message = "Stack limit reached, not pushing"; //$NON-NLS-1$
217 throw new AttributeNotFoundException(message);
a52fde77
AM
218 }
219
220 stackDepth++;
221 subAttributeQuark = getQuarkRelativeAndAdd(attributeQuark,
222 stackDepth.toString());
223
224 modifyAttribute(t, TmfStateValue.newValueInt(stackDepth),
225 attributeQuark);
90a25ebe 226 modifyAttribute(t, value, subAttributeQuark);
a52fde77
AM
227 }
228
a52fde77
AM
229 public void popAttribute(long t, int attributeQuark)
230 throws AttributeNotFoundException, TimeRangeException,
231 StateValueTypeException {
a52fde77
AM
232 Integer stackDepth;
233 int subAttributeQuark;
234 ITmfStateValue previousSV = transState.getOngoingStateValue(attributeQuark);
235
236 if (previousSV.isNull()) {
90a25ebe
AM
237 /* Same as if stackDepth == 0, see below */
238 return;
239 }
240 if (previousSV.getType() != 0) {
a52fde77 241 /*
90a25ebe
AM
242 * The existing value was a string, this doesn't look like a valid
243 * stack attribute.
a52fde77 244 */
90a25ebe 245 throw new StateValueTypeException();
a52fde77
AM
246 }
247
90a25ebe
AM
248 stackDepth = previousSV.unboxInt();
249
a52fde77
AM
250 if (stackDepth == 0) {
251 /*
252 * Trying to pop an empty stack. This often happens at the start of
253 * traces, for example when we see a syscall_exit, without having
254 * the corresponding syscall_entry in the trace. Just ignore
255 * silently.
256 */
257 return;
90a25ebe
AM
258 }
259
260 if (stackDepth < 0) {
a52fde77 261 /* This on the other hand should not happen... */
90a25ebe
AM
262 String message = "A top-level stack attribute " + //$NON-NLS-1$
263 "cannot have a negative integer value."; //$NON-NLS-1$
264 throw new StateValueTypeException(message);
a52fde77
AM
265 }
266
267 /* The attribute should already exist... */
268 subAttributeQuark = getQuarkRelative(attributeQuark,
269 stackDepth.toString());
270
271 stackDepth--;
272 modifyAttribute(t, TmfStateValue.newValueInt(stackDepth),
273 attributeQuark);
274 removeAttribute(t, subAttributeQuark);
275 }
276
a52fde77
AM
277 public void removeAttribute(long t, int attributeQuark)
278 throws TimeRangeException, AttributeNotFoundException {
279 assert (attributeQuark >= 0);
c66426fd
AM
280 List<Integer> childAttributes;
281
282 /*
283 * "Nullify our children first, recursively. We pass 'false' because we
284 * handle the recursion ourselves.
285 */
286 childAttributes = attributeTree.getSubAttributes(attributeQuark, false);
a52fde77
AM
287 for (Integer childNodeQuark : childAttributes) {
288 assert (attributeQuark != childNodeQuark);
289 removeAttribute(t, childNodeQuark);
290 }
291 /* Nullify ourselves */
7e0b2b56
AM
292 try {
293 transState.processStateChange(t, TmfStateValue.nullValue(),
294 attributeQuark);
295 } catch (StateValueTypeException e) {
50678114
AM
296 /*
297 * Will not happen since we're inserting null values only, but poor
298 * compiler has no way of knowing this...
7e0b2b56
AM
299 */
300 e.printStackTrace();
301 }
a52fde77
AM
302 }
303
304 /**
305 * @name "Current" query/update methods -
306 */
307
a52fde77
AM
308 public ITmfStateValue queryOngoingState(int attributeQuark)
309 throws AttributeNotFoundException {
310 return transState.getOngoingStateValue(attributeQuark);
311 }
312
a52fde77
AM
313 public void updateOngoingState(ITmfStateValue newValue, int attributeQuark)
314 throws AttributeNotFoundException {
315 transState.changeOngoingStateValue(attributeQuark, newValue);
316 }
317
50678114
AM
318 public String getAttributeName(int attributeQuark) {
319 return attributeTree.getAttributeName(attributeQuark);
320 }
321
a52fde77
AM
322 public String getFullAttributePath(int attributeQuark) {
323 return attributeTree.getFullAttributeName(attributeQuark);
324 }
325
326 /**
327 * Print out the contents of the inner structures.
328 *
329 * @param writer
330 * The PrintWriter in which to print the output
331 */
332 public void debugPrint(PrintWriter writer) {
333 attributeTree.debugPrint(writer);
334 transState.debugPrint(writer);
335 }
336
337}
This page took 0.041037 seconds and 5 git commands to generate.