From 6e71ce46928931c8860c1431690d6463e9cb7f49 Mon Sep 17 00:00:00 2001 From: Alexandre Montplaisir Date: Fri, 1 Jun 2012 10:17:54 -0400 Subject: [PATCH] tmf: Introduce the StateSystemManager The HistoryBuilder class goes back to being a dumb "state history factory", while the Manager will handle the set up and locking of those constructions. refs Eclipse bug #381393 Signed-off-by: Alexandre Montplaisir --- .../StateSystemFullHistoryTest.java | 122 ++++++++---------- .../StateSystemFullThreadedHistoryTest.java | 74 ----------- .../core/tests/stateprovider/TestAll.java | 3 +- .../kernel/core/trace/CtfKernelTrace.java | 51 +------- .../tmf/core/statesystem/HistoryBuilder.java | 83 ++---------- .../core/statesystem/StateSystemManager.java | 98 ++++++++++++++ 6 files changed, 170 insertions(+), 261 deletions(-) delete mode 100644 org.eclipse.linuxtools.lttng2.kernel.core.tests/src/org/eclipse/linuxtools/lttng2/kernel/core/tests/stateprovider/StateSystemFullThreadedHistoryTest.java create mode 100644 org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/statesystem/StateSystemManager.java diff --git a/org.eclipse.linuxtools.lttng2.kernel.core.tests/src/org/eclipse/linuxtools/lttng2/kernel/core/tests/stateprovider/StateSystemFullHistoryTest.java b/org.eclipse.linuxtools.lttng2.kernel.core.tests/src/org/eclipse/linuxtools/lttng2/kernel/core/tests/stateprovider/StateSystemFullHistoryTest.java index 55d60b8247..167610c084 100644 --- a/org.eclipse.linuxtools.lttng2.kernel.core.tests/src/org/eclipse/linuxtools/lttng2/kernel/core/tests/stateprovider/StateSystemFullHistoryTest.java +++ b/org.eclipse.linuxtools.lttng2.kernel.core.tests/src/org/eclipse/linuxtools/lttng2/kernel/core/tests/stateprovider/StateSystemFullHistoryTest.java @@ -12,25 +12,27 @@ package org.eclipse.linuxtools.lttng2.kernel.core.tests.stateprovider; -import static org.junit.Assert.*; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; import java.io.File; import java.io.IOException; import java.util.List; +import org.eclipse.linuxtools.internal.lttng2.kernel.core.Attributes; +import org.eclipse.linuxtools.internal.lttng2.kernel.core.stateprovider.CtfKernelStateInput; import org.eclipse.linuxtools.tmf.core.exceptions.AttributeNotFoundException; import org.eclipse.linuxtools.tmf.core.exceptions.StateValueTypeException; import org.eclipse.linuxtools.tmf.core.exceptions.TimeRangeException; import org.eclipse.linuxtools.tmf.core.exceptions.TmfTraceException; import org.eclipse.linuxtools.tmf.core.interval.ITmfStateInterval; -import org.eclipse.linuxtools.tmf.core.statesystem.HistoryBuilder; import org.eclipse.linuxtools.tmf.core.statesystem.IStateChangeInput; -import org.eclipse.linuxtools.tmf.core.statesystem.IStateHistoryBackend; -import org.eclipse.linuxtools.tmf.core.statesystem.IStateSystemBuilder; -import org.eclipse.linuxtools.tmf.core.statesystem.backend.historytree.HistoryTreeBackend; -import org.eclipse.linuxtools.internal.lttng2.kernel.core.Attributes; -import org.eclipse.linuxtools.internal.lttng2.kernel.core.stateprovider.CtfKernelStateInput; -import org.junit.*; +import org.eclipse.linuxtools.tmf.core.statesystem.IStateSystemQuerier; +import org.eclipse.linuxtools.tmf.core.statesystem.StateSystemManager; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; /** * Unit tests for the StateHistorySystem, which uses a full (non-partial) @@ -45,10 +47,8 @@ public class StateSystemFullHistoryTest { static File stateFile; static File stateFileBenchmark; - static HistoryBuilder builder; static IStateChangeInput input; - static IStateHistoryBackend hp; - static IStateSystemBuilder ssb; + static IStateSystemQuerier ssq; /* Offset in the trace + start time of the trace */ private final static long interestingTimestamp1 = 18670067372290L + 1331649577946812237L; @@ -63,13 +63,10 @@ public class StateSystemFullHistoryTest { stateFileBenchmark = new File(getTestFileName() + ".benchmark"); //$NON-NLS-1$ try { input = new CtfKernelStateInput(CtfTestFiles.getTestTrace()); - hp = new HistoryTreeBackend(stateFile, input.getStartTime()); - builder = new HistoryBuilder(input, hp); + ssq = StateSystemManager.loadStateHistory(stateFile, input); } catch (Exception e) { e.printStackTrace(); } - builder.startBuilding(null); - ssb = builder.getStateSystemBuilder(); } @AfterClass @@ -92,31 +89,26 @@ public class StateSystemFullHistoryTest { */ @Test public void testBuild() throws IOException, TmfTraceException { - HistoryBuilder zebuilder; - IStateChangeInput zeinput; - IStateHistoryBackend zehp = null; - - zeinput = new CtfKernelStateInput(CtfTestFiles.getTestTrace()); - zehp = new HistoryTreeBackend(stateFileBenchmark, zeinput.getStartTime()); - zebuilder = new HistoryBuilder(zeinput, zehp); - zebuilder.startBuilding(null); + IStateChangeInput input2; + IStateSystemQuerier ssb2; + + input2 = new CtfKernelStateInput(CtfTestFiles.getTestTrace()); + ssb2 = StateSystemManager.loadStateHistory(stateFileBenchmark, input2); - assertEquals(CtfTestFiles.startTime, zehp.getStartTime()); - assertEquals(CtfTestFiles.endTime, zehp.getEndTime()); + assertEquals(CtfTestFiles.startTime, ssb2.getStartTime()); + assertEquals(CtfTestFiles.endTime, ssb2.getCurrentEndTime()); } @Test - public void testOpenExistingStateFile() throws IOException { - IStateHistoryBackend hp2 = null; - IStateSystemBuilder ssb2 = null; + public void testOpenExistingStateFile() throws IOException, TmfTraceException { + IStateSystemQuerier ssb2; /* 'newStateFile' should have already been created */ - hp2 = new HistoryTreeBackend(stateFile); - ssb2 = HistoryBuilder.openExistingHistory(hp2); + ssb2 = StateSystemManager.loadStateHistory(stateFile, null); assertNotNull(ssb2); - assertEquals(CtfTestFiles.startTime, hp2.getStartTime()); - assertEquals(CtfTestFiles.endTime, hp2.getEndTime()); + assertEquals(CtfTestFiles.startTime, ssb2.getStartTime()); + assertEquals(CtfTestFiles.endTime, ssb2.getCurrentEndTime()); } @Test @@ -128,19 +120,19 @@ public class StateSystemFullHistoryTest { int quark, valueInt; String valueStr; - list = ssb.queryFullState(interestingTimestamp1); + list = ssq.queryFullState(interestingTimestamp1); - quark = ssb.getQuarkAbsolute(Attributes.CPUS, "0", Attributes.CURRENT_THREAD); + quark = ssq.getQuarkAbsolute(Attributes.CPUS, "0", Attributes.CURRENT_THREAD); interval = list.get(quark); valueInt = interval.getStateValue().unboxInt(); assertEquals(1397, valueInt); - quark = ssb.getQuarkAbsolute(Attributes.THREADS, "1432", Attributes.EXEC_NAME); + quark = ssq.getQuarkAbsolute(Attributes.THREADS, "1432", Attributes.EXEC_NAME); interval = list.get(quark); valueStr = interval.getStateValue().unboxStr(); assertEquals("gdbus", valueStr); - quark = ssb.getQuarkAbsolute(Attributes.THREADS, "1432", Attributes.SYSTEM_CALL); + quark = ssq.getQuarkAbsolute(Attributes.THREADS, "1432", Attributes.SYSTEM_CALL); interval = list.get(quark); valueStr = interval.getStateValue().unboxStr(); assertTrue(valueStr.equals("sys_poll")); @@ -165,8 +157,8 @@ public class StateSystemFullHistoryTest { ITmfStateInterval interval; String valueStr; - quark = ssb.getQuarkAbsolute(Attributes.THREADS, "1432", Attributes.EXEC_NAME); - interval = ssb.querySingleState(timestamp, quark); + quark = ssq.getQuarkAbsolute(Attributes.THREADS, "1432", Attributes.EXEC_NAME); + interval = ssq.querySingleState(timestamp, quark); valueStr = interval.getStateValue().unboxStr(); assertEquals("gdbus", valueStr); } @@ -193,8 +185,8 @@ public class StateSystemFullHistoryTest { int quark; List intervals; - quark = ssb.getQuarkAbsolute(Attributes.CPUS, "0", Attributes.CURRENT_THREAD); - intervals = ssb.queryHistoryRange(quark, time1, time2); + quark = ssq.getQuarkAbsolute(Attributes.CPUS, "0", Attributes.CURRENT_THREAD); + intervals = ssq.queryHistoryRange(quark, time1, time2); assertEquals(487, intervals.size()); /* Number of context switches! */ assertEquals(1685, intervals.get(100).getStateValue().unboxInt()); assertEquals(1331668248427681372L, intervals.get(205).getEndTime()); @@ -210,11 +202,11 @@ public class StateSystemFullHistoryTest { List intervals; - int quark = ssb.getQuarkAbsolute(Attributes.RESOURCES, Attributes.IRQS, "1"); - long ts1 = ssb.getStartTime(); /* start of the trace */ + int quark = ssq.getQuarkAbsolute(Attributes.RESOURCES, Attributes.IRQS, "1"); + long ts1 = ssq.getStartTime(); /* start of the trace */ long ts2 = CtfTestFiles.startTime + 20L * CtfTestFiles.NANOSECS_PER_SEC; /* invalid, but ignored */ - intervals = ssb.queryHistoryRange(quark, ts1, ts2); + intervals = ssq.queryHistoryRange(quark, ts1, ts2); /* Activity of IRQ 1 over the whole trace */ assertEquals(65, intervals.size()); @@ -233,8 +225,8 @@ public class StateSystemFullHistoryTest { int quark; List intervals; - quark = ssb.getQuarkAbsolute(Attributes.CPUS, "0", Attributes.CURRENT_THREAD); - intervals = ssb.queryHistoryRange(quark, time1, time2, resolution); + quark = ssq.getQuarkAbsolute(Attributes.CPUS, "0", Attributes.CURRENT_THREAD); + intervals = ssq.queryHistoryRange(quark, time1, time2, resolution); assertEquals(126, intervals.size()); /* Number of context switches! */ assertEquals(1452, intervals.get(50).getStateValue().unboxInt()); assertEquals(1331668248815698779L, intervals.get(100).getEndTime()); @@ -248,14 +240,14 @@ public class StateSystemFullHistoryTest { @Test(expected = TimeRangeException.class) public void testFullQueryInvalidTime1() throws TimeRangeException { long ts = CtfTestFiles.startTime + 20L * CtfTestFiles.NANOSECS_PER_SEC; - ssb.queryFullState(ts); + ssq.queryFullState(ts); } @Test(expected = TimeRangeException.class) public void testFullQueryInvalidTime2() throws TimeRangeException { long ts = CtfTestFiles.startTime - 20L * CtfTestFiles.NANOSECS_PER_SEC; - ssb.queryFullState(ts); + ssq.queryFullState(ts); } @@ -263,40 +255,40 @@ public class StateSystemFullHistoryTest { public void testSingleQueryInvalidTime1() throws AttributeNotFoundException, TimeRangeException { - int quark = ssb.getQuarkAbsolute(Attributes.CPUS, "0", Attributes.CURRENT_THREAD); + int quark = ssq.getQuarkAbsolute(Attributes.CPUS, "0", Attributes.CURRENT_THREAD); long ts = CtfTestFiles.startTime + 20L * CtfTestFiles.NANOSECS_PER_SEC; - ssb.querySingleState(ts, quark); + ssq.querySingleState(ts, quark); } @Test(expected = TimeRangeException.class) public void testSingleQueryInvalidTime2() throws AttributeNotFoundException, TimeRangeException { - int quark = ssb.getQuarkAbsolute(Attributes.CPUS, "0", Attributes.CURRENT_THREAD); + int quark = ssq.getQuarkAbsolute(Attributes.CPUS, "0", Attributes.CURRENT_THREAD); long ts = CtfTestFiles.startTime - 20L * CtfTestFiles.NANOSECS_PER_SEC; - ssb.querySingleState(ts, quark); + ssq.querySingleState(ts, quark); } @Test(expected = TimeRangeException.class) public void testRangeQueryInvalidTime1() throws AttributeNotFoundException, TimeRangeException { - int quark = ssb.getQuarkAbsolute(Attributes.CPUS, "0", Attributes.CURRENT_THREAD); + int quark = ssq.getQuarkAbsolute(Attributes.CPUS, "0", Attributes.CURRENT_THREAD); long ts1 = CtfTestFiles.startTime - 20L * CtfTestFiles.NANOSECS_PER_SEC; /* invalid */ long ts2 = CtfTestFiles.startTime + 1L * CtfTestFiles.NANOSECS_PER_SEC; /* valid */ - ssb.queryHistoryRange(quark, ts1, ts2); + ssq.queryHistoryRange(quark, ts1, ts2); } @Test(expected = TimeRangeException.class) public void testRangeQueryInvalidTime2() throws TimeRangeException, AttributeNotFoundException { - int quark = ssb.getQuarkAbsolute(Attributes.CPUS, "0", Attributes.CURRENT_THREAD); + int quark = ssq.getQuarkAbsolute(Attributes.CPUS, "0", Attributes.CURRENT_THREAD); long ts1 = CtfTestFiles.startTime - 1L * CtfTestFiles.NANOSECS_PER_SEC; /* invalid */ long ts2 = CtfTestFiles.startTime + 20L * CtfTestFiles.NANOSECS_PER_SEC; /* invalid */ - ssb.queryHistoryRange(quark, ts1, ts2); + ssq.queryHistoryRange(quark, ts1, ts2); } /** @@ -307,7 +299,7 @@ public class StateSystemFullHistoryTest { @Test(expected = AttributeNotFoundException.class) public void testQueryInvalidAttribute() throws AttributeNotFoundException { - ssb.getQuarkAbsolute("There", "is", "no", "cow", "level"); + ssq.getQuarkAbsolute("There", "is", "no", "cow", "level"); } /** @@ -324,8 +316,8 @@ public class StateSystemFullHistoryTest { ITmfStateInterval interval; int quark; - list = ssb.queryFullState(interestingTimestamp1); - quark = ssb.getQuarkAbsolute(Attributes.CPUS, "0", Attributes.CURRENT_THREAD); + list = ssq.queryFullState(interestingTimestamp1); + quark = ssq.getQuarkAbsolute(Attributes.CPUS, "0", Attributes.CURRENT_THREAD); interval = list.get(quark); /* This is supposed to be an int value */ @@ -339,8 +331,8 @@ public class StateSystemFullHistoryTest { ITmfStateInterval interval; int quark; - list = ssb.queryFullState(interestingTimestamp1); - quark = ssb.getQuarkAbsolute(Attributes.THREADS, "1432", Attributes.EXEC_NAME); + list = ssq.queryFullState(interestingTimestamp1); + quark = ssq.getQuarkAbsolute(Attributes.THREADS, "1432", Attributes.EXEC_NAME); interval = list.get(quark); /* This is supposed to be a String value */ @@ -349,21 +341,21 @@ public class StateSystemFullHistoryTest { @Test public void testFullAttributeName() throws AttributeNotFoundException { - int quark = ssb.getQuarkAbsolute(Attributes.CPUS, "0", Attributes.CURRENT_THREAD); - String name = ssb.getFullAttributePath(quark); + int quark = ssq.getQuarkAbsolute(Attributes.CPUS, "0", Attributes.CURRENT_THREAD); + String name = ssq.getFullAttributePath(quark); assertEquals(name, "CPUs/0/Current_thread"); } @Test public void testGetQuarks_begin() { - List list = ssb.getQuarks("*", "1577", Attributes.EXEC_NAME); + List list = ssq.getQuarks("*", "1577", Attributes.EXEC_NAME); assertEquals(1, list.size()); } @Test public void testGetQuarks_middle() { - List list = ssb.getQuarks(Attributes.THREADS, "*", Attributes.EXEC_NAME); + List list = ssq.getQuarks(Attributes.THREADS, "*", Attributes.EXEC_NAME); /* Number of different kernel threads in the trace */ assertEquals(168, list.size()); @@ -371,7 +363,7 @@ public class StateSystemFullHistoryTest { @Test public void testGetQuarks_end() { - List list = ssb.getQuarks(Attributes.THREADS, "1577", "*"); + List list = ssq.getQuarks(Attributes.THREADS, "1577", "*"); /* There should be 4 sub-attributes for each Thread node */ assertEquals(4, list.size()); diff --git a/org.eclipse.linuxtools.lttng2.kernel.core.tests/src/org/eclipse/linuxtools/lttng2/kernel/core/tests/stateprovider/StateSystemFullThreadedHistoryTest.java b/org.eclipse.linuxtools.lttng2.kernel.core.tests/src/org/eclipse/linuxtools/lttng2/kernel/core/tests/stateprovider/StateSystemFullThreadedHistoryTest.java deleted file mode 100644 index 9a79d37098..0000000000 --- a/org.eclipse.linuxtools.lttng2.kernel.core.tests/src/org/eclipse/linuxtools/lttng2/kernel/core/tests/stateprovider/StateSystemFullThreadedHistoryTest.java +++ /dev/null @@ -1,74 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2012 Ericsson - * Copyright (c) 2010, 2011 École Polytechnique de Montréal - * Copyright (c) 2010, 2011 Alexandre Montplaisir - * - * 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 - * - *******************************************************************************/ - -package org.eclipse.linuxtools.lttng2.kernel.core.tests.stateprovider; - -import java.io.File; - -import org.eclipse.linuxtools.internal.lttng2.kernel.core.stateprovider.CtfKernelStateInput; -import org.eclipse.linuxtools.tmf.core.statesystem.HistoryBuilder; -import org.eclipse.linuxtools.tmf.core.statesystem.IStateChangeInput; -import org.eclipse.linuxtools.tmf.core.statesystem.IStateHistoryBackend; -import org.eclipse.linuxtools.tmf.core.statesystem.backend.historytree.ThreadedHistoryTreeBackend; - -import org.junit.BeforeClass; -import org.junit.Test; - -/** - * Variant of the StateSystemFullHistoryTest, which uses the threaded event - * handler instead. - * - * @author alexmont - * - */ -public class StateSystemFullThreadedHistoryTest extends - StateSystemFullHistoryTest { - - /* Hiding the static method in the superclass */ - protected static String getTestFileName() { - return "/tmp/statefile-threaded.ht"; //$NON-NLS-1$ - } - - @BeforeClass - public static void initialize() { - stateFile = new File(getTestFileName()); - stateFileBenchmark = new File(getTestFileName() + ".benchmark"); //$NON-NLS-1$ - try { - input = new CtfKernelStateInput(CtfTestFiles.getTestTrace()); - hp = new ThreadedHistoryTreeBackend(stateFile, - input.getStartTime(), 2000); - builder = new HistoryBuilder(input, hp); - } catch (Exception e) { - e.printStackTrace(); - } - builder.startBuilding(null); - ssb = builder.getStateSystemBuilder(); - } - - @Override - @Test - public void testBuild() { - HistoryBuilder zebuilder; - IStateChangeInput zeinput; - IStateHistoryBackend zehp; - - try { - zeinput = new CtfKernelStateInput(CtfTestFiles.getTestTrace()); - zehp = new ThreadedHistoryTreeBackend(stateFileBenchmark, - zeinput.getStartTime(), 2000); - zebuilder = new HistoryBuilder(zeinput, zehp); - zebuilder.startBuilding(null); - } catch (Exception e) { - e.printStackTrace(); - } - } -} diff --git a/org.eclipse.linuxtools.lttng2.kernel.core.tests/src/org/eclipse/linuxtools/lttng2/kernel/core/tests/stateprovider/TestAll.java b/org.eclipse.linuxtools.lttng2.kernel.core.tests/src/org/eclipse/linuxtools/lttng2/kernel/core/tests/stateprovider/TestAll.java index 15b53bbf3d..fa9d695484 100644 --- a/org.eclipse.linuxtools.lttng2.kernel.core.tests/src/org/eclipse/linuxtools/lttng2/kernel/core/tests/stateprovider/TestAll.java +++ b/org.eclipse.linuxtools.lttng2.kernel.core.tests/src/org/eclipse/linuxtools/lttng2/kernel/core/tests/stateprovider/TestAll.java @@ -26,8 +26,7 @@ import org.junit.runners.Suite; */ @RunWith(Suite.class) @Suite.SuiteClasses({ CtfKernelStateInputTest.class, - StateSystemFullHistoryTest.class, - StateSystemFullThreadedHistoryTest.class}) + StateSystemFullHistoryTest.class}) public class TestAll { /** diff --git a/org.eclipse.linuxtools.lttng2.kernel.core/src/org/eclipse/linuxtools/lttng2/kernel/core/trace/CtfKernelTrace.java b/org.eclipse.linuxtools.lttng2.kernel.core/src/org/eclipse/linuxtools/lttng2/kernel/core/trace/CtfKernelTrace.java index dc98c11b6f..db6fb6b6ce 100644 --- a/org.eclipse.linuxtools.lttng2.kernel.core/src/org/eclipse/linuxtools/lttng2/kernel/core/trace/CtfKernelTrace.java +++ b/org.eclipse.linuxtools.lttng2.kernel.core/src/org/eclipse/linuxtools/lttng2/kernel/core/trace/CtfKernelTrace.java @@ -13,7 +13,6 @@ package org.eclipse.linuxtools.lttng2.kernel.core.trace; import java.io.File; -import java.io.IOException; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; @@ -22,11 +21,8 @@ import org.eclipse.linuxtools.internal.lttng2.kernel.core.stateprovider.CtfKerne import org.eclipse.linuxtools.tmf.core.TmfCommonConstants; import org.eclipse.linuxtools.tmf.core.ctfadaptor.CtfTmfTrace; import org.eclipse.linuxtools.tmf.core.exceptions.TmfTraceException; -import org.eclipse.linuxtools.tmf.core.statesystem.HistoryBuilder; import org.eclipse.linuxtools.tmf.core.statesystem.IStateChangeInput; -import org.eclipse.linuxtools.tmf.core.statesystem.IStateHistoryBackend; -import org.eclipse.linuxtools.tmf.core.statesystem.backend.historytree.HistoryTreeBackend; -import org.eclipse.linuxtools.tmf.core.statesystem.backend.historytree.ThreadedHistoryTreeBackend; +import org.eclipse.linuxtools.tmf.core.statesystem.StateSystemManager; /** * This is the specification of CtfTmfTrace for use with LTTng 2.x kernel @@ -41,9 +37,6 @@ public class CtfKernelTrace extends CtfTmfTrace { * The file name of the History Tree */ public final static String HISTORY_TREE_FILE_NAME = "stateHistory.ht"; //$NON-NLS-1$ - - /** Size of the blocking queue to use when building a state history */ - private final static int QUEUE_SIZE = 10000; public CtfKernelTrace() { super(); @@ -61,7 +54,7 @@ public class CtfKernelTrace extends CtfTmfTrace { @Override protected void buildStateSystem() throws TmfTraceException { /* Set up the path to the history tree file we'll use */ - IResource resource = getResource(); + IResource resource = this.getResource(); String supplDirectory = null; try { @@ -72,44 +65,8 @@ public class CtfKernelTrace extends CtfTmfTrace { } final File htFile = new File(supplDirectory + File.separator + HISTORY_TREE_FILE_NAME); + final IStateChangeInput htInput = new CtfKernelStateInput(this); - IStateHistoryBackend htBackend; - IStateChangeInput htInput; - HistoryBuilder builder; - - /* If the target file already exists, do not rebuild it uselessly */ - // TODO for now we assume it's complete. Might be a good idea to check - // at least if its range matches the trace's range. - if (htFile.exists()) { - /* Load an existing history */ - try { - htBackend = new HistoryTreeBackend(htFile); - this.ss = HistoryBuilder.openExistingHistory(htBackend); - return; - } catch (IOException e) { - /* - * There was an error opening the existing file. Perhaps it was - * corrupted, perhaps it's an old version? We'll just - * fall-through and try to build a new one from scratch instead. - */ - } - } - - /* Create a new state history from scratch */ - htInput = new CtfKernelStateInput(this); - - try { - htBackend = new ThreadedHistoryTreeBackend(htFile, - htInput.getStartTime(), QUEUE_SIZE); - builder = new HistoryBuilder(htInput, htBackend); - } catch (IOException e) { - /* - * If it fails here however, it means there was a problem writing - * to the disk, so throw a real exception this time. - */ - throw new TmfTraceException(e.toString(), e); - } - - this.ss = builder.getStateSystemQuerier(); + this.ss = StateSystemManager.loadStateHistory(htFile, htInput); } } diff --git a/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/statesystem/HistoryBuilder.java b/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/statesystem/HistoryBuilder.java index 5018ff89eb..53e810c767 100644 --- a/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/statesystem/HistoryBuilder.java +++ b/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/statesystem/HistoryBuilder.java @@ -13,21 +13,13 @@ package org.eclipse.linuxtools.tmf.core.statesystem; import java.io.IOException; -import java.util.concurrent.Semaphore; import org.eclipse.linuxtools.internal.tmf.core.statesystem.StateHistorySystem; -import org.eclipse.linuxtools.tmf.core.component.TmfComponent; import org.eclipse.linuxtools.tmf.core.ctfadaptor.CtfTmfEvent; -import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; import org.eclipse.linuxtools.tmf.core.event.TmfTimeRange; import org.eclipse.linuxtools.tmf.core.request.ITmfDataRequest; -import org.eclipse.linuxtools.tmf.core.request.ITmfEventRequest; import org.eclipse.linuxtools.tmf.core.request.TmfDataRequest; import org.eclipse.linuxtools.tmf.core.request.TmfEventRequest; -import org.eclipse.linuxtools.tmf.core.signal.TmfExperimentRangeUpdatedSignal; -import org.eclipse.linuxtools.tmf.core.signal.TmfExperimentSelectedSignal; -import org.eclipse.linuxtools.tmf.core.signal.TmfSignalHandler; -import org.eclipse.linuxtools.tmf.core.signal.TmfSignalManager; /** * This is the high-level wrapper around the State History and its input and @@ -40,12 +32,7 @@ import org.eclipse.linuxtools.tmf.core.signal.TmfSignalManager; * @author alexmont * */ -public class HistoryBuilder extends TmfComponent { - - private static final Semaphore hbSem = new Semaphore(1); - - private ITmfEventRequest currentRequest = null; - private boolean isRunning = false; +public class HistoryBuilder implements Runnable { private final IStateChangeInput sci; private final StateHistorySystem shs; @@ -112,51 +99,19 @@ public class HistoryBuilder extends TmfComponent { return shs; } - // ------------------------------------------------------------------------ - // Signal handlers - // ------------------------------------------------------------------------ - - /** - * Signal handler to start building the configured state history. - * - * This could also be called by anyone to trigger the building of the - * history without using any TMF signals. Simply pass 'null' as a parameter - * then. - * - * @param signal The signal that triggered the build - */ - @TmfSignalHandler @SuppressWarnings("unchecked") - public void startBuilding(final TmfExperimentRangeUpdatedSignal signal) { - /* Start the construction of the history if it's not started yet */ - if (!this.isRunning) { - hbSem.acquireUninterruptibly(); - currentRequest = new StateSystemBuildRequest(this); - isRunning = true; - sci.getTrace().sendRequest(currentRequest); + @Override + public void run() { + StateSystemBuildRequest request = new StateSystemBuildRequest(this); + sci.getTrace().sendRequest(request); + try { + request.waitForCompletion(); + } catch (InterruptedException e) { + e.printStackTrace(); } + sci.dispose(); } - /** - * Signal handler to cancel any currently running requests. It will delete - * any incomplete file that might have been created. - * - * This could also be called by anyone to cancel the current request without - * using any TMF signals. Simply pass 'null' as a parameter then. - * - * @param signal - */ - @TmfSignalHandler - public void cancelCurrentBuild(final TmfExperimentSelectedSignal signal) { - /* - * We've switched experiments (or re-opened the current one), so stop - * whatever request is currently running. - */ - if (this.isRunning && currentRequest != null) { - currentRequest.cancel(); - } - } - // ------------------------------------------------------------------------ // Methods reserved for the request object below @@ -166,27 +121,13 @@ public class HistoryBuilder extends TmfComponent { IStateChangeInput getInputPlugin() { return sci; } - - /** Shutdown this builder object when the request is over */ - void finish(boolean deleteFile) { - sci.dispose(); - if (deleteFile) { - hb.removeFiles(); - } - currentRequest = null; - isRunning = false; - TmfSignalManager.deregister(this); - hbSem.release(); - } } - class StateSystemBuildRequest extends TmfEventRequest { /** The amount of events queried at a time through the requests */ private final static int chunkSize = 50000; - private final HistoryBuilder builder; private final IStateChangeInput sci; @SuppressWarnings("unchecked") @@ -194,7 +135,6 @@ class StateSystemBuildRequest extends TmfEventRequest { super((Class) builder.getInputPlugin().getExpectedEventType().getClass(), TmfTimeRange.ETERNITY, TmfDataRequest.ALL_DATA, chunkSize, ITmfDataRequest.ExecutionType.BACKGROUND); - this.builder = builder; this.sci = builder.getInputPlugin(); } @@ -209,18 +149,15 @@ class StateSystemBuildRequest extends TmfEventRequest { @Override public void handleSuccess() { super.handleSuccess(); - builder.finish(false); } @Override public void handleCancel() { super.handleCancel(); - builder.finish(true); } @Override public void handleFailure() { super.handleFailure(); - builder.finish(true); } } \ No newline at end of file diff --git a/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/statesystem/StateSystemManager.java b/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/statesystem/StateSystemManager.java new file mode 100644 index 0000000000..9e12b09c2b --- /dev/null +++ b/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/statesystem/StateSystemManager.java @@ -0,0 +1,98 @@ +/******************************************************************************* + * Copyright (c) 2012 Ericsson + * Copyright (c) 2010, 2011 École Polytechnique de Montréal + * Copyright (c) 2010, 2011 Alexandre Montplaisir + * + * 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 + * + *******************************************************************************/ + +package org.eclipse.linuxtools.tmf.core.statesystem; + +import java.io.File; +import java.io.IOException; + +import org.eclipse.linuxtools.tmf.core.component.TmfComponent; +import org.eclipse.linuxtools.tmf.core.exceptions.TmfTraceException; +import org.eclipse.linuxtools.tmf.core.statesystem.backend.historytree.HistoryTreeBackend; +import org.eclipse.linuxtools.tmf.core.statesystem.backend.historytree.ThreadedHistoryTreeBackend; + +/** + * This abstract manager class handles loading or creating state history files + * for use in TMF's generic state system. + * + * @author alexmont + * + */ +public abstract class StateSystemManager extends TmfComponent { + + /** Size of the blocking queue to use when building a state history */ + private final static int QUEUE_SIZE = 10000; + + /** + * Load the history file matching the target trace. If the file already + * exists, it will be opened directly. If not, it will be created from + * scratch. In the case the history has to be built, it's possible to block + * the calling thread until construction is complete. + * + * @param htFile + * The target name of the history file we want to use. If it + * exists it will be opened. If it doesn't, a new file will be + * created with this name/path. + * @param htInput + * The IStateChangeInput to use for building the history file. It + * may be required even if we are opening an already-existing + * history (ie, for partial histories). + * @param waitForCompletion + * Should we block the calling thread until the construction is + * complete? It has no effect if the file already exists. + * @return A IStateSystemQuerier handler to the state system, with which you + * can then run queries on the history. + * @throws TmfTraceException + */ + public static IStateSystemQuerier loadStateHistory(File htFile, + IStateChangeInput htInput) throws TmfTraceException { + IStateSystemQuerier ss; + IStateHistoryBackend htBackend; + + /* If the target file already exists, do not rebuild it uselessly */ + // TODO for now we assume it's complete. Might be a good idea to check + // at least if its range matches the trace's range. + if (htFile.exists()) { + /* Load an existing history */ + try { + htBackend = new HistoryTreeBackend(htFile); + ss = HistoryBuilder.openExistingHistory(htBackend); + return ss; + } catch (IOException e) { + /* + * There was an error opening the existing file. Perhaps it was + * corrupted, perhaps it's an old version? We'll just + * fall-through and try to build a new one from scratch instead. + */ + } + } + + /* Create a new state history from scratch */ + HistoryBuilder builder; + if (htInput == null) { + return null; + } + try { + htBackend = new ThreadedHistoryTreeBackend(htFile, + htInput.getStartTime(), QUEUE_SIZE); + builder = new HistoryBuilder(htInput, htBackend); + builder.run(); //FIXME + } catch (IOException e) { + /* + * If it fails here however, it means there was a problem writing + * to the disk, so throw a real exception this time. + */ + throw new TmfTraceException(e.toString(), e); + } + return builder.getStateSystemQuerier(); + } +} -- 2.34.1