ss: Bug 486689: Add methods for getting an optional attribute quark
[deliverable/tracecompass.git] / statesystem / org.eclipse.tracecompass.statesystem.core / src / org / eclipse / tracecompass / internal / statesystem / core / StateSystem.java
CommitLineData
a52fde77 1/*******************************************************************************
c44f0a0c 2 * Copyright (c) 2012, 2016 Ericsson
a52fde77
AM
3 * Copyright (c) 2010, 2011 École Polytechnique de Montréal
4 * Copyright (c) 2010, 2011 Alexandre Montplaisir <alexandre.montplaisir@gmail.com>
5df842b3 5 *
a52fde77
AM
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
5df842b3 10 *
e13bd4cd
PT
11 * Contributors:
12 * Alexandre Montplaisir - Initial API and implementation
13 * Patrick Tasse - Add message to exceptions
a52fde77
AM
14 *******************************************************************************/
15
e894a508 16package org.eclipse.tracecompass.internal.statesystem.core;
a52fde77 17
8d1346f0
AM
18import java.io.File;
19import java.io.IOException;
a52fde77 20import java.io.PrintWriter;
8d1346f0 21import java.util.ArrayList;
c44f0a0c 22import java.util.Arrays;
f94a0bac 23import java.util.LinkedList;
a52fde77 24import java.util.List;
16576a7e 25import java.util.concurrent.CountDownLatch;
9287b6a2 26import java.util.concurrent.TimeUnit;
a52fde77 27
2e21b6d8 28import org.eclipse.jdt.annotation.NonNull;
df2597e0 29import org.eclipse.jdt.annotation.Nullable;
e894a508
AM
30import org.eclipse.tracecompass.statesystem.core.ITmfStateSystemBuilder;
31import org.eclipse.tracecompass.statesystem.core.backend.IStateHistoryBackend;
32import org.eclipse.tracecompass.statesystem.core.exceptions.AttributeNotFoundException;
33import org.eclipse.tracecompass.statesystem.core.exceptions.StateSystemDisposedException;
34import org.eclipse.tracecompass.statesystem.core.exceptions.StateValueTypeException;
35import org.eclipse.tracecompass.statesystem.core.exceptions.TimeRangeException;
36import org.eclipse.tracecompass.statesystem.core.interval.ITmfStateInterval;
e894a508 37import org.eclipse.tracecompass.statesystem.core.statevalue.ITmfStateValue;
e894a508 38import org.eclipse.tracecompass.statesystem.core.statevalue.ITmfStateValue.Type;
1dd75589 39import org.eclipse.tracecompass.statesystem.core.statevalue.TmfStateValue;
a52fde77
AM
40
41/**
8d1346f0
AM
42 * This is the core class of the Generic State System. It contains all the
43 * methods to build and query a state history. It's exposed externally through
44 * the IStateSystemQuerier and IStateSystemBuilder interfaces, depending if the
45 * user needs read-only access or read-write access.
5df842b3 46 *
8d1346f0
AM
47 * When building, DON'T FORGET to call .closeHistory() when you are done
48 * inserting intervals, or the storage backend will have no way of knowing it
49 * can close and write itself to disk, and its thread will keep running.
5df842b3 50 *
a52fde77 51 * @author alexmont
5df842b3 52 *
a52fde77 53 */
f1f86dfb 54public class StateSystem implements ITmfStateSystemBuilder {
a52fde77
AM
55
56 /* References to the inner structures */
8d1346f0
AM
57 private final AttributeTree attributeTree;
58 private final TransientState transState;
59 private final IStateHistoryBackend backend;
a52fde77 60
16576a7e
AM
61 /* Latch tracking if the state history is done building or not */
62 private final CountDownLatch finishedLatch = new CountDownLatch(1);
63
1a4205d9 64 private boolean buildCancelled = false;
96345c5a 65 private boolean isDisposed = false;
1a4205d9 66
f9a76cac
AM
67 /**
68 * New-file constructor. For when you build a state system with a new file,
69 * or if the back-end does not require a file on disk.
70 *
71 * @param backend
72 * Back-end plugin to use
73 */
b2f62cb5 74 public StateSystem(@NonNull IStateHistoryBackend backend) {
f9a76cac
AM
75 this.backend = backend;
76 this.transState = new TransientState(backend);
77 this.attributeTree = new AttributeTree(this);
78 }
79
a52fde77 80 /**
8d1346f0
AM
81 * General constructor
82 *
83 * @param backend
f9a76cac 84 * The "state history storage" back-end to use.
8d1346f0
AM
85 * @param newFile
86 * Put true if this is a new history started from scratch. It is
87 * used to tell the state system where to get its attribute tree.
88 * @throws IOException
89 * If there was a problem creating the new history file
a52fde77 90 */
b2f62cb5 91 public StateSystem(@NonNull IStateHistoryBackend backend, boolean newFile)
8d1346f0
AM
92 throws IOException {
93 this.backend = backend;
94 this.transState = new TransientState(backend);
a52fde77 95
8d1346f0
AM
96 if (newFile) {
97 attributeTree = new AttributeTree(this);
98 } else {
99 /* We're opening an existing file */
100 this.attributeTree = new AttributeTree(this, backend.supplyAttributeTreeReader());
101 transState.setInactive();
16576a7e
AM
102 finishedLatch.countDown(); /* The history is already built */
103 }
104 }
105
84a9548a
AM
106 @Override
107 public String getSSID() {
b2f62cb5 108 return backend.getSSID();
84a9548a
AM
109 }
110
16576a7e 111 @Override
2002c638
AM
112 public boolean isCancelled() {
113 return buildCancelled;
114 }
115
116 @Override
117 public void waitUntilBuilt() {
16576a7e
AM
118 try {
119 finishedLatch.await();
120 } catch (InterruptedException e) {
121 e.printStackTrace();
8d1346f0 122 }
1a4205d9
AM
123 }
124
9287b6a2
AM
125 @Override
126 public boolean waitUntilBuilt(long timeout) {
127 boolean ret = false;
128 try {
129 ret = finishedLatch.await(timeout, TimeUnit.MILLISECONDS);
130 } catch (InterruptedException e) {
131 e.printStackTrace();
132 }
133 return ret;
134 }
135
1a4205d9
AM
136 @Override
137 public synchronized void dispose() {
96345c5a 138 isDisposed = true;
1a4205d9
AM
139 if (transState.isActive()) {
140 transState.setInactive();
141 buildCancelled = true;
142 }
143 backend.dispose();
a52fde77
AM
144 }
145
8d1346f0
AM
146 //--------------------------------------------------------------------------
147 // General methods related to the attribute tree
148 //--------------------------------------------------------------------------
149
339d27b4
AM
150 /**
151 * Get the attribute tree associated with this state system. This should be
152 * the only way of accessing it (and if subclasses want to point to a
153 * different attribute tree than their own, they should only need to
154 * override this).
155 *
156 * @return The attribute tree
157 */
158 public AttributeTree getAttributeTree() {
159 return attributeTree;
160 }
161
8d1346f0
AM
162 /**
163 * Method used by the attribute tree when creating new attributes, to keep
164 * the attribute count in the transient state in sync.
165 */
bcec0116 166 public void addEmptyAttribute() {
8d1346f0
AM
167 transState.addEmptyEntry();
168 }
169
170 @Override
4623f57f 171 public int getNbAttributes() {
339d27b4 172 return getAttributeTree().getNbAttributes();
4623f57f
AM
173 }
174
8d1346f0
AM
175 @Override
176 public String getAttributeName(int attributeQuark) {
339d27b4 177 return getAttributeTree().getAttributeName(attributeQuark);
8d1346f0
AM
178 }
179
180 @Override
181 public String getFullAttributePath(int attributeQuark) {
339d27b4 182 return getAttributeTree().getFullAttributeName(attributeQuark);
8d1346f0
AM
183 }
184
34638411
AM
185 @Override
186 public String[] getFullAttributePathArray(int attributeQuark) {
187 return getAttributeTree().getFullAttributePathArray(attributeQuark);
188 }
189
8d1346f0
AM
190 //--------------------------------------------------------------------------
191 // Methods related to the storage backend
192 //--------------------------------------------------------------------------
a52fde77 193
8d1346f0
AM
194 @Override
195 public long getStartTime() {
196 return backend.getStartTime();
197 }
198
199 @Override
200 public long getCurrentEndTime() {
201 return backend.getEndTime();
202 }
203
204 @Override
205 public void closeHistory(long endTime) throws TimeRangeException {
206 File attributeTreeFile;
207 long attributeTreeFilePos;
208 long realEndTime = endTime;
209
210 if (realEndTime < backend.getEndTime()) {
211 /*
212 * This can happen (empty nodes pushing the border further, etc.)
213 * but shouldn't be too big of a deal.
214 */
215 realEndTime = backend.getEndTime();
216 }
217 transState.closeTransientState(realEndTime);
218 backend.finishedBuilding(realEndTime);
219
220 attributeTreeFile = backend.supplyAttributeTreeWriterFile();
221 attributeTreeFilePos = backend.supplyAttributeTreeWriterFilePosition();
222 if (attributeTreeFile != null) {
223 /*
224 * If null was returned, we simply won't save the attribute tree,
225 * too bad!
226 */
339d27b4 227 getAttributeTree().writeSelf(attributeTreeFile, attributeTreeFilePos);
8d1346f0 228 }
16576a7e 229 finishedLatch.countDown(); /* Mark the history as finished building */
8d1346f0
AM
230 }
231
232 //--------------------------------------------------------------------------
233 // Quark-retrieving methods
234 //--------------------------------------------------------------------------
235
236 @Override
a52fde77
AM
237 public int getQuarkAbsolute(String... attribute)
238 throws AttributeNotFoundException {
c44f0a0c
PT
239 int quark = getAttributeTree().getQuarkDontAdd(ROOT_ATTRIBUTE, attribute);
240 if (quark == INVALID_ATTRIBUTE) {
241 throw new AttributeNotFoundException(getSSID() + " Path:" + Arrays.toString(attribute)); //$NON-NLS-1$
242 }
243 return quark;
244 }
245
246 @Override
247 public int optQuarkAbsolute(String... attribute) {
248 return getAttributeTree().getQuarkDontAdd(ROOT_ATTRIBUTE, attribute);
a52fde77
AM
249 }
250
8d1346f0 251 @Override
a52fde77 252 public int getQuarkAbsoluteAndAdd(String... attribute) {
c44f0a0c 253 return getAttributeTree().getQuarkAndAdd(ROOT_ATTRIBUTE, attribute);
a52fde77
AM
254 }
255
8d1346f0 256 @Override
a52fde77
AM
257 public int getQuarkRelative(int startingNodeQuark, String... subPath)
258 throws AttributeNotFoundException {
c44f0a0c
PT
259 int quark = getAttributeTree().getQuarkDontAdd(startingNodeQuark, subPath);
260 if (quark == INVALID_ATTRIBUTE) {
261 throw new AttributeNotFoundException(getSSID() + " Quark:" + startingNodeQuark + ", SubPath:" + Arrays.toString(subPath)); //$NON-NLS-1$ //$NON-NLS-2$
262 }
263 return quark;
264 }
265
266 @Override
267 public int optQuarkRelative(int startingNodeQuark, String... subPath) {
339d27b4 268 return getAttributeTree().getQuarkDontAdd(startingNodeQuark, subPath);
a52fde77
AM
269 }
270
8d1346f0 271 @Override
a52fde77 272 public int getQuarkRelativeAndAdd(int startingNodeQuark, String... subPath) {
339d27b4 273 return getAttributeTree().getQuarkAndAdd(startingNodeQuark, subPath);
a52fde77
AM
274 }
275
8d1346f0 276 @Override
c66426fd 277 public List<Integer> getSubAttributes(int quark, boolean recursive)
0a9de3d2 278 throws AttributeNotFoundException {
339d27b4 279 return getAttributeTree().getSubAttributes(quark, recursive);
0a9de3d2
AM
280 }
281
5206c858
AM
282 @Override
283 public List<Integer> getSubAttributes(int quark, boolean recursive, String pattern)
284 throws AttributeNotFoundException {
285 List<Integer> all = getSubAttributes(quark, recursive);
286 List<Integer> ret = new LinkedList<>();
287 for (Integer attQuark : all) {
288 String name = getAttributeName(attQuark.intValue());
289 if (name.matches(pattern)) {
290 ret.add(attQuark);
291 }
292 }
293 return ret;
294 }
295
0fdd2c45
FG
296 @Override
297 public int getParentAttributeQuark(int quark) {
298 return getAttributeTree().getParentAttributeQuark(quark);
299 }
300
8d1346f0 301 @Override
df2597e0
AM
302 public List<@NonNull Integer> getQuarks(String... pattern) {
303 List<@NonNull Integer> quarks = new LinkedList<>();
a4524c1b
AM
304 List<String> prefix = new LinkedList<>();
305 List<String> suffix = new LinkedList<>();
f94a0bac
AM
306 boolean split = false;
307 String[] prefixStr;
308 String[] suffixStr;
309 List<Integer> directChildren;
310 int startingAttribute;
311
312 /* Fill the "prefix" and "suffix" parts of the pattern around the '*' */
313 for (String entry : pattern) {
314 if (entry.equals("*")) { //$NON-NLS-1$
315 if (split) {
316 /*
317 * Split was already true? This means there was more than
318 * one wildcard. This is not supported, return an empty
319 * list.
320 */
321 return quarks;
322 }
323 split = true;
324 continue;
325 }
326
327 if (split) {
328 suffix.add(entry);
329 } else {
330 prefix.add(entry);
331 }
332 }
333 prefixStr = prefix.toArray(new String[prefix.size()]);
334 suffixStr = suffix.toArray(new String[suffix.size()]);
335
336 /*
337 * If there was no wildcard, we'll only return the one matching
338 * attribute, if there is one.
339 */
cb42195c 340 if (!split) {
f94a0bac
AM
341 int quark;
342 try {
343 quark = getQuarkAbsolute(prefixStr);
344 } catch (AttributeNotFoundException e) {
345 /* It's fine, we'll just return the empty List */
346 return quarks;
347 }
348 quarks.add(quark);
349 return quarks;
350 }
351
c44f0a0c
PT
352 if (prefix.isEmpty()) {
353 /*
354 * If 'prefix' is empty, this means the wildcard was the first
355 * element. Look for the root node's sub-attributes.
356 */
357 startingAttribute = ROOT_ATTRIBUTE;
358 } else {
359 startingAttribute = optQuarkAbsolute(prefixStr);
360 if (startingAttribute == INVALID_ATTRIBUTE) {
361 /* That attribute path did not exist, return the empty array */
362 return quarks;
f94a0bac 363 }
c44f0a0c
PT
364 }
365 try {
339d27b4 366 directChildren = getSubAttributes(startingAttribute, false);
f94a0bac 367 } catch (AttributeNotFoundException e) {
c44f0a0c
PT
368 /* Should not happen, starting attribute is a valid quark */
369 throw new IllegalStateException();
f94a0bac
AM
370 }
371
372 /*
373 * Iterate of all the sub-attributes, and only keep those who match the
374 * 'suffix' part of the initial pattern.
375 */
376 for (int childQuark : directChildren) {
c44f0a0c
PT
377 int matchingQuark = optQuarkRelative(childQuark, suffixStr);
378 if (matchingQuark != INVALID_ATTRIBUTE) {
379 quarks.add(matchingQuark);
f94a0bac 380 }
f94a0bac
AM
381 }
382
383 return quarks;
384 }
385
8d1346f0
AM
386 //--------------------------------------------------------------------------
387 // Methods related to insertions in the history
388 //--------------------------------------------------------------------------
a52fde77 389
8d1346f0 390 @Override
a52fde77 391 public void modifyAttribute(long t, ITmfStateValue value, int attributeQuark)
7e0b2b56
AM
392 throws TimeRangeException, AttributeNotFoundException,
393 StateValueTypeException {
feea3b3c
AM
394 if (value == null) {
395 /*
396 * TODO Replace with @NonNull parameter (will require fixing all the
397 * state providers!)
398 */
399 throw new IllegalArgumentException();
400 }
a52fde77
AM
401 transState.processStateChange(t, value, attributeQuark);
402 }
403
8d1346f0 404 @Override
a52fde77
AM
405 public void incrementAttribute(long t, int attributeQuark)
406 throws StateValueTypeException, TimeRangeException,
407 AttributeNotFoundException {
359eeba0
PT
408 ITmfStateValue stateValue = queryOngoingState(attributeQuark);
409 int prevValue = 0;
410 /* if the attribute was previously null, start counting at 0 */
411 if (!stateValue.isNull()) {
412 prevValue = stateValue.unboxInt();
280bbdbb 413 }
a52fde77
AM
414 modifyAttribute(t, TmfStateValue.newValueInt(prevValue + 1),
415 attributeQuark);
416 }
417
8d1346f0 418 @Override
a52fde77
AM
419 public void pushAttribute(long t, ITmfStateValue value, int attributeQuark)
420 throws TimeRangeException, AttributeNotFoundException,
421 StateValueTypeException {
0126a8ca 422 int stackDepth;
a52fde77
AM
423 int subAttributeQuark;
424 ITmfStateValue previousSV = transState.getOngoingStateValue(attributeQuark);
425
426 if (previousSV.isNull()) {
427 /*
428 * If the StateValue was null, this means this is the first time we
429 * use this attribute. Leave stackDepth at 0.
430 */
cb42195c 431 stackDepth = 0;
b67a2540 432 } else if (previousSV.getType() == Type.INTEGER) {
a52fde77
AM
433 /* Previous value was an integer, all is good, use it */
434 stackDepth = previousSV.unboxInt();
a52fde77
AM
435 } else {
436 /* Previous state of this attribute was another type? Not good! */
e13bd4cd 437 throw new StateValueTypeException(getSSID() + " Quark:" + attributeQuark + ", Type:" + previousSV.getType() + ", Expected:" + Type.INTEGER); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
90a25ebe
AM
438 }
439
e8251298 440 if (stackDepth >= 100000) {
90a25ebe 441 /*
a0f8fb9b
FW
442 * Limit stackDepth to 100000, to avoid having Attribute Trees grow
443 * out of control due to buggy insertions
90a25ebe 444 */
e13bd4cd
PT
445 String message = " Stack limit reached, not pushing"; //$NON-NLS-1$
446 throw new AttributeNotFoundException(getSSID() + " Quark:" + attributeQuark + message); //$NON-NLS-1$
a52fde77
AM
447 }
448
449 stackDepth++;
0126a8ca 450 subAttributeQuark = getQuarkRelativeAndAdd(attributeQuark, String.valueOf(stackDepth));
a52fde77 451
5896eb76 452 modifyAttribute(t, TmfStateValue.newValueInt(stackDepth), attributeQuark);
90a25ebe 453 modifyAttribute(t, value, subAttributeQuark);
a52fde77
AM
454 }
455
8d1346f0 456 @Override
5896eb76 457 public ITmfStateValue popAttribute(long t, int attributeQuark)
a52fde77
AM
458 throws AttributeNotFoundException, TimeRangeException,
459 StateValueTypeException {
e2eac108 460 /* These are the state values of the stack-attribute itself */
e13bd4cd 461 ITmfStateValue previousSV = transState.getOngoingStateValue(attributeQuark);
a52fde77
AM
462
463 if (previousSV.isNull()) {
e2eac108
AM
464 /*
465 * Trying to pop an empty stack. This often happens at the start of
466 * traces, for example when we see a syscall_exit, without having
467 * the corresponding syscall_entry in the trace. Just ignore
468 * silently.
469 */
5896eb76 470 return null;
90a25ebe 471 }
b67a2540 472 if (previousSV.getType() != Type.INTEGER) {
a52fde77 473 /*
b67a2540
AM
474 * The existing value was not an integer (which is expected for
475 * stack tops), this doesn't look like a valid stack attribute.
a52fde77 476 */
e13bd4cd 477 throw new StateValueTypeException(getSSID() + " Quark:" + attributeQuark + ", Type:" + previousSV.getType() + ", Expected:" + Type.INTEGER); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
a52fde77
AM
478 }
479
0126a8ca 480 int stackDepth = previousSV.unboxInt();
90a25ebe 481
e2eac108 482 if (stackDepth <= 0) {
a52fde77 483 /* This on the other hand should not happen... */
e13bd4cd 484 throw new StateValueTypeException(getSSID() + " Quark:" + attributeQuark + ", Stack depth:" + stackDepth); //$NON-NLS-1$//$NON-NLS-2$
a52fde77
AM
485 }
486
e2eac108 487 /* The attribute should already exist at this point */
0126a8ca 488 int subAttributeQuark = getQuarkRelative(attributeQuark, String.valueOf(stackDepth));
5896eb76 489 ITmfStateValue poppedValue = queryOngoingState(subAttributeQuark);
a52fde77 490
e2eac108
AM
491 /* Update the state value of the stack-attribute */
492 ITmfStateValue nextSV;
a0f8fb9b 493 if (--stackDepth == 0) {
359eeba0 494 /* Store a null state value */
e2eac108
AM
495 nextSV = TmfStateValue.nullValue();
496 } else {
497 nextSV = TmfStateValue.newValueInt(stackDepth);
498 }
499 modifyAttribute(t, nextSV, attributeQuark);
500
501 /* Delete the sub-attribute that contained the user's state value */
a52fde77 502 removeAttribute(t, subAttributeQuark);
e2eac108 503
5896eb76 504 return poppedValue;
a52fde77
AM
505 }
506
8d1346f0 507 @Override
a52fde77
AM
508 public void removeAttribute(long t, int attributeQuark)
509 throws TimeRangeException, AttributeNotFoundException {
feea3b3c
AM
510 if (attributeQuark < 0) {
511 throw new IllegalArgumentException();
512 }
c66426fd
AM
513
514 /*
feea3b3c 515 * Nullify our children first, recursively. We pass 'false' because we
c66426fd
AM
516 * handle the recursion ourselves.
517 */
feea3b3c 518 List<Integer> childAttributes = getSubAttributes(attributeQuark, false);
0126a8ca 519 for (int childNodeQuark : childAttributes) {
feea3b3c
AM
520 if (attributeQuark == childNodeQuark) {
521 /* Something went very wrong when building out attribute tree */
522 throw new IllegalStateException();
523 }
a52fde77
AM
524 removeAttribute(t, childNodeQuark);
525 }
526 /* Nullify ourselves */
7e0b2b56 527 try {
feea3b3c 528 transState.processStateChange(t, TmfStateValue.nullValue(), attributeQuark);
7e0b2b56 529 } catch (StateValueTypeException e) {
50678114
AM
530 /*
531 * Will not happen since we're inserting null values only, but poor
532 * compiler has no way of knowing this...
7e0b2b56 533 */
cb42195c 534 throw new IllegalStateException(e);
7e0b2b56 535 }
a52fde77
AM
536 }
537
8d1346f0
AM
538 //--------------------------------------------------------------------------
539 // "Current" query/update methods
540 //--------------------------------------------------------------------------
a52fde77 541
8d1346f0 542 @Override
a52fde77
AM
543 public ITmfStateValue queryOngoingState(int attributeQuark)
544 throws AttributeNotFoundException {
545 return transState.getOngoingStateValue(attributeQuark);
546 }
547
602c0697
AM
548 @Override
549 public long getOngoingStartTime(int attribute)
550 throws AttributeNotFoundException {
551 return transState.getOngoingStartTime(attribute);
552 }
553
8d1346f0 554 @Override
a52fde77
AM
555 public void updateOngoingState(ITmfStateValue newValue, int attributeQuark)
556 throws AttributeNotFoundException {
557 transState.changeOngoingStateValue(attributeQuark, newValue);
558 }
559
66866869
AM
560 /**
561 * Modify the whole "ongoing state" (state values + start times). This can
562 * be used when "seeking" a state system to a different point in the trace
563 * (and restoring the known stateInfo at this location). Use with care!
564 *
565 * @param newStateIntervals
566 * The new List of state values to use as ongoing state info
567 */
df2597e0 568 protected void replaceOngoingState(@NonNull List<@NonNull ITmfStateInterval> newStateIntervals) {
66866869 569 transState.replaceOngoingState(newStateIntervals);
a0f8fb9b 570 }
66866869 571
8d1346f0
AM
572 //--------------------------------------------------------------------------
573 // Regular query methods (sent to the back-end)
574 //--------------------------------------------------------------------------
575
576 @Override
577 public synchronized List<ITmfStateInterval> queryFullState(long t)
96345c5a
AM
578 throws TimeRangeException, StateSystemDisposedException {
579 if (isDisposed) {
580 throw new StateSystemDisposedException();
581 }
582
e62a23a9 583 final int nbAttr = getNbAttributes();
df2597e0 584 List<@Nullable ITmfStateInterval> stateInfo = new ArrayList<>(nbAttr);
8d1346f0
AM
585
586 /* Bring the size of the array to the current number of attributes */
e62a23a9 587 for (int i = 0; i < nbAttr; i++) {
8d1346f0
AM
588 stateInfo.add(null);
589 }
590
8d1346f0
AM
591 /*
592 * If we are currently building the history, also query the "ongoing"
593 * states for stuff that might not yet be written to the history.
594 */
595 if (transState.isActive()) {
596 transState.doQuery(stateInfo, t);
597 }
598
e62a23a9
AM
599 /* Query the storage backend */
600 backend.doQuery(stateInfo, t);
601
8d1346f0
AM
602 /*
603 * We should have previously inserted an interval for every attribute.
8d1346f0 604 */
e62a23a9
AM
605 for (ITmfStateInterval interval : stateInfo) {
606 if (interval == null) {
607 throw new IllegalStateException("Incoherent interval storage"); //$NON-NLS-1$
8d1346f0
AM
608 }
609 }
610 return stateInfo;
50678114
AM
611 }
612
8d1346f0
AM
613 @Override
614 public ITmfStateInterval querySingleState(long t, int attributeQuark)
96345c5a
AM
615 throws AttributeNotFoundException, TimeRangeException,
616 StateSystemDisposedException {
617 if (isDisposed) {
618 throw new StateSystemDisposedException();
619 }
8d1346f0 620
09e6fd9b
AM
621 ITmfStateInterval ret = transState.getIntervalAt(t, attributeQuark);
622 if (ret == null) {
623 /*
624 * The transient state did not have the information, let's look into
625 * the backend next.
626 */
8d1346f0
AM
627 ret = backend.doSingularQuery(t, attributeQuark);
628 }
629
8d1346f0 630 if (ret == null) {
e62a23a9
AM
631 /*
632 * If we did our job correctly, there should be intervals for every
633 * possible attribute, over all the valid time range.
634 */
635 throw new IllegalStateException("Incoherent interval storage"); //$NON-NLS-1$
8d1346f0
AM
636 }
637 return ret;
638 }
639
8d1346f0
AM
640 //--------------------------------------------------------------------------
641 // Debug methods
642 //--------------------------------------------------------------------------
643
644 static void logMissingInterval(int attribute, long timestamp) {
bcec0116 645 Activator.getDefault().logInfo("No data found in history for attribute " + //$NON-NLS-1$
8d1346f0
AM
646 attribute + " at time " + timestamp + //$NON-NLS-1$
647 ", returning dummy interval"); //$NON-NLS-1$
a52fde77
AM
648 }
649
650 /**
651 * Print out the contents of the inner structures.
5df842b3 652 *
a52fde77
AM
653 * @param writer
654 * The PrintWriter in which to print the output
655 */
feea3b3c 656 public void debugPrint(@NonNull PrintWriter writer) {
339d27b4 657 getAttributeTree().debugPrint(writer);
a52fde77 658 transState.debugPrint(writer);
8d1346f0 659 backend.debugPrint(writer);
a52fde77
AM
660 }
661
8d1346f0 662}
This page took 0.111197 seconds and 5 git commands to generate.