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