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