From 1dd75589718832113f585fbae2b786aa11a673a3 Mon Sep 17 00:00:00 2001 From: Alexandre Montplaisir Date: Thu, 2 Oct 2014 17:59:10 -0400 Subject: [PATCH] ss: Add a StateSystemUtils for advanced queries We want to offer convenience and advance query methods for the state system, but these should not be part of the ITmfStateSystem interface. That one should only be for the "basic" types. Everything else should go in a separate utility class. Change-Id: I62936e77454112c67f6861a1f0ca7a60c9aef2d1 Signed-off-by: Alexandre Montplaisir Reviewed-on: https://git.eclipse.org/r/35341 --- .../tests/stateprovider/StateSystemTest.java | 38 ++- .../ui/views/controlflow/ControlFlowView.java | 7 +- .../ui/views/cpuusage/CpuUsageComposite.java | 5 +- .../ui/views/resources/ResourcesView.java | 7 +- .../trace/callstack/AbstractProviderTest.java | 7 +- .../core/tests/StateSystemPushPopTest.java | 69 ++--- .../core/tests/StateSystemUtilsTest.java | 120 ++++++++ .../statesystem/core/StateSystem.java | 118 +------- .../statesystem/core/ITmfStateSystem.java | 97 +----- .../core/ITmfStateSystemBuilder.java | 2 + .../statesystem/core/StateSystemUtils.java | 281 ++++++++++++++++++ .../xml/ui/views/timegraph/XmlEntry.java | 3 +- .../ui/views/timegraph/XmlTimeGraphView.java | 3 +- .../mipmap/TmfStateSystemOperations.java | 6 +- .../tmf/ui/views/callstack/CallStackView.java | 3 +- 15 files changed, 489 insertions(+), 277 deletions(-) create mode 100644 org.eclipse.tracecompass.statesystem.core.tests/src/org/eclipse/tracecompass/statesystem/core/tests/StateSystemUtilsTest.java create mode 100644 org.eclipse.tracecompass.statesystem.core/src/org/eclipse/tracecompass/statesystem/core/StateSystemUtils.java diff --git a/org.eclipse.tracecompass.lttng2.kernel.core.tests/src/org/eclipse/tracecompass/lttng2/kernel/core/tests/stateprovider/StateSystemTest.java b/org.eclipse.tracecompass.lttng2.kernel.core.tests/src/org/eclipse/tracecompass/lttng2/kernel/core/tests/stateprovider/StateSystemTest.java index 0900e3fc3e..ae7ab0fff0 100644 --- a/org.eclipse.tracecompass.lttng2.kernel.core.tests/src/org/eclipse/tracecompass/lttng2/kernel/core/tests/stateprovider/StateSystemTest.java +++ b/org.eclipse.tracecompass.lttng2.kernel.core.tests/src/org/eclipse/tracecompass/lttng2/kernel/core/tests/stateprovider/StateSystemTest.java @@ -22,6 +22,7 @@ import java.util.List; import org.eclipse.tracecompass.internal.lttng2.kernel.core.Attributes; import org.eclipse.tracecompass.statesystem.core.ITmfStateSystem; +import org.eclipse.tracecompass.statesystem.core.StateSystemUtils; import org.eclipse.tracecompass.statesystem.core.exceptions.AttributeNotFoundException; import org.eclipse.tracecompass.statesystem.core.exceptions.StateSystemDisposedException; import org.eclipse.tracecompass.statesystem.core.exceptions.StateValueTypeException; @@ -145,9 +146,12 @@ public abstract class StateSystemTest { int quark; List intervals; + final ITmfStateSystem ss = fixture; + assertNotNull(ss); + try { - quark = fixture.getQuarkAbsolute(Attributes.CPUS, "0", Attributes.CURRENT_THREAD); - intervals = fixture.queryHistoryRange(quark, time1, time2); + quark = ss.getQuarkAbsolute(Attributes.CPUS, "0", Attributes.CURRENT_THREAD); + intervals = StateSystemUtils.queryHistoryRange(ss, quark, time1, time2); assertEquals(487, intervals.size()); /* Number of context switches! */ assertEquals(1685, intervals.get(100).getStateValue().unboxInt()); assertEquals(1331668248427681372L, intervals.get(205).getEndTime()); @@ -165,12 +169,15 @@ public abstract class StateSystemTest { public void testRangeQuery2() { List intervals; + final ITmfStateSystem ss = fixture; + assertNotNull(ss); + try { - int quark = fixture.getQuarkAbsolute(Attributes.RESOURCES, Attributes.IRQS, "1"); - long ts1 = fixture.getStartTime(); /* start of the trace */ + int quark = ss.getQuarkAbsolute(Attributes.RESOURCES, Attributes.IRQS, "1"); + long ts1 = ss.getStartTime(); /* start of the trace */ long ts2 = startTime + 20L * NANOSECS_PER_SEC; /* invalid, but ignored */ - intervals = fixture.queryHistoryRange(quark, ts1, ts2); + intervals = StateSystemUtils.queryHistoryRange(ss, quark, ts1, ts2); /* Activity of IRQ 1 over the whole trace */ assertEquals(65, intervals.size()); @@ -191,9 +198,12 @@ public abstract class StateSystemTest { int quark; List intervals; + final ITmfStateSystem ss = fixture; + assertNotNull(ss); + try { - quark = fixture.getQuarkAbsolute(Attributes.CPUS, "0", Attributes.CURRENT_THREAD); - intervals = fixture.queryHistoryRange(quark, time1, time2, resolution, null); + quark = ss.getQuarkAbsolute(Attributes.CPUS, "0", Attributes.CURRENT_THREAD); + intervals = StateSystemUtils.queryHistoryRange(ss, quark, time1, time2, resolution, null); assertEquals(126, intervals.size()); /* Number of context switches! */ assertEquals(1452, intervals.get(50).getStateValue().unboxInt()); assertEquals(1331668248815698779L, intervals.get(100).getEndTime()); @@ -246,11 +256,14 @@ public abstract class StateSystemTest { @Test(expected = TimeRangeException.class) public void testRangeQueryInvalidTime1() throws TimeRangeException { + final ITmfStateSystem ss = fixture; + assertNotNull(ss); + try { - int quark = fixture.getQuarkAbsolute(Attributes.CPUS, "0", Attributes.CURRENT_THREAD); + int quark = ss.getQuarkAbsolute(Attributes.CPUS, "0", Attributes.CURRENT_THREAD); long ts1 = startTime - 20L * NANOSECS_PER_SEC; /* invalid */ long ts2 = startTime + 1L * NANOSECS_PER_SEC; /* valid */ - fixture.queryHistoryRange(quark, ts1, ts2); + StateSystemUtils.queryHistoryRange(ss, quark, ts1, ts2); } catch (AttributeNotFoundException e) { fail(); @@ -261,11 +274,14 @@ public abstract class StateSystemTest { @Test(expected = TimeRangeException.class) public void testRangeQueryInvalidTime2() throws TimeRangeException { + final ITmfStateSystem ss = fixture; + assertNotNull(ss); + try { - int quark = fixture.getQuarkAbsolute(Attributes.CPUS, "0", Attributes.CURRENT_THREAD); + int quark = ss.getQuarkAbsolute(Attributes.CPUS, "0", Attributes.CURRENT_THREAD); long ts1 = startTime - 1L * NANOSECS_PER_SEC; /* invalid */ long ts2 = startTime + 20L * NANOSECS_PER_SEC; /* invalid */ - fixture.queryHistoryRange(quark, ts1, ts2); + StateSystemUtils.queryHistoryRange(ss, quark, ts1, ts2); } catch (AttributeNotFoundException | StateSystemDisposedException e) { fail(); diff --git a/org.eclipse.tracecompass.lttng2.kernel.ui/src/org/eclipse/tracecompass/internal/lttng2/kernel/ui/views/controlflow/ControlFlowView.java b/org.eclipse.tracecompass.lttng2.kernel.ui/src/org/eclipse/tracecompass/internal/lttng2/kernel/ui/views/controlflow/ControlFlowView.java index faad427fab..927a31c16f 100644 --- a/org.eclipse.tracecompass.lttng2.kernel.ui/src/org/eclipse/tracecompass/internal/lttng2/kernel/ui/views/controlflow/ControlFlowView.java +++ b/org.eclipse.tracecompass.lttng2.kernel.ui/src/org/eclipse/tracecompass/internal/lttng2/kernel/ui/views/controlflow/ControlFlowView.java @@ -29,6 +29,7 @@ import org.eclipse.tracecompass.internal.lttng2.kernel.ui.Activator; import org.eclipse.tracecompass.internal.lttng2.kernel.ui.Messages; import org.eclipse.tracecompass.lttng2.kernel.core.analysis.LttngKernelAnalysisModule; import org.eclipse.tracecompass.statesystem.core.ITmfStateSystem; +import org.eclipse.tracecompass.statesystem.core.StateSystemUtils; import org.eclipse.tracecompass.statesystem.core.exceptions.AttributeNotFoundException; import org.eclipse.tracecompass.statesystem.core.exceptions.StateSystemDisposedException; import org.eclipse.tracecompass.statesystem.core.exceptions.StateValueTypeException; @@ -270,7 +271,7 @@ public class ControlFlowView extends AbstractTimeGraphView { List execNameIntervals; try { execNameQuark = ssq.getQuarkRelative(threadQuark, Attributes.EXEC_NAME); - execNameIntervals = ssq.queryHistoryRange(execNameQuark, start, end); + execNameIntervals = StateSystemUtils.queryHistoryRange(ssq, execNameQuark, start, end); } catch (AttributeNotFoundException e) { /* No information on this thread (yet?), skip it for now */ continue; @@ -413,7 +414,7 @@ public class ControlFlowView extends AbstractTimeGraphView { } try { int statusQuark = ssq.getQuarkRelative(entry.getThreadQuark(), Attributes.STATUS); - List statusIntervals = ssq.queryHistoryRange(statusQuark, realStart, realEnd - 1, resolution, monitor); + List statusIntervals = StateSystemUtils.queryHistoryRange(ssq, statusQuark, realStart, realEnd - 1, resolution, monitor); eventList = new ArrayList<>(statusIntervals.size()); long lastEndTime = -1; for (ITmfStateInterval statusInterval : statusIntervals) { @@ -537,7 +538,7 @@ public class ControlFlowView extends AbstractTimeGraphView { // adjust the query range to include the previous and following intervals long qstart = Math.max(ssq.querySingleState(start, currentThreadQuark).getStartTime() - 1, ssq.getStartTime()); long qend = Math.min(ssq.querySingleState(end, currentThreadQuark).getEndTime() + 1, ssq.getCurrentEndTime()); - List currentThreadIntervals = ssq.queryHistoryRange(currentThreadQuark, qstart, qend, resolution, monitor); + List currentThreadIntervals = StateSystemUtils.queryHistoryRange(ssq, currentThreadQuark, qstart, qend, resolution, monitor); int prevThread = 0; long prevEnd = 0; long lastEnd = 0; diff --git a/org.eclipse.tracecompass.lttng2.kernel.ui/src/org/eclipse/tracecompass/internal/lttng2/kernel/ui/views/cpuusage/CpuUsageComposite.java b/org.eclipse.tracecompass.lttng2.kernel.ui/src/org/eclipse/tracecompass/internal/lttng2/kernel/ui/views/cpuusage/CpuUsageComposite.java index c29a6d2319..477d258f6e 100644 --- a/org.eclipse.tracecompass.lttng2.kernel.ui/src/org/eclipse/tracecompass/internal/lttng2/kernel/ui/views/cpuusage/CpuUsageComposite.java +++ b/org.eclipse.tracecompass.lttng2.kernel.ui/src/org/eclipse/tracecompass/internal/lttng2/kernel/ui/views/cpuusage/CpuUsageComposite.java @@ -28,6 +28,7 @@ import org.eclipse.tracecompass.internal.lttng2.kernel.core.Attributes; import org.eclipse.tracecompass.lttng2.kernel.core.analysis.LttngKernelAnalysisModule; import org.eclipse.tracecompass.lttng2.kernel.core.cpuusage.LttngKernelCpuUsageAnalysis; import org.eclipse.tracecompass.statesystem.core.ITmfStateSystem; +import org.eclipse.tracecompass.statesystem.core.StateSystemUtils; import org.eclipse.tracecompass.statesystem.core.exceptions.AttributeNotFoundException; import org.eclipse.tracecompass.statesystem.core.exceptions.StateSystemDisposedException; import org.eclipse.tracecompass.statesystem.core.interval.ITmfStateInterval; @@ -38,8 +39,8 @@ import org.eclipse.tracecompass.tmf.ui.viewers.tree.AbstractTmfTreeViewer; import org.eclipse.tracecompass.tmf.ui.viewers.tree.ITmfTreeColumnDataProvider; import org.eclipse.tracecompass.tmf.ui.viewers.tree.ITmfTreeViewerEntry; import org.eclipse.tracecompass.tmf.ui.viewers.tree.TmfTreeColumnData; -import org.eclipse.tracecompass.tmf.ui.viewers.tree.TmfTreeViewerEntry; import org.eclipse.tracecompass.tmf.ui.viewers.tree.TmfTreeColumnData.ITmfColumnPercentageProvider; +import org.eclipse.tracecompass.tmf.ui.viewers.tree.TmfTreeViewerEntry; /** * Tree viewer to display CPU usage information in a specified time range. It @@ -282,7 +283,7 @@ public class CpuUsageComposite extends AbstractTmfTreeViewer { List execNameIntervals; try { execNameQuark = kernelSs.getQuarkRelative(tidQuark, Attributes.EXEC_NAME); - execNameIntervals = kernelSs.queryHistoryRange(execNameQuark, getStartTime(), getEndTime()); + execNameIntervals = StateSystemUtils.queryHistoryRange(kernelSs, execNameQuark, getStartTime(), getEndTime()); } catch (AttributeNotFoundException e) { /* No information on this thread (yet?), skip it for now */ continue; diff --git a/org.eclipse.tracecompass.lttng2.kernel.ui/src/org/eclipse/tracecompass/internal/lttng2/kernel/ui/views/resources/ResourcesView.java b/org.eclipse.tracecompass.lttng2.kernel.ui/src/org/eclipse/tracecompass/internal/lttng2/kernel/ui/views/resources/ResourcesView.java index 9ddf9d56e8..e6b9adddd7 100644 --- a/org.eclipse.tracecompass.lttng2.kernel.ui/src/org/eclipse/tracecompass/internal/lttng2/kernel/ui/views/resources/ResourcesView.java +++ b/org.eclipse.tracecompass.lttng2.kernel.ui/src/org/eclipse/tracecompass/internal/lttng2/kernel/ui/views/resources/ResourcesView.java @@ -27,6 +27,7 @@ import org.eclipse.tracecompass.internal.lttng2.kernel.ui.Messages; import org.eclipse.tracecompass.internal.lttng2.kernel.ui.views.resources.ResourcesEntry.Type; import org.eclipse.tracecompass.lttng2.kernel.core.analysis.LttngKernelAnalysisModule; import org.eclipse.tracecompass.statesystem.core.ITmfStateSystem; +import org.eclipse.tracecompass.statesystem.core.StateSystemUtils; import org.eclipse.tracecompass.statesystem.core.exceptions.AttributeNotFoundException; import org.eclipse.tracecompass.statesystem.core.exceptions.StateSystemDisposedException; import org.eclipse.tracecompass.statesystem.core.exceptions.StateValueTypeException; @@ -222,7 +223,7 @@ public class ResourcesView extends AbstractTimeGraphView { try { if (resourcesEntry.getType().equals(Type.CPU)) { int statusQuark = ssq.getQuarkRelative(quark, Attributes.STATUS); - List statusIntervals = ssq.queryHistoryRange(statusQuark, realStart, realEnd - 1, resolution, monitor); + List statusIntervals = StateSystemUtils.queryHistoryRange(ssq, statusQuark, realStart, realEnd - 1, resolution, monitor); eventList = new ArrayList<>(statusIntervals.size()); long lastEndTime = -1; for (ITmfStateInterval statusInterval : statusIntervals) { @@ -244,7 +245,7 @@ public class ResourcesView extends AbstractTimeGraphView { lastEndTime = time + duration; } } else if (resourcesEntry.getType().equals(Type.IRQ)) { - List irqIntervals = ssq.queryHistoryRange(quark, realStart, realEnd - 1, resolution, monitor); + List irqIntervals = StateSystemUtils.queryHistoryRange(ssq, quark, realStart, realEnd - 1, resolution, monitor); eventList = new ArrayList<>(irqIntervals.size()); long lastEndTime = -1; boolean lastIsNull = true; @@ -277,7 +278,7 @@ public class ResourcesView extends AbstractTimeGraphView { lastEndTime = time + duration; } } else if (resourcesEntry.getType().equals(Type.SOFT_IRQ)) { - List softIrqIntervals = ssq.queryHistoryRange(quark, realStart, realEnd - 1, resolution, monitor); + List softIrqIntervals = StateSystemUtils.queryHistoryRange(ssq, quark, realStart, realEnd - 1, resolution, monitor); eventList = new ArrayList<>(softIrqIntervals.size()); long lastEndTime = -1; boolean lastIsNull = true; diff --git a/org.eclipse.tracecompass.lttng2.ust.core.tests/src/org/eclipse/tracecompass/lttng2/ust/core/tests/trace/callstack/AbstractProviderTest.java b/org.eclipse.tracecompass.lttng2.ust.core.tests/src/org/eclipse/tracecompass/lttng2/ust/core/tests/trace/callstack/AbstractProviderTest.java index 681c932513..414f4f8462 100644 --- a/org.eclipse.tracecompass.lttng2.ust.core.tests/src/org/eclipse/tracecompass/lttng2/ust/core/tests/trace/callstack/AbstractProviderTest.java +++ b/org.eclipse.tracecompass.lttng2.ust.core.tests/src/org/eclipse/tracecompass/lttng2/ust/core/tests/trace/callstack/AbstractProviderTest.java @@ -23,6 +23,7 @@ import java.util.List; import org.eclipse.tracecompass.internal.lttng2.ust.core.trace.callstack.LttngUstCallStackProvider; import org.eclipse.tracecompass.statesystem.core.ITmfStateSystem; +import org.eclipse.tracecompass.statesystem.core.StateSystemUtils; import org.eclipse.tracecompass.statesystem.core.exceptions.AttributeNotFoundException; import org.eclipse.tracecompass.statesystem.core.exceptions.StateSystemDisposedException; import org.eclipse.tracecompass.statesystem.core.interval.ITmfStateInterval; @@ -252,8 +253,10 @@ public abstract class AbstractProviderTest { int depth = state.get(stackAttribute).getStateValue().unboxInt(); int stackTop = ss.getQuarkRelative(stackAttribute, String.valueOf(depth)); - ITmfStateValue top = state.get(stackTop).getStateValue(); - assertEquals(top, ss.querySingleStackTop(timestamp, stackAttribute).getStateValue()); + ITmfStateValue expectedValue = state.get(stackTop).getStateValue(); + ITmfStateInterval interval = StateSystemUtils.querySingleStackTop(ss, timestamp, stackAttribute); + assertNotNull(interval); + assertEquals(expectedValue, interval.getStateValue()); String[] ret = new String[depth]; for (int i = 0; i < depth; i++) { diff --git a/org.eclipse.tracecompass.statesystem.core.tests/src/org/eclipse/tracecompass/statesystem/core/tests/StateSystemPushPopTest.java b/org.eclipse.tracecompass.statesystem.core.tests/src/org/eclipse/tracecompass/statesystem/core/tests/StateSystemPushPopTest.java index 14cd28c527..a3fe97c81b 100644 --- a/org.eclipse.tracecompass.statesystem.core.tests/src/org/eclipse/tracecompass/statesystem/core/tests/StateSystemPushPopTest.java +++ b/org.eclipse.tracecompass.statesystem.core.tests/src/org/eclipse/tracecompass/statesystem/core/tests/StateSystemPushPopTest.java @@ -14,6 +14,7 @@ package org.eclipse.tracecompass.statesystem.core.tests; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; @@ -23,6 +24,7 @@ import java.util.List; import org.eclipse.tracecompass.internal.statesystem.core.StateSystem; import org.eclipse.tracecompass.statesystem.core.ITmfStateSystemBuilder; +import org.eclipse.tracecompass.statesystem.core.StateSystemUtils; import org.eclipse.tracecompass.statesystem.core.backend.IStateHistoryBackend; import org.eclipse.tracecompass.statesystem.core.backend.historytree.HistoryTreeBackend; import org.eclipse.tracecompass.statesystem.core.exceptions.AttributeNotFoundException; @@ -45,8 +47,6 @@ import org.junit.Test; public class StateSystemPushPopTest { private ITmfStateSystemBuilder ss; - - private ITmfStateInterval interval; private int attribute; private File testHtFile; @@ -144,7 +144,7 @@ public class StateSystemPushPopTest { @Test public void testBeginEnd() { try { - interval = ss.querySingleState(0, attribute); + ITmfStateInterval interval = ss.querySingleState(0, attribute); assertEquals(0, interval.getStartTime()); assertEquals(1, interval.getEndTime()); assertTrue(interval.getStateValue().isNull()); @@ -169,7 +169,7 @@ public class StateSystemPushPopTest { final int subAttribute2 = ss.getQuarkRelative(attribute, "2"); /* Test the stack attributes themselves */ - interval = ss.querySingleState(11, attribute); + ITmfStateInterval interval = ss.querySingleState(11, attribute); assertEquals(4, interval.getStateValue().unboxInt()); interval = ss.querySingleState(24, attribute); @@ -185,13 +185,7 @@ public class StateSystemPushPopTest { interval = ss.querySingleState(25, subAttribute2); assertTrue(interval.getStateValue().isNull()); // Stack depth is 1 at that point. - } catch (AttributeNotFoundException e) { - fail(errMsg + e.toString()); - } catch (StateValueTypeException e) { - fail(errMsg + e.toString()); - } catch (TimeRangeException e) { - fail(errMsg + e.toString()); - } catch (StateSystemDisposedException e) { + } catch (AttributeNotFoundException | TimeRangeException | StateSystemDisposedException e) { fail(errMsg + e.toString()); } } @@ -201,29 +195,31 @@ public class StateSystemPushPopTest { */ @Test public void testStackTop() { + final ITmfStateSystemBuilder ss2 = ss; + assertNotNull(ss2); + try { - interval = ss.querySingleStackTop(10, attribute); + ITmfStateInterval interval = StateSystemUtils.querySingleStackTop(ss2, 10, attribute); + assertNotNull(interval); assertEquals(value5, interval.getStateValue()); - interval = ss.querySingleStackTop(9, attribute); + interval = StateSystemUtils.querySingleStackTop(ss2, 9, attribute); + assertNotNull(interval); assertEquals(value4, interval.getStateValue()); - interval = ss.querySingleStackTop(13, attribute); + interval = StateSystemUtils.querySingleStackTop(ss2, 13, attribute); + assertNotNull(interval); assertEquals(value3, interval.getStateValue()); - interval = ss.querySingleStackTop(16, attribute); + interval = StateSystemUtils.querySingleStackTop(ss2, 16, attribute); + assertNotNull(interval); assertEquals(value1, interval.getStateValue()); - interval = ss.querySingleStackTop(25, attribute); + interval = StateSystemUtils.querySingleStackTop(ss2, 25, attribute); + assertNotNull(interval); assertEquals(value1, interval.getStateValue()); - } catch (AttributeNotFoundException e) { - fail(errMsg + e.toString()); - } catch (StateValueTypeException e) { - fail(errMsg + e.toString()); - } catch (TimeRangeException e) { - fail(errMsg + e.toString()); - } catch (StateSystemDisposedException e) { + } catch (AttributeNotFoundException | TimeRangeException | StateSystemDisposedException e) { fail(errMsg + e.toString()); } } @@ -233,32 +229,29 @@ public class StateSystemPushPopTest { */ @Test public void testEmptyStack() { + final ITmfStateSystemBuilder ss2 = ss; + assertNotNull(ss2); + try { /* At the start */ - interval = ss.querySingleState(1, attribute); + ITmfStateInterval interval = ss.querySingleState(1, attribute); assertTrue(interval.getStateValue().isNull()); - interval = ss.querySingleStackTop(1, attribute); + interval = StateSystemUtils.querySingleStackTop(ss2, 1, attribute); assertEquals(null, interval); /* Between the two "stacks" in the state history */ interval = ss.querySingleState(19, attribute); assertTrue(interval.getStateValue().isNull()); - interval = ss.querySingleStackTop(19, attribute); + interval = StateSystemUtils.querySingleStackTop(ss2, 19, attribute); assertEquals(null, interval); /* At the end */ interval = ss.querySingleState(27, attribute); assertTrue(interval.getStateValue().isNull()); - interval = ss.querySingleStackTop(27, attribute); + interval = StateSystemUtils.querySingleStackTop(ss2, 27, attribute); assertEquals(null, interval); - } catch (AttributeNotFoundException e) { - fail(errMsg + e.toString()); - } catch (StateValueTypeException e) { - fail(errMsg + e.toString()); - } catch (TimeRangeException e) { - fail(errMsg + e.toString()); - } catch (StateSystemDisposedException e) { + } catch (AttributeNotFoundException | TimeRangeException | StateSystemDisposedException e) { fail(errMsg + e.toString()); } } @@ -299,13 +292,7 @@ public class StateSystemPushPopTest { assertTrue(state.get(subAttrib3).getStateValue().isNull()); assertTrue(state.get(subAttrib4).getStateValue().isNull()); - } catch (AttributeNotFoundException e) { - fail(errMsg + e.toString()); - } catch (StateValueTypeException e) { - fail(errMsg + e.toString()); - } catch (TimeRangeException e) { - fail(errMsg + e.toString()); - } catch (StateSystemDisposedException e) { + } catch (AttributeNotFoundException | TimeRangeException | StateSystemDisposedException e) { fail(errMsg + e.toString()); } } diff --git a/org.eclipse.tracecompass.statesystem.core.tests/src/org/eclipse/tracecompass/statesystem/core/tests/StateSystemUtilsTest.java b/org.eclipse.tracecompass.statesystem.core.tests/src/org/eclipse/tracecompass/statesystem/core/tests/StateSystemUtilsTest.java new file mode 100644 index 0000000000..4a01a01fd1 --- /dev/null +++ b/org.eclipse.tracecompass.statesystem.core.tests/src/org/eclipse/tracecompass/statesystem/core/tests/StateSystemUtilsTest.java @@ -0,0 +1,120 @@ +/******************************************************************************* + * Copyright (c) 2014 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.statesystem.core.tests; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.fail; + +import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.tracecompass.statesystem.core.ITmfStateSystem; +import org.eclipse.tracecompass.statesystem.core.ITmfStateSystemBuilder; +import org.eclipse.tracecompass.statesystem.core.StateSystemFactory; +import org.eclipse.tracecompass.statesystem.core.StateSystemUtils; +import org.eclipse.tracecompass.statesystem.core.backend.IStateHistoryBackend; +import org.eclipse.tracecompass.statesystem.core.backend.InMemoryBackend; +import org.eclipse.tracecompass.statesystem.core.exceptions.AttributeNotFoundException; +import org.eclipse.tracecompass.statesystem.core.exceptions.StateValueTypeException; +import org.eclipse.tracecompass.statesystem.core.interval.ITmfStateInterval; +import org.eclipse.tracecompass.statesystem.core.statevalue.ITmfStateValue; +import org.eclipse.tracecompass.statesystem.core.statevalue.TmfStateValue; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +/** + * Test the {@link StateSystemUtils} class + * + * @author Geneviève Bastien + */ +public class StateSystemUtilsTest { + + private static final long START_TIME = 1000L; + private static final @NonNull String DUMMY_STRING = "test"; + private static final int INT_VAL = 10; + + private ITmfStateSystemBuilder fStateSystem; + + /** + * Build a small test state system in memory + */ + @Before + public void setupStateSystem() { + try { + IStateHistoryBackend backend = new InMemoryBackend(START_TIME); + fStateSystem = StateSystemFactory.newStateSystem(DUMMY_STRING, backend); + int quark = fStateSystem.getQuarkAbsoluteAndAdd(DUMMY_STRING); + + fStateSystem.modifyAttribute(1200L, TmfStateValue.newValueInt(INT_VAL), quark); + fStateSystem.modifyAttribute(1500L, TmfStateValue.newValueInt(20), quark); + fStateSystem.closeHistory(2000L); + } catch (StateValueTypeException | AttributeNotFoundException e) { + fail(e.getMessage()); + } + } + + /** + * Clean-up + */ + @After + public void tearDown() { + fStateSystem.dispose(); + } + + /** + * Test the {@link StateSystemUtils#queryUntilNonNullValue} method. + */ + @Test + public void testQueryUntilNonNullValue() { + ITmfStateSystem ss = fStateSystem; + assertNotNull(ss); + + int quark; + try { + quark = ss.getQuarkAbsolute(DUMMY_STRING); + + /* Should return null if requested range is not within range */ + assertNull(StateSystemUtils.queryUntilNonNullValue(ss, quark, 0, 999L)); + assertNull(StateSystemUtils.queryUntilNonNullValue(ss, quark, 2001L, 5000L)); + + /* + * Should return null if request within range, but condition is + * false + */ + assertNull(StateSystemUtils.queryUntilNonNullValue(ss, quark, 1000L, 1199L)); + + /* + * Should return the right interval if an interval is within range, + * even if the range starts or ends outside state system range + */ + ITmfStateInterval interval = StateSystemUtils.queryUntilNonNullValue(ss, quark, 1000L, 1300L); + assertNotNull(interval); + assertEquals(ITmfStateValue.Type.INTEGER, interval.getStateValue().getType()); + assertEquals(INT_VAL, interval.getStateValue().unboxInt()); + + interval = StateSystemUtils.queryUntilNonNullValue(ss, quark, 800L, 2500L); + assertNotNull(interval); + assertEquals(ITmfStateValue.Type.INTEGER, interval.getStateValue().getType()); + assertEquals(INT_VAL, interval.getStateValue().unboxInt()); + + interval = StateSystemUtils.queryUntilNonNullValue(ss, quark, 1500L, 2500L); + assertNull(interval); + + } catch (AttributeNotFoundException e) { + fail(e.getMessage()); + } + + } + +} diff --git a/org.eclipse.tracecompass.statesystem.core/src/org/eclipse/tracecompass/internal/statesystem/core/StateSystem.java b/org.eclipse.tracecompass.statesystem.core/src/org/eclipse/tracecompass/internal/statesystem/core/StateSystem.java index 9ce0ff4402..15e2679b3d 100644 --- a/org.eclipse.tracecompass.statesystem.core/src/org/eclipse/tracecompass/internal/statesystem/core/StateSystem.java +++ b/org.eclipse.tracecompass.statesystem.core/src/org/eclipse/tracecompass/internal/statesystem/core/StateSystem.java @@ -21,8 +21,6 @@ import java.util.List; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; -import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.jdt.annotation.NonNull; import org.eclipse.tracecompass.statesystem.core.ITmfStateSystemBuilder; import org.eclipse.tracecompass.statesystem.core.backend.IStateHistoryBackend; @@ -33,8 +31,8 @@ import org.eclipse.tracecompass.statesystem.core.exceptions.TimeRangeException; import org.eclipse.tracecompass.statesystem.core.interval.ITmfStateInterval; import org.eclipse.tracecompass.statesystem.core.interval.TmfStateInterval; import org.eclipse.tracecompass.statesystem.core.statevalue.ITmfStateValue; -import org.eclipse.tracecompass.statesystem.core.statevalue.TmfStateValue; import org.eclipse.tracecompass.statesystem.core.statevalue.ITmfStateValue.Type; +import org.eclipse.tracecompass.statesystem.core.statevalue.TmfStateValue; /** * This is the core class of the Generic State System. It contains all the @@ -613,120 +611,6 @@ public class StateSystem implements ITmfStateSystemBuilder { return ret; } - @Override - public ITmfStateInterval querySingleStackTop(long t, int stackAttributeQuark) - throws StateValueTypeException, AttributeNotFoundException, - TimeRangeException, StateSystemDisposedException { - ITmfStateValue curStackStateValue = querySingleState(t, stackAttributeQuark).getStateValue(); - - if (curStackStateValue.isNull()) { - /* There is nothing stored in this stack at this moment */ - return null; - } - int curStackDepth = curStackStateValue.unboxInt(); - if (curStackDepth <= 0) { - /* - * This attribute is an integer attribute, but it doesn't seem like - * it's used as a stack-attribute... - */ - throw new StateValueTypeException(); - } - - int subAttribQuark = getQuarkRelative(stackAttributeQuark, String.valueOf(curStackDepth)); - return querySingleState(t, subAttribQuark); - } - - @Override - public List queryHistoryRange(int attributeQuark, - long t1, long t2) throws TimeRangeException, - AttributeNotFoundException, StateSystemDisposedException { - if (isDisposed) { - throw new StateSystemDisposedException(); - } - - List intervals; - ITmfStateInterval currentInterval; - long ts, tEnd; - - /* Make sure the time range makes sense */ - if (t2 < t1) { - throw new TimeRangeException(); - } - - /* Set the actual, valid end time of the range query */ - if (t2 > this.getCurrentEndTime()) { - tEnd = this.getCurrentEndTime(); - } else { - tEnd = t2; - } - - /* Get the initial state at time T1 */ - intervals = new ArrayList<>(); - currentInterval = querySingleState(t1, attributeQuark); - intervals.add(currentInterval); - - /* Get the following state changes */ - ts = currentInterval.getEndTime(); - while (ts != -1 && ts < tEnd) { - ts++; /* To "jump over" to the next state in the history */ - currentInterval = querySingleState(ts, attributeQuark); - intervals.add(currentInterval); - ts = currentInterval.getEndTime(); - } - return intervals; - } - - @Override - public List queryHistoryRange(int attributeQuark, - long t1, long t2, long resolution, IProgressMonitor monitor) - throws TimeRangeException, AttributeNotFoundException, - StateSystemDisposedException { - if (isDisposed) { - throw new StateSystemDisposedException(); - } - - List intervals = new LinkedList<>(); - ITmfStateInterval currentInterval = null; - long ts, tEnd; - - IProgressMonitor mon = monitor; - if (mon == null) { - mon = new NullProgressMonitor(); - } - - /* Make sure the time range makes sense */ - if (t2 < t1 || resolution <= 0) { - throw new TimeRangeException(); - } - - /* Set the actual, valid end time of the range query */ - if (t2 > this.getCurrentEndTime()) { - tEnd = this.getCurrentEndTime(); - } else { - tEnd = t2; - } - - /* - * Iterate over the "resolution points". We skip unneeded queries in the - * case the current interval is longer than the resolution. - */ - for (ts = t1; ts <= tEnd; - ts += ((currentInterval.getEndTime() - ts) / resolution + 1) * resolution) { - if (mon.isCanceled()) { - return intervals; - } - currentInterval = querySingleState(ts, attributeQuark); - intervals.add(currentInterval); - } - - /* Add the interval at t2, if it wasn't included already. */ - if (currentInterval != null && currentInterval.getEndTime() < tEnd) { - currentInterval = querySingleState(tEnd, attributeQuark); - intervals.add(currentInterval); - } - return intervals; - } - //-------------------------------------------------------------------------- // Debug methods //-------------------------------------------------------------------------- diff --git a/org.eclipse.tracecompass.statesystem.core/src/org/eclipse/tracecompass/statesystem/core/ITmfStateSystem.java b/org.eclipse.tracecompass.statesystem.core/src/org/eclipse/tracecompass/statesystem/core/ITmfStateSystem.java index 31321087e4..78a4ebc8b9 100644 --- a/org.eclipse.tracecompass.statesystem.core/src/org/eclipse/tracecompass/statesystem/core/ITmfStateSystem.java +++ b/org.eclipse.tracecompass.statesystem.core/src/org/eclipse/tracecompass/statesystem/core/ITmfStateSystem.java @@ -14,20 +14,21 @@ package org.eclipse.tracecompass.statesystem.core; import java.util.List; -import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.tracecompass.statesystem.core.exceptions.AttributeNotFoundException; import org.eclipse.tracecompass.statesystem.core.exceptions.StateSystemDisposedException; -import org.eclipse.tracecompass.statesystem.core.exceptions.StateValueTypeException; import org.eclipse.tracecompass.statesystem.core.exceptions.TimeRangeException; import org.eclipse.tracecompass.statesystem.core.interval.ITmfStateInterval; import org.eclipse.tracecompass.statesystem.core.statevalue.ITmfStateValue; + /** * This is the read-only interface to the generic state system. It contains all * the read-only quark-getting methods, as well as the history-querying ones. * * @author Alexandre Montplaisir * @since 3.0 + * @noimplement Only the internal StateSystem class should implement this + * interface. */ public interface ITmfStateSystem { @@ -332,94 +333,4 @@ public interface ITmfStateSystem { */ ITmfStateInterval querySingleState(long t, int attributeQuark) throws AttributeNotFoundException, StateSystemDisposedException; - - /** - * Convenience method to query attribute stacks (created with - * pushAttribute()/popAttribute()). This will return the interval that is - * currently at the top of the stack, or 'null' if that stack is currently - * empty. It works similarly to querySingleState(). - * - * To retrieve the other values in a stack, you can query the sub-attributes - * manually. - * - * @param t - * The timestamp of the query - * @param stackAttributeQuark - * The top-level stack-attribute (that was the target of - * pushAttribute() at creation time) - * @return The interval that was at the top of the stack, or 'null' if the - * stack was empty. - * @throws StateValueTypeException - * If the target attribute is not a valid stack attribute (if it - * has a string value for example) - * @throws AttributeNotFoundException - * If the attribute was simply not found - * @throws TimeRangeException - * If the given timestamp is invalid - * @throws StateSystemDisposedException - * If the query is sent after the state system has been disposed - */ - ITmfStateInterval querySingleStackTop(long t, int stackAttributeQuark) - throws AttributeNotFoundException, StateSystemDisposedException; - - /** - * Return a list of state intervals, containing the "history" of a given - * attribute between timestamps t1 and t2. The list will be ordered by - * ascending time. - * - * Note that contrary to queryFullState(), the returned list here is in the - * "direction" of time (and not in the direction of attributes, as is the - * case with queryFullState()). - * - * @param attributeQuark - * Which attribute this query is interested in - * @param t1 - * Start time of the range query - * @param t2 - * Target end time of the query. If t2 is greater than the end of - * the trace, we will return what we have up to the end of the - * history. - * @return The List of state intervals that happened between t1 and t2 - * @throws TimeRangeException - * If t1 is invalid, or if t2 <= t1 - * @throws AttributeNotFoundException - * If the requested quark does not exist in the model. - * @throws StateSystemDisposedException - * If the query is sent after the state system has been disposed - */ - List queryHistoryRange(int attributeQuark, long t1, long t2) - throws AttributeNotFoundException, StateSystemDisposedException; - - /** - * Return the state history of a given attribute, but with at most one - * update per "resolution". This can be useful for populating views (where - * it's useless to have more than one query per pixel, for example). A - * progress monitor can be used to cancel the query before completion. - * - * @param attributeQuark - * Which attribute this query is interested in - * @param t1 - * Start time of the range query - * @param t2 - * Target end time of the query. If t2 is greater than the end of - * the trace, we will return what we have up to the end of the - * history. - * @param resolution - * The "step" of this query - * @param monitor - * A progress monitor. If the monitor is canceled during a query, - * we will return what has been found up to that point. You can - * use "null" if you do not want to use one. - * @return The List of states that happened between t1 and t2 - * @throws TimeRangeException - * If t1 is invalid, if t2 <= t1, or if the resolution isn't - * greater than zero. - * @throws AttributeNotFoundException - * If the attribute doesn't exist - * @throws StateSystemDisposedException - * If the query is sent after the state system has been disposed - */ - List queryHistoryRange(int attributeQuark, - long t1, long t2, long resolution, IProgressMonitor monitor) - throws AttributeNotFoundException, StateSystemDisposedException; -} +} \ No newline at end of file diff --git a/org.eclipse.tracecompass.statesystem.core/src/org/eclipse/tracecompass/statesystem/core/ITmfStateSystemBuilder.java b/org.eclipse.tracecompass.statesystem.core/src/org/eclipse/tracecompass/statesystem/core/ITmfStateSystemBuilder.java index 936ef27c67..6ac1819bae 100644 --- a/org.eclipse.tracecompass.statesystem.core/src/org/eclipse/tracecompass/statesystem/core/ITmfStateSystemBuilder.java +++ b/org.eclipse.tracecompass.statesystem.core/src/org/eclipse/tracecompass/statesystem/core/ITmfStateSystemBuilder.java @@ -30,6 +30,8 @@ import org.eclipse.tracecompass.statesystem.core.statevalue.ITmfStateValue; * * @author Alexandre Montplaisir * @since 3.0 + * @noimplement Only the internal StateSystem class should implement this + * interface. */ public interface ITmfStateSystemBuilder extends ITmfStateSystem { diff --git a/org.eclipse.tracecompass.statesystem.core/src/org/eclipse/tracecompass/statesystem/core/StateSystemUtils.java b/org.eclipse.tracecompass.statesystem.core/src/org/eclipse/tracecompass/statesystem/core/StateSystemUtils.java new file mode 100644 index 0000000000..693a309e3e --- /dev/null +++ b/org.eclipse.tracecompass.statesystem.core/src/org/eclipse/tracecompass/statesystem/core/StateSystemUtils.java @@ -0,0 +1,281 @@ +/******************************************************************************* + * Copyright (c) 2014 École Polytechnique de Montréal + * + * All rights reserved. This program and the accompanying materials are + * made available under the terms of the Eclipse Public License v1.0 which + * accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Geneviève Bastien - Initial API and implementation + * Alexandre Montplaisir - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.statesystem.core; + +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.NullProgressMonitor; +import org.eclipse.jdt.annotation.NonNullByDefault; +import org.eclipse.jdt.annotation.Nullable; +import org.eclipse.tracecompass.statesystem.core.exceptions.AttributeNotFoundException; +import org.eclipse.tracecompass.statesystem.core.exceptions.StateSystemDisposedException; +import org.eclipse.tracecompass.statesystem.core.exceptions.StateValueTypeException; +import org.eclipse.tracecompass.statesystem.core.exceptions.TimeRangeException; +import org.eclipse.tracecompass.statesystem.core.interval.ITmfStateInterval; +import org.eclipse.tracecompass.statesystem.core.statevalue.ITmfStateValue; + +/** + * Provide utility methods for the state system + * + * @author Geneviève Bastien + */ +@NonNullByDefault +public final class StateSystemUtils { + + private StateSystemUtils() { + } + + /** + * Convenience method to query attribute stacks (created with + * pushAttribute()/popAttribute()). This will return the interval that is + * currently at the top of the stack, or 'null' if that stack is currently + * empty. It works similarly to querySingleState(). + * + * To retrieve the other values in a stack, you can query the sub-attributes + * manually. + * + * @param ss + * The state system to query + * @param t + * The timestamp of the query + * @param stackAttributeQuark + * The top-level stack-attribute (that was the target of + * pushAttribute() at creation time) + * @return The interval that was at the top of the stack, or 'null' if the + * stack was empty. + * @throws StateValueTypeException + * If the target attribute is not a valid stack attribute (if it + * has a string value for example) + * @throws AttributeNotFoundException + * If the attribute was simply not found + * @throws TimeRangeException + * If the given timestamp is invalid + * @throws StateSystemDisposedException + * If the query is sent after the state system has been disposed + */ + public static @Nullable ITmfStateInterval querySingleStackTop(ITmfStateSystem ss, + long t, int stackAttributeQuark) + throws AttributeNotFoundException, StateSystemDisposedException { + ITmfStateValue curStackStateValue = ss.querySingleState(t, stackAttributeQuark).getStateValue(); + + if (curStackStateValue.isNull()) { + /* There is nothing stored in this stack at this moment */ + return null; + } + int curStackDepth = curStackStateValue.unboxInt(); + if (curStackDepth <= 0) { + /* + * This attribute is an integer attribute, but it doesn't seem like + * it's used as a stack-attribute... + */ + throw new StateValueTypeException(); + } + + int subAttribQuark = ss.getQuarkRelative(stackAttributeQuark, String.valueOf(curStackDepth)); + return ss.querySingleState(t, subAttribQuark); + } + + /** + * Return a list of state intervals, containing the "history" of a given + * attribute between timestamps t1 and t2. The list will be ordered by + * ascending time. + * + * Note that contrary to queryFullState(), the returned list here is in the + * "direction" of time (and not in the direction of attributes, as is the + * case with queryFullState()). + * + * @param ss + * The state system to query + * @param attributeQuark + * Which attribute this query is interested in + * @param t1 + * Start time of the range query + * @param t2 + * Target end time of the query. If t2 is greater than the end of + * the trace, we will return what we have up to the end of the + * history. + * @return The List of state intervals that happened between t1 and t2 + * @throws TimeRangeException + * If t1 is invalid, or if t2 <= t1 + * @throws AttributeNotFoundException + * If the requested quark does not exist in the model. + * @throws StateSystemDisposedException + * If the query is sent after the state system has been disposed + */ + public static List queryHistoryRange(ITmfStateSystem ss, + int attributeQuark, long t1, long t2) + throws AttributeNotFoundException, StateSystemDisposedException { + + List intervals; + ITmfStateInterval currentInterval; + long ts, tEnd; + + /* Make sure the time range makes sense */ + if (t2 < t1) { + throw new TimeRangeException(); + } + + /* Set the actual, valid end time of the range query */ + if (t2 > ss.getCurrentEndTime()) { + tEnd = ss.getCurrentEndTime(); + } else { + tEnd = t2; + } + + /* Get the initial state at time T1 */ + intervals = new ArrayList<>(); + currentInterval = ss.querySingleState(t1, attributeQuark); + intervals.add(currentInterval); + + /* Get the following state changes */ + ts = currentInterval.getEndTime(); + while (ts != -1 && ts < tEnd) { + ts++; /* To "jump over" to the next state in the history */ + currentInterval = ss.querySingleState(ts, attributeQuark); + intervals.add(currentInterval); + ts = currentInterval.getEndTime(); + } + return intervals; + } + + /** + * Return the state history of a given attribute, but with at most one + * update per "resolution". This can be useful for populating views (where + * it's useless to have more than one query per pixel, for example). A + * progress monitor can be used to cancel the query before completion. + * + * @param ss + * The state system to query + * @param attributeQuark + * Which attribute this query is interested in + * @param t1 + * Start time of the range query + * @param t2 + * Target end time of the query. If t2 is greater than the end of + * the trace, we will return what we have up to the end of the + * history. + * @param resolution + * The "step" of this query + * @param monitor + * A progress monitor. If the monitor is canceled during a query, + * we will return what has been found up to that point. You can + * use "null" if you do not want to use one. + * @return The List of states that happened between t1 and t2 + * @throws TimeRangeException + * If t1 is invalid, if t2 <= t1, or if the resolution isn't + * greater than zero. + * @throws AttributeNotFoundException + * If the attribute doesn't exist + * @throws StateSystemDisposedException + * If the query is sent after the state system has been disposed + */ + public static List queryHistoryRange(ITmfStateSystem ss, + int attributeQuark, long t1, long t2, long resolution, + @Nullable IProgressMonitor monitor) + throws AttributeNotFoundException, StateSystemDisposedException { + List intervals = new LinkedList<>(); + ITmfStateInterval currentInterval = null; + long ts, tEnd; + + /* Make sure the time range makes sense */ + if (t2 < t1 || resolution <= 0) { + throw new TimeRangeException(); + } + + /* Set the actual, valid end time of the range query */ + if (t2 > ss.getCurrentEndTime()) { + tEnd = ss.getCurrentEndTime(); + } else { + tEnd = t2; + } + + IProgressMonitor mon = monitor; + if (mon == null) { + mon = new NullProgressMonitor(); + } + + /* + * Iterate over the "resolution points". We skip unneeded queries in the + * case the current interval is longer than the resolution. + */ + for (ts = t1; ts <= tEnd; ts += ((currentInterval.getEndTime() - ts) / resolution + 1) * resolution) { + if (mon.isCanceled()) { + return intervals; + } + currentInterval = ss.querySingleState(ts, attributeQuark); + intervals.add(currentInterval); + } + + /* Add the interval at t2, if it wasn't included already. */ + if (currentInterval != null && currentInterval.getEndTime() < tEnd) { + currentInterval = ss.querySingleState(tEnd, attributeQuark); + intervals.add(currentInterval); + } + return intervals; + } + + /** + * Queries intervals in the state system for a given attribute, starting at + * time t1, until we obtain a non-null value. + * + * @param ss + * The state system on which to query intervals + * @param attributeQuark + * The attribute quark to query + * @param t1 + * Start time of the query + * @param t2 + * Time limit of the query. Use {@link Long#MAX_VALUE} for no + * limit. + * @return The first interval from t1 for which the value is not a null + * value, or null if no interval was found once we + * reach either t2 or the end time of the state system. + */ + public static @Nullable ITmfStateInterval queryUntilNonNullValue(ITmfStateSystem ss, + int attributeQuark, long t1, long t2) { + + long current = t1; + /* Make sure the range is ok */ + if (t1 < ss.getStartTime()) { + current = ss.getStartTime(); + } + long end = t2; + if (end < ss.getCurrentEndTime()) { + end = ss.getCurrentEndTime(); + } + /* Make sure the time range makes sense */ + if (end < current) { + return null; + } + + try { + while (current < t2) { + ITmfStateInterval currentInterval = ss.querySingleState(current, attributeQuark); + ITmfStateValue value = currentInterval.getStateValue(); + + if (!value.isNull()) { + return currentInterval; + } + current = currentInterval.getEndTime() + 1; + } + } catch (AttributeNotFoundException | StateSystemDisposedException | TimeRangeException e) { + /* Nothing to do */ + } + return null; + } + +} diff --git a/org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/tracecompass/tmf/analysis/xml/ui/views/timegraph/XmlEntry.java b/org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/tracecompass/tmf/analysis/xml/ui/views/timegraph/XmlEntry.java index 51439b9895..96ad597752 100644 --- a/org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/tracecompass/tmf/analysis/xml/ui/views/timegraph/XmlEntry.java +++ b/org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/tracecompass/tmf/analysis/xml/ui/views/timegraph/XmlEntry.java @@ -19,6 +19,7 @@ import java.util.List; import org.eclipse.jdt.annotation.NonNull; import org.eclipse.tracecompass.internal.tmf.analysis.xml.ui.TmfXmlUiStrings; import org.eclipse.tracecompass.statesystem.core.ITmfStateSystem; +import org.eclipse.tracecompass.statesystem.core.StateSystemUtils; import org.eclipse.tracecompass.statesystem.core.exceptions.AttributeNotFoundException; import org.eclipse.tracecompass.statesystem.core.exceptions.StateSystemDisposedException; import org.eclipse.tracecompass.statesystem.core.interval.ITmfStateInterval; @@ -157,7 +158,7 @@ public class XmlEntry extends TimeGraphEntry implements IXmlStateSystemContainer if (quark != IXmlStateSystemContainer.ERROR_QUARK) { try { /* Find the first attribute with a parent */ - List execNameIntervals = fSs.queryHistoryRange(quark, getStartTime(), getEndTime()); + List execNameIntervals = StateSystemUtils.queryHistoryRange(fSs, quark, getStartTime(), getEndTime()); for (ITmfStateInterval execNameInterval : execNameIntervals) { if (!execNameInterval.getStateValue().isNull()) { diff --git a/org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/tracecompass/tmf/analysis/xml/ui/views/timegraph/XmlTimeGraphView.java b/org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/tracecompass/tmf/analysis/xml/ui/views/timegraph/XmlTimeGraphView.java index 89cee8c865..0a7938ff3c 100644 --- a/org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/tracecompass/tmf/analysis/xml/ui/views/timegraph/XmlTimeGraphView.java +++ b/org.eclipse.tracecompass.tmf.analysis.xml.ui/src/org/eclipse/tracecompass/tmf/analysis/xml/ui/views/timegraph/XmlTimeGraphView.java @@ -33,6 +33,7 @@ import org.eclipse.tracecompass.internal.tmf.analysis.xml.ui.Activator; import org.eclipse.tracecompass.internal.tmf.analysis.xml.ui.TmfXmlUiStrings; import org.eclipse.tracecompass.internal.tmf.analysis.xml.ui.views.XmlViewInfo; import org.eclipse.tracecompass.statesystem.core.ITmfStateSystem; +import org.eclipse.tracecompass.statesystem.core.StateSystemUtils; import org.eclipse.tracecompass.statesystem.core.exceptions.AttributeNotFoundException; import org.eclipse.tracecompass.statesystem.core.exceptions.StateSystemDisposedException; import org.eclipse.tracecompass.statesystem.core.exceptions.StateValueTypeException; @@ -479,7 +480,7 @@ public class XmlTimeGraphView extends AbstractTimeGraphView { try { if (xmlEntry.getType() == EntryDisplayType.DISPLAY) { - List statusIntervals = ssq.queryHistoryRange(quark, realStart, realEnd - 1, resolution, monitor); + List statusIntervals = StateSystemUtils.queryHistoryRange(ssq, quark, realStart, realEnd - 1, resolution, monitor); eventList = new ArrayList<>(statusIntervals.size()); long lastEndTime = -1; for (ITmfStateInterval statusInterval : statusIntervals) { diff --git a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/statesystem/mipmap/TmfStateSystemOperations.java b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/statesystem/mipmap/TmfStateSystemOperations.java index aaf2e67fda..f7d355d778 100644 --- a/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/statesystem/mipmap/TmfStateSystemOperations.java +++ b/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/internal/tmf/core/statesystem/mipmap/TmfStateSystemOperations.java @@ -17,14 +17,16 @@ import java.util.ArrayList; import java.util.List; import org.eclipse.tracecompass.statesystem.core.ITmfStateSystem; +import org.eclipse.tracecompass.statesystem.core.StateSystemUtils; import org.eclipse.tracecompass.statesystem.core.exceptions.AttributeNotFoundException; import org.eclipse.tracecompass.statesystem.core.exceptions.StateSystemDisposedException; import org.eclipse.tracecompass.statesystem.core.exceptions.StateValueTypeException; import org.eclipse.tracecompass.statesystem.core.exceptions.TimeRangeException; import org.eclipse.tracecompass.statesystem.core.interval.ITmfStateInterval; import org.eclipse.tracecompass.statesystem.core.statevalue.ITmfStateValue; -import org.eclipse.tracecompass.statesystem.core.statevalue.TmfStateValue; import org.eclipse.tracecompass.statesystem.core.statevalue.ITmfStateValue.Type; +import org.eclipse.tracecompass.statesystem.core.statevalue.TmfStateValue; + /** * This class implements additional statistical operations that can be @@ -212,7 +214,7 @@ public final class TmfStateSystemOperations { intervals.add(interval); } } else { - for (ITmfStateInterval interval : ss.queryHistoryRange(baseQuark, t1, t2)) { + for (ITmfStateInterval interval : StateSystemUtils.queryHistoryRange(ss, baseQuark, t1, t2)) { if (!interval.getStateValue().isNull()) { intervals.add(interval); } diff --git a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/callstack/CallStackView.java b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/callstack/CallStackView.java index bc18feb6fe..be8b681fce 100644 --- a/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/callstack/CallStackView.java +++ b/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/callstack/CallStackView.java @@ -63,6 +63,7 @@ import org.eclipse.tracecompass.internal.tmf.ui.Activator; import org.eclipse.tracecompass.internal.tmf.ui.ITmfImageConstants; import org.eclipse.tracecompass.internal.tmf.ui.Messages; import org.eclipse.tracecompass.statesystem.core.ITmfStateSystem; +import org.eclipse.tracecompass.statesystem.core.StateSystemUtils; import org.eclipse.tracecompass.statesystem.core.exceptions.AttributeNotFoundException; import org.eclipse.tracecompass.statesystem.core.exceptions.StateSystemDisposedException; import org.eclipse.tracecompass.statesystem.core.exceptions.StateValueTypeException; @@ -995,7 +996,7 @@ public class CallStackView extends TmfView { } List eventList = null; try { - List stackIntervals = ss.queryHistoryRange(entry.getQuark(), start, end - 1, resolution, monitor); + List stackIntervals = StateSystemUtils.queryHistoryRange(ss, entry.getQuark(), start, end - 1, resolution, monitor); eventList = new ArrayList<>(stackIntervals.size()); long lastEndTime = -1; boolean lastIsNull = true; -- 2.34.1