lttng: Remove lttng2.control from required plugins of kernel.core
[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
acec47ce 404 @Deprecated
8d1346f0 405 @Override
a52fde77
AM
406 public void incrementAttribute(long t, int attributeQuark)
407 throws StateValueTypeException, TimeRangeException,
408 AttributeNotFoundException {
359eeba0
PT
409 ITmfStateValue stateValue = queryOngoingState(attributeQuark);
410 int prevValue = 0;
411 /* if the attribute was previously null, start counting at 0 */
412 if (!stateValue.isNull()) {
413 prevValue = stateValue.unboxInt();
280bbdbb 414 }
a52fde77
AM
415 modifyAttribute(t, TmfStateValue.newValueInt(prevValue + 1),
416 attributeQuark);
417 }
418
8d1346f0 419 @Override
a52fde77
AM
420 public void pushAttribute(long t, ITmfStateValue value, int attributeQuark)
421 throws TimeRangeException, AttributeNotFoundException,
422 StateValueTypeException {
0126a8ca 423 int stackDepth;
a52fde77
AM
424 int subAttributeQuark;
425 ITmfStateValue previousSV = transState.getOngoingStateValue(attributeQuark);
426
427 if (previousSV.isNull()) {
428 /*
429 * If the StateValue was null, this means this is the first time we
430 * use this attribute. Leave stackDepth at 0.
431 */
cb42195c 432 stackDepth = 0;
b67a2540 433 } else if (previousSV.getType() == Type.INTEGER) {
a52fde77
AM
434 /* Previous value was an integer, all is good, use it */
435 stackDepth = previousSV.unboxInt();
a52fde77
AM
436 } else {
437 /* Previous state of this attribute was another type? Not good! */
e13bd4cd 438 throw new StateValueTypeException(getSSID() + " Quark:" + attributeQuark + ", Type:" + previousSV.getType() + ", Expected:" + Type.INTEGER); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
90a25ebe
AM
439 }
440
e8251298 441 if (stackDepth >= 100000) {
90a25ebe 442 /*
a0f8fb9b
FW
443 * Limit stackDepth to 100000, to avoid having Attribute Trees grow
444 * out of control due to buggy insertions
90a25ebe 445 */
e13bd4cd
PT
446 String message = " Stack limit reached, not pushing"; //$NON-NLS-1$
447 throw new AttributeNotFoundException(getSSID() + " Quark:" + attributeQuark + message); //$NON-NLS-1$
a52fde77
AM
448 }
449
450 stackDepth++;
0126a8ca 451 subAttributeQuark = getQuarkRelativeAndAdd(attributeQuark, String.valueOf(stackDepth));
a52fde77 452
5896eb76 453 modifyAttribute(t, TmfStateValue.newValueInt(stackDepth), attributeQuark);
90a25ebe 454 modifyAttribute(t, value, subAttributeQuark);
a52fde77
AM
455 }
456
8d1346f0 457 @Override
5896eb76 458 public ITmfStateValue popAttribute(long t, int attributeQuark)
a52fde77
AM
459 throws AttributeNotFoundException, TimeRangeException,
460 StateValueTypeException {
e2eac108 461 /* These are the state values of the stack-attribute itself */
e13bd4cd 462 ITmfStateValue previousSV = transState.getOngoingStateValue(attributeQuark);
a52fde77
AM
463
464 if (previousSV.isNull()) {
e2eac108
AM
465 /*
466 * Trying to pop an empty stack. This often happens at the start of
467 * traces, for example when we see a syscall_exit, without having
468 * the corresponding syscall_entry in the trace. Just ignore
469 * silently.
470 */
5896eb76 471 return null;
90a25ebe 472 }
b67a2540 473 if (previousSV.getType() != Type.INTEGER) {
a52fde77 474 /*
b67a2540
AM
475 * The existing value was not an integer (which is expected for
476 * stack tops), this doesn't look like a valid stack attribute.
a52fde77 477 */
e13bd4cd 478 throw new StateValueTypeException(getSSID() + " Quark:" + attributeQuark + ", Type:" + previousSV.getType() + ", Expected:" + Type.INTEGER); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
a52fde77
AM
479 }
480
0126a8ca 481 int stackDepth = previousSV.unboxInt();
90a25ebe 482
e2eac108 483 if (stackDepth <= 0) {
a52fde77 484 /* This on the other hand should not happen... */
e13bd4cd 485 throw new StateValueTypeException(getSSID() + " Quark:" + attributeQuark + ", Stack depth:" + stackDepth); //$NON-NLS-1$//$NON-NLS-2$
a52fde77
AM
486 }
487
e2eac108 488 /* The attribute should already exist at this point */
0126a8ca 489 int subAttributeQuark = getQuarkRelative(attributeQuark, String.valueOf(stackDepth));
5896eb76 490 ITmfStateValue poppedValue = queryOngoingState(subAttributeQuark);
a52fde77 491
e2eac108
AM
492 /* Update the state value of the stack-attribute */
493 ITmfStateValue nextSV;
a0f8fb9b 494 if (--stackDepth == 0) {
359eeba0 495 /* Store a null state value */
e2eac108
AM
496 nextSV = TmfStateValue.nullValue();
497 } else {
498 nextSV = TmfStateValue.newValueInt(stackDepth);
499 }
500 modifyAttribute(t, nextSV, attributeQuark);
501
502 /* Delete the sub-attribute that contained the user's state value */
a52fde77 503 removeAttribute(t, subAttributeQuark);
e2eac108 504
5896eb76 505 return poppedValue;
a52fde77
AM
506 }
507
8d1346f0 508 @Override
a52fde77
AM
509 public void removeAttribute(long t, int attributeQuark)
510 throws TimeRangeException, AttributeNotFoundException {
feea3b3c
AM
511 if (attributeQuark < 0) {
512 throw new IllegalArgumentException();
513 }
c66426fd
AM
514
515 /*
feea3b3c 516 * Nullify our children first, recursively. We pass 'false' because we
c66426fd
AM
517 * handle the recursion ourselves.
518 */
feea3b3c 519 List<Integer> childAttributes = getSubAttributes(attributeQuark, false);
0126a8ca 520 for (int childNodeQuark : childAttributes) {
feea3b3c
AM
521 if (attributeQuark == childNodeQuark) {
522 /* Something went very wrong when building out attribute tree */
523 throw new IllegalStateException();
524 }
a52fde77
AM
525 removeAttribute(t, childNodeQuark);
526 }
527 /* Nullify ourselves */
7e0b2b56 528 try {
feea3b3c 529 transState.processStateChange(t, TmfStateValue.nullValue(), attributeQuark);
7e0b2b56 530 } catch (StateValueTypeException e) {
50678114
AM
531 /*
532 * Will not happen since we're inserting null values only, but poor
533 * compiler has no way of knowing this...
7e0b2b56 534 */
cb42195c 535 throw new IllegalStateException(e);
7e0b2b56 536 }
a52fde77
AM
537 }
538
8d1346f0
AM
539 //--------------------------------------------------------------------------
540 // "Current" query/update methods
541 //--------------------------------------------------------------------------
a52fde77 542
8d1346f0 543 @Override
a52fde77
AM
544 public ITmfStateValue queryOngoingState(int attributeQuark)
545 throws AttributeNotFoundException {
546 return transState.getOngoingStateValue(attributeQuark);
547 }
548
602c0697
AM
549 @Override
550 public long getOngoingStartTime(int attribute)
551 throws AttributeNotFoundException {
552 return transState.getOngoingStartTime(attribute);
553 }
554
8d1346f0 555 @Override
a52fde77
AM
556 public void updateOngoingState(ITmfStateValue newValue, int attributeQuark)
557 throws AttributeNotFoundException {
558 transState.changeOngoingStateValue(attributeQuark, newValue);
559 }
560
66866869
AM
561 /**
562 * Modify the whole "ongoing state" (state values + start times). This can
563 * be used when "seeking" a state system to a different point in the trace
564 * (and restoring the known stateInfo at this location). Use with care!
565 *
566 * @param newStateIntervals
567 * The new List of state values to use as ongoing state info
568 */
df2597e0 569 protected void replaceOngoingState(@NonNull List<@NonNull ITmfStateInterval> newStateIntervals) {
66866869 570 transState.replaceOngoingState(newStateIntervals);
a0f8fb9b 571 }
66866869 572
8d1346f0
AM
573 //--------------------------------------------------------------------------
574 // Regular query methods (sent to the back-end)
575 //--------------------------------------------------------------------------
576
577 @Override
578 public synchronized List<ITmfStateInterval> queryFullState(long t)
96345c5a
AM
579 throws TimeRangeException, StateSystemDisposedException {
580 if (isDisposed) {
581 throw new StateSystemDisposedException();
582 }
583
e62a23a9 584 final int nbAttr = getNbAttributes();
df2597e0 585 List<@Nullable ITmfStateInterval> stateInfo = new ArrayList<>(nbAttr);
8d1346f0
AM
586
587 /* Bring the size of the array to the current number of attributes */
e62a23a9 588 for (int i = 0; i < nbAttr; i++) {
8d1346f0
AM
589 stateInfo.add(null);
590 }
591
8d1346f0
AM
592 /*
593 * If we are currently building the history, also query the "ongoing"
594 * states for stuff that might not yet be written to the history.
595 */
596 if (transState.isActive()) {
597 transState.doQuery(stateInfo, t);
598 }
599
e62a23a9
AM
600 /* Query the storage backend */
601 backend.doQuery(stateInfo, t);
602
8d1346f0
AM
603 /*
604 * We should have previously inserted an interval for every attribute.
8d1346f0 605 */
e62a23a9
AM
606 for (ITmfStateInterval interval : stateInfo) {
607 if (interval == null) {
608 throw new IllegalStateException("Incoherent interval storage"); //$NON-NLS-1$
8d1346f0
AM
609 }
610 }
611 return stateInfo;
50678114
AM
612 }
613
8d1346f0
AM
614 @Override
615 public ITmfStateInterval querySingleState(long t, int attributeQuark)
96345c5a
AM
616 throws AttributeNotFoundException, TimeRangeException,
617 StateSystemDisposedException {
618 if (isDisposed) {
619 throw new StateSystemDisposedException();
620 }
8d1346f0 621
09e6fd9b
AM
622 ITmfStateInterval ret = transState.getIntervalAt(t, attributeQuark);
623 if (ret == null) {
624 /*
625 * The transient state did not have the information, let's look into
626 * the backend next.
627 */
8d1346f0
AM
628 ret = backend.doSingularQuery(t, attributeQuark);
629 }
630
8d1346f0 631 if (ret == null) {
e62a23a9
AM
632 /*
633 * If we did our job correctly, there should be intervals for every
634 * possible attribute, over all the valid time range.
635 */
636 throw new IllegalStateException("Incoherent interval storage"); //$NON-NLS-1$
8d1346f0
AM
637 }
638 return ret;
639 }
640
8d1346f0
AM
641 //--------------------------------------------------------------------------
642 // Debug methods
643 //--------------------------------------------------------------------------
644
645 static void logMissingInterval(int attribute, long timestamp) {
bcec0116 646 Activator.getDefault().logInfo("No data found in history for attribute " + //$NON-NLS-1$
8d1346f0
AM
647 attribute + " at time " + timestamp + //$NON-NLS-1$
648 ", returning dummy interval"); //$NON-NLS-1$
a52fde77
AM
649 }
650
651 /**
652 * Print out the contents of the inner structures.
5df842b3 653 *
a52fde77
AM
654 * @param writer
655 * The PrintWriter in which to print the output
656 */
feea3b3c 657 public void debugPrint(@NonNull PrintWriter writer) {
339d27b4 658 getAttributeTree().debugPrint(writer);
a52fde77 659 transState.debugPrint(writer);
8d1346f0 660 backend.debugPrint(writer);
a52fde77
AM
661 }
662
8d1346f0 663}
This page took 0.112541 seconds and 5 git commands to generate.