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