aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGeneviève Bastien2013-01-17 11:52:32 (EST)
committerGenevieve Bastien2013-08-22 14:00:30 (EDT)
commit2dd07f769a5ab03b63a407cdf77e0cb1bb07fbf5 (patch)
treeb5a0456d1324a82cf96d9d36756d5730d2a393e0
parent721b8fc4e1511afcaee8e82c506aa7b256587d3a (diff)
downloadorg.eclipse.linuxtools-2dd07f769a5ab03b63a407cdf77e0cb1bb07fbf5.zip
org.eclipse.linuxtools-2dd07f769a5ab03b63a407cdf77e0cb1bb07fbf5.tar.gz
org.eclipse.linuxtools-2dd07f769a5ab03b63a407cdf77e0cb1bb07fbf5.tar.bz2
Tmf: Trace synchronization using network eventsrefs/changes/56/14056/10
* Event matching infrastructure allow to create dependencies between 2 events. * Network events (TCP packets) are matched for LTTng 2.0 traces, using one of two techniques: fgiraldeau's dynamic probe addon module, or an experimental branch with additional data on net_* tracepoints of lttng-modules. * Traces in an experiment are synchronized using the Fully Incremental Convex Hull algorithm. * A trace's timestamps can be modified using Timestamp Transforms classes. TmfTimestampTransformLinear takes a slope and/or an offset. * Once synchronized, the trace is copied, without its supplementary files so the state system is regenerated with synchronized time. * A new synchronization view shows statistics about the synchronization. * The synchronization information is kept at the experiment level to be able to view synchronization's statistics after first sync. * Synchronization formula for a trace is saved in supplementary files. * Unit tests for trace synchronization. Change-Id: I1971fcd856254fc5654c609d6146904cd3dfd25c Signed-off-by: Geneviève Bastien <gbastien+lttng@versatic.net> Reviewed-on: https://git.eclipse.org/r/14056 Tested-by: Hudson CI Reviewed-by: Bernd Hufmann <bernd.hufmann@ericsson.com> IP-Clean: Bernd Hufmann <bernd.hufmann@ericsson.com> Tested-by: Bernd Hufmann <bernd.hufmann@ericsson.com>
-rw-r--r--lttng/org.eclipse.linuxtools.ctf.core.tests/shared/org/eclipse/linuxtools/ctf/core/tests/shared/CtfTestTraces.java4
-rw-r--r--lttng/org.eclipse.linuxtools.ctf.core.tests/traces/.gitignore1
-rwxr-xr-xlttng/org.eclipse.linuxtools.ctf.core.tests/traces/get-traces.sh4
-rw-r--r--lttng/org.eclipse.linuxtools.ctf.core.tests/traces/get-traces.xml4
-rw-r--r--lttng/org.eclipse.linuxtools.lttng2.kernel.core.tests/META-INF/MANIFEST.MF10
-rw-r--r--lttng/org.eclipse.linuxtools.lttng2.kernel.core.tests/src/org/eclipse/linuxtools/lttng2/kernel/core/tests/AllTests.java3
-rw-r--r--lttng/org.eclipse.linuxtools.lttng2.kernel.core.tests/src/org/eclipse/linuxtools/lttng2/kernel/core/tests/event/matchandsync/AllTests.java28
-rw-r--r--lttng/org.eclipse.linuxtools.lttng2.kernel.core.tests/src/org/eclipse/linuxtools/lttng2/kernel/core/tests/event/matchandsync/ExperimentSyncTest.java100
-rw-r--r--lttng/org.eclipse.linuxtools.lttng2.kernel.core.tests/src/org/eclipse/linuxtools/lttng2/kernel/core/tests/event/matchandsync/MatchAndSyncTest.java63
-rw-r--r--lttng/org.eclipse.linuxtools.lttng2.kernel.core/META-INF/MANIFEST.MF3
-rw-r--r--lttng/org.eclipse.linuxtools.lttng2.kernel.core/src/org/eclipse/linuxtools/internal/lttng2/kernel/core/Activator.java5
-rw-r--r--lttng/org.eclipse.linuxtools.lttng2.kernel.core/src/org/eclipse/linuxtools/internal/lttng2/kernel/core/TcpEventStrings.java60
-rw-r--r--lttng/org.eclipse.linuxtools.lttng2.kernel.core/src/org/eclipse/linuxtools/lttng2/kernel/core/event/matching/TcpEventMatching.java87
-rw-r--r--lttng/org.eclipse.linuxtools.lttng2.kernel.core/src/org/eclipse/linuxtools/lttng2/kernel/core/event/matching/TcpLttngEventMatching.java116
-rw-r--r--lttng/org.eclipse.linuxtools.tmf.core.tests/shared/org/eclipse/linuxtools/tmf/core/tests/shared/CtfTmfTestTraces.java2
-rw-r--r--lttng/org.eclipse.linuxtools.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/AllTmfCoreTests.java1
-rw-r--r--lttng/org.eclipse.linuxtools.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/synchronization/AllTests.java26
-rw-r--r--lttng/org.eclipse.linuxtools.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/synchronization/SyncTest.java240
-rw-r--r--lttng/org.eclipse.linuxtools.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/synchronization/TsTransformTest.java144
-rw-r--r--lttng/org.eclipse.linuxtools.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/trace/TmfTraceTest.java8
-rw-r--r--lttng/org.eclipse.linuxtools.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/event/TmfSyncEventStub.java45
-rw-r--r--lttng/org.eclipse.linuxtools.tmf.core/META-INF/MANIFEST.MF2
-rw-r--r--lttng/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/ctfadaptor/CtfTmfEvent.java1
-rw-r--r--lttng/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/ctfadaptor/CtfTmfEventFactory.java3
-rw-r--r--lttng/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/ctfadaptor/CtfTmfTrace.java15
-rw-r--r--lttng/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/event/matching/IMatchProcessingUnit.java56
-rw-r--r--lttng/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/event/matching/ITmfEventMatching.java31
-rw-r--r--lttng/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/event/matching/ITmfMatchEventDefinition.java56
-rw-r--r--lttng/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/event/matching/TmfEventDependency.java60
-rw-r--r--lttng/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/event/matching/TmfEventMatches.java82
-rw-r--r--lttng/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/event/matching/TmfEventMatching.java275
-rw-r--r--lttng/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/event/matching/TmfNetworkEventMatching.java226
-rw-r--r--lttng/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/event/matching/TmfNetworkMatchDefinition.java37
-rw-r--r--lttng/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/signal/TmfTraceSynchronizedSignal.java53
-rw-r--r--lttng/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/synchronization/ITmfTimestampTransform.java55
-rw-r--r--lttng/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/synchronization/Messages.java53
-rw-r--r--lttng/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/synchronization/SyncAlgorithmFullyIncremental.java572
-rw-r--r--lttng/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/synchronization/SynchronizationAlgorithm.java135
-rw-r--r--lttng/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/synchronization/SynchronizationBackend.java219
-rw-r--r--lttng/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/synchronization/SynchronizationManager.java133
-rw-r--r--lttng/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/synchronization/TmfTimestampTransform.java79
-rw-r--r--lttng/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/synchronization/TmfTimestampTransformLinear.java148
-rw-r--r--lttng/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/synchronization/messages.properties21
-rw-r--r--lttng/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/timestamp/TmfTimestamp.java21
-rw-r--r--lttng/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/ITmfTrace.java104
-rw-r--r--lttng/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/TmfExperiment.java117
-rw-r--r--lttng/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/TmfTrace.java114
-rw-r--r--lttng/org.eclipse.linuxtools.tmf.ui/META-INF/MANIFEST.MF1
-rw-r--r--lttng/org.eclipse.linuxtools.tmf.ui/icons/eview16/synced.gifbin0 -> 160 bytes
-rw-r--r--lttng/org.eclipse.linuxtools.tmf.ui/plugin.properties6
-rw-r--r--lttng/org.eclipse.linuxtools.tmf.ui/plugin.xml56
-rw-r--r--lttng/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/handlers/Messages.java11
-rw-r--r--lttng/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/handlers/OpenExperimentHandler.java3
-rw-r--r--lttng/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/handlers/SynchronizeTracesHandler.java250
-rw-r--r--lttng/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/handlers/messages.properties10
-rw-r--r--lttng/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/model/TmfWithFolderElement.java4
-rw-r--r--lttng/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/synchronization/Messages.java33
-rw-r--r--lttng/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/synchronization/TmfSynchronizationView.java127
-rw-r--r--lttng/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/synchronization/messages.properties2
59 files changed, 4060 insertions, 65 deletions
diff --git a/lttng/org.eclipse.linuxtools.ctf.core.tests/shared/org/eclipse/linuxtools/ctf/core/tests/shared/CtfTestTraces.java b/lttng/org.eclipse.linuxtools.ctf.core.tests/shared/org/eclipse/linuxtools/ctf/core/tests/shared/CtfTestTraces.java
index 1f8f14f..9128c73 100644
--- a/lttng/org.eclipse.linuxtools.ctf.core.tests/shared/org/eclipse/linuxtools/ctf/core/tests/shared/CtfTestTraces.java
+++ b/lttng/org.eclipse.linuxtools.ctf.core.tests/shared/org/eclipse/linuxtools/ctf/core/tests/shared/CtfTestTraces.java
@@ -30,7 +30,9 @@ public abstract class CtfTestTraces {
private static final String[] testTracePaths = {
"../org.eclipse.linuxtools.ctf.core.tests/traces/kernel",
"../org.eclipse.linuxtools.ctf.core.tests/traces/trace2",
- "../org.eclipse.linuxtools.ctf.core.tests/traces/kernel_vm"
+ "../org.eclipse.linuxtools.ctf.core.tests/traces/kernel_vm",
+ "../org.eclipse.linuxtools.ctf.core.tests/traces/synctraces/scp_src",
+ "../org.eclipse.linuxtools.ctf.core.tests/traces/synctraces/scp_dest"
};
private static CTFTrace[] testTraces = new CTFTrace[testTracePaths.length];
diff --git a/lttng/org.eclipse.linuxtools.ctf.core.tests/traces/.gitignore b/lttng/org.eclipse.linuxtools.ctf.core.tests/traces/.gitignore
index 0d74bee..4194ab3 100644
--- a/lttng/org.eclipse.linuxtools.ctf.core.tests/traces/.gitignore
+++ b/lttng/org.eclipse.linuxtools.ctf.core.tests/traces/.gitignore
@@ -3,6 +3,7 @@
/ctf-testsuite
/kernel
/kernel_vm
+/synctraces
/trace2
*.ht
diff --git a/lttng/org.eclipse.linuxtools.ctf.core.tests/traces/get-traces.sh b/lttng/org.eclipse.linuxtools.ctf.core.tests/traces/get-traces.sh
index 4abdb95..71ef353 100755
--- a/lttng/org.eclipse.linuxtools.ctf.core.tests/traces/get-traces.sh
+++ b/lttng/org.eclipse.linuxtools.ctf.core.tests/traces/get-traces.sh
@@ -24,3 +24,7 @@ wget http://www.dorsal.polymtl.ca/~alexmont/data/kernel_vm.tar.bz2 -O- | tar xvj
# CTF test suite, used for testing CTF parser compliance
git clone https://github.com/efficios/ctf-testsuite.git
+
+# Trace used by the lttng2 kernel to match packets and synchronize
+wget http://www.dorsal.polymtl.ca/~gbastien/traces/synctraces.tar.gz -O- | tar xvzf - &&
+
diff --git a/lttng/org.eclipse.linuxtools.ctf.core.tests/traces/get-traces.xml b/lttng/org.eclipse.linuxtools.ctf.core.tests/traces/get-traces.xml
index 09d0410..b860eba 100644
--- a/lttng/org.eclipse.linuxtools.ctf.core.tests/traces/get-traces.xml
+++ b/lttng/org.eclipse.linuxtools.ctf.core.tests/traces/get-traces.xml
@@ -14,6 +14,7 @@
<get ignoreerrors="true" dest="sample-ctf-trace-20120412.tar.bz2" skipexisting="true" src="http://lttng.org/files/samples/sample-ctf-trace-20120412.tar.bz2"/>
<get ignoreerrors="true" dest="trace2.tar.bz2" skipexisting="true" src="http://www.dorsal.polymtl.ca/~alexmont/data/trace2.tar.bz2"/>
<get ignoreerrors="true" dest="kernel_vm.tar.bz2" skipexisting="true" src="http://www.dorsal.polymtl.ca/~alexmont/data/kernel_vm.tar.bz2" />
+ <get ignoreerrors="true" dest="synctraces.tar.gz" skipexisting="true" src="http://www.dorsal.polymtl.ca/~gbastien/traces/synctraces.tar.gz" />
<exec executable = "git" failifexecutionfails="false">
<arg value = "clone"/>
<arg value = "https://github.com/efficios/ctf-testsuite.git"/>
@@ -29,6 +30,7 @@
<available file="sample-ctf-trace-20120412.tar.bz2"/>
<available file="trace2.tar.bz2"/>
<available file="kernel_vm.tar.bz2" />
+ <available file="synctraces.tar.gz" />
</and>
</condition>
<antcall target="extractTraces"/>
@@ -44,9 +46,11 @@
<bunzip2 src="sample-ctf-trace-20120412.tar.bz2"/>
<bunzip2 src="trace2.tar.bz2"/>
<bunzip2 src="kernel_vm.tar.bz2" />
+ <gunzip src="synctraces.tar.gz" />
<untar src="sample-ctf-trace-20120412.tar" dest="." />
<untar src="trace2.tar" dest="." />
<untar src="kernel_vm.tar" dest="." />
+ <untar src="synctraces.tar" dest="." />
<echo message="Traces extracted successfully"/>
</target>
</project>
diff --git a/lttng/org.eclipse.linuxtools.lttng2.kernel.core.tests/META-INF/MANIFEST.MF b/lttng/org.eclipse.linuxtools.lttng2.kernel.core.tests/META-INF/MANIFEST.MF
index be9524c..83dd137 100644
--- a/lttng/org.eclipse.linuxtools.lttng2.kernel.core.tests/META-INF/MANIFEST.MF
+++ b/lttng/org.eclipse.linuxtools.lttng2.kernel.core.tests/META-INF/MANIFEST.MF
@@ -11,7 +11,9 @@ Require-Bundle: org.junit;bundle-version="4.0.0",
org.eclipse.core.runtime,
org.eclipse.linuxtools.tmf.core;bundle-version="3.0.0",
org.eclipse.linuxtools.tmf.core.tests;bundle-version="3.0.0",
- org.eclipse.linuxtools.lttng2.kernel.core;bundle-version="3.0.0"
-Export-Package: org.eclipse.linuxtools.lttng2.kernel.core.tests;x-friends:="org.eclipse.linuxtools.lttng.alltests",
- org.eclipse.linuxtools.lttng2.kernel.core.tests.headless;x-internal:=true,
- org.eclipse.linuxtools.lttng2.kernel.core.tests.stateprovider;x-internal:=true
+ org.eclipse.linuxtools.lttng2.kernel.core;bundle-version="3.0.0",
+ org.eclipse.core.resources
+Export-Package: org.eclipse.linuxtools.lttng2.kernel.core.tests,
+ org.eclipse.linuxtools.lttng2.kernel.core.tests.event.matchandsync,
+ org.eclipse.linuxtools.lttng2.kernel.core.tests.headless,
+ org.eclipse.linuxtools.lttng2.kernel.core.tests.stateprovider
diff --git a/lttng/org.eclipse.linuxtools.lttng2.kernel.core.tests/src/org/eclipse/linuxtools/lttng2/kernel/core/tests/AllTests.java b/lttng/org.eclipse.linuxtools.lttng2.kernel.core.tests/src/org/eclipse/linuxtools/lttng2/kernel/core/tests/AllTests.java
index 682e400..e6f3cb6 100644
--- a/lttng/org.eclipse.linuxtools.lttng2.kernel.core.tests/src/org/eclipse/linuxtools/lttng2/kernel/core/tests/AllTests.java
+++ b/lttng/org.eclipse.linuxtools.lttng2.kernel.core.tests/src/org/eclipse/linuxtools/lttng2/kernel/core/tests/AllTests.java
@@ -21,6 +21,7 @@ import org.junit.runners.Suite;
@RunWith(Suite.class)
@Suite.SuiteClasses({
ActivatorTest.class,
- org.eclipse.linuxtools.lttng2.kernel.core.tests.stateprovider.TestAll.class
+ org.eclipse.linuxtools.lttng2.kernel.core.tests.stateprovider.TestAll.class,
+ org.eclipse.linuxtools.lttng2.kernel.core.tests.event.matchandsync.AllTests.class
})
public class AllTests { }
diff --git a/lttng/org.eclipse.linuxtools.lttng2.kernel.core.tests/src/org/eclipse/linuxtools/lttng2/kernel/core/tests/event/matchandsync/AllTests.java b/lttng/org.eclipse.linuxtools.lttng2.kernel.core.tests/src/org/eclipse/linuxtools/lttng2/kernel/core/tests/event/matchandsync/AllTests.java
new file mode 100644
index 0000000..9a37836
--- /dev/null
+++ b/lttng/org.eclipse.linuxtools.lttng2.kernel.core.tests/src/org/eclipse/linuxtools/lttng2/kernel/core/tests/event/matchandsync/AllTests.java
@@ -0,0 +1,28 @@
+/*******************************************************************************
+ * Copyright (c) 2013 É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 implementation
+ *******************************************************************************/
+
+package org.eclipse.linuxtools.lttng2.kernel.core.tests.event.matchandsync;
+
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
+
+/**
+ * Test suite for org.eclipse.linuxtools.lttng2.kernel.core.tests.event.matching
+ */
+@RunWith(Suite.class)
+@Suite.SuiteClasses({
+ MatchAndSyncTest.class,
+ ExperimentSyncTest.class
+})
+public class AllTests {
+
+}
diff --git a/lttng/org.eclipse.linuxtools.lttng2.kernel.core.tests/src/org/eclipse/linuxtools/lttng2/kernel/core/tests/event/matchandsync/ExperimentSyncTest.java b/lttng/org.eclipse.linuxtools.lttng2.kernel.core.tests/src/org/eclipse/linuxtools/lttng2/kernel/core/tests/event/matchandsync/ExperimentSyncTest.java
new file mode 100644
index 0000000..6267b03
--- /dev/null
+++ b/lttng/org.eclipse.linuxtools.lttng2.kernel.core.tests/src/org/eclipse/linuxtools/lttng2/kernel/core/tests/event/matchandsync/ExperimentSyncTest.java
@@ -0,0 +1,100 @@
+/*******************************************************************************
+ * Copyright (c) 2013 É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 implementation
+ *******************************************************************************/
+
+package org.eclipse.linuxtools.lttng2.kernel.core.tests.event.matchandsync;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+import org.eclipse.linuxtools.lttng2.kernel.core.event.matching.TcpEventMatching;
+import org.eclipse.linuxtools.lttng2.kernel.core.event.matching.TcpLttngEventMatching;
+import org.eclipse.linuxtools.tmf.core.ctfadaptor.CtfTmfTrace;
+import org.eclipse.linuxtools.tmf.core.event.matching.TmfEventMatching;
+import org.eclipse.linuxtools.tmf.core.exceptions.TmfTraceException;
+import org.eclipse.linuxtools.tmf.core.synchronization.ITmfTimestampTransform;
+import org.eclipse.linuxtools.tmf.core.synchronization.SynchronizationAlgorithm;
+import org.eclipse.linuxtools.tmf.core.synchronization.TmfTimestampTransform;
+import org.eclipse.linuxtools.tmf.core.tests.shared.CtfTmfTestTraces;
+import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace;
+import org.eclipse.linuxtools.tmf.core.trace.TmfExperiment;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Tests for experiment syncing
+ *
+ * @author Geneviève Bastien
+ */
+@SuppressWarnings("nls")
+public class ExperimentSyncTest {
+
+ private static final String EXPERIMENT = "MyExperiment";
+ private static int BLOCK_SIZE = 1000;
+
+ private static ITmfTrace[] fTraces;
+ private static TmfExperiment fExperiment;
+
+ /**
+ * Setup the traces and experiment
+ */
+ @Before
+ public void setUp() {
+ CtfTmfTrace trace1 = CtfTmfTestTraces.getTestTrace(3);
+ CtfTmfTrace trace2 = CtfTmfTestTraces.getTestTrace(4);
+
+ fTraces = new CtfTmfTrace[2];
+ fTraces[0] = trace1;
+ fTraces[1] = trace2;
+
+ fExperiment = new TmfExperiment(trace1.getEventType(), EXPERIMENT, fTraces, BLOCK_SIZE);
+
+ TmfEventMatching.registerMatchObject(new TcpEventMatching());
+ TmfEventMatching.registerMatchObject(new TcpLttngEventMatching());
+ }
+
+ /**
+ * Reset the timestamp transforms on the traces
+ */
+ @After
+ public void cleanUp() {
+ fTraces[0].setTimestampTransform(TmfTimestampTransform.IDENTITY);
+ fTraces[1].setTimestampTransform(TmfTimestampTransform.IDENTITY);
+ }
+
+ /**
+ * Testing experiment synchronization
+ */
+ @Test
+ public void testExperimentSync() {
+ try {
+ SynchronizationAlgorithm syncAlgo = fExperiment.synchronizeTraces(true);
+
+ ITmfTimestampTransform tt1, tt2;
+
+ tt1 = syncAlgo.getTimestampTransform(fTraces[0]);
+ tt2 = syncAlgo.getTimestampTransform(fTraces[1]);
+
+ fTraces[0].setTimestampTransform(tt1);
+ fTraces[1].setTimestampTransform(tt2);
+
+ assertEquals("TmfTimestampTransform [ IDENTITY ]", tt2.toString());
+ assertEquals("TmfTimestampLinear [ alpha = 0.9999413783703139011056845831168394, beta = 79796507913179.33347660124688298171 ]", tt1.toString());
+
+ assertEquals(syncAlgo.getTimestampTransform(fTraces[0].getName()),fTraces[0].getTimestampTransform());
+ assertEquals(syncAlgo.getTimestampTransform(fTraces[1].getName()),fTraces[1].getTimestampTransform());
+
+ } catch (TmfTraceException e) {
+ fail("Exception thrown in experiment synchronization " + e.getMessage());
+ }
+ }
+}
diff --git a/lttng/org.eclipse.linuxtools.lttng2.kernel.core.tests/src/org/eclipse/linuxtools/lttng2/kernel/core/tests/event/matchandsync/MatchAndSyncTest.java b/lttng/org.eclipse.linuxtools.lttng2.kernel.core.tests/src/org/eclipse/linuxtools/lttng2/kernel/core/tests/event/matchandsync/MatchAndSyncTest.java
new file mode 100644
index 0000000..b036336
--- /dev/null
+++ b/lttng/org.eclipse.linuxtools.lttng2.kernel.core.tests/src/org/eclipse/linuxtools/lttng2/kernel/core/tests/event/matchandsync/MatchAndSyncTest.java
@@ -0,0 +1,63 @@
+/*******************************************************************************
+ * Copyright (c) 2013 É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 implementation
+ *******************************************************************************/
+
+package org.eclipse.linuxtools.lttng2.kernel.core.tests.event.matchandsync;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import org.eclipse.linuxtools.lttng2.kernel.core.event.matching.TcpEventMatching;
+import org.eclipse.linuxtools.lttng2.kernel.core.event.matching.TcpLttngEventMatching;
+import org.eclipse.linuxtools.tmf.core.ctfadaptor.CtfTmfTrace;
+import org.eclipse.linuxtools.tmf.core.event.matching.TmfEventMatching;
+import org.eclipse.linuxtools.tmf.core.event.matching.TmfNetworkEventMatching;
+import org.eclipse.linuxtools.tmf.core.tests.shared.CtfTmfTestTraces;
+import org.junit.Test;
+
+/**
+ * Tests for {@link TcpEventMatching}
+ *
+ * @author Geneviève Bastien
+ */
+@SuppressWarnings("nls")
+public class MatchAndSyncTest {
+
+ /**
+ * Testing the packet matching
+ */
+ @Test
+ public void testMatching() {
+ final String cr = System.getProperty("line.separator");
+ CtfTmfTrace trace1 = CtfTmfTestTraces.getTestTrace(3);
+ CtfTmfTrace trace2 = CtfTmfTestTraces.getTestTrace(4);
+
+ CtfTmfTrace[] tracearr = new CtfTmfTrace[2];
+ tracearr[0] = trace1;
+ tracearr[1] = trace2;
+
+ TmfEventMatching.registerMatchObject(new TcpEventMatching());
+ TmfEventMatching.registerMatchObject(new TcpLttngEventMatching());
+
+ TmfNetworkEventMatching twoTraceMatch = new TmfNetworkEventMatching(tracearr);
+ assertTrue(twoTraceMatch.matchEvents());
+
+ String stats = twoTraceMatch.toString();
+ assertEquals("TmfEventMatches [ Number of matches found: 46 ]" +
+ "Trace 0:" + cr +
+ " 3 unmatched incoming events" + cr +
+ " 2 unmatched outgoing events" + cr +
+ "Trace 1:" + cr +
+ " 2 unmatched incoming events" + cr +
+ " 1 unmatched outgoing events" + cr, stats);
+ }
+
+}
diff --git a/lttng/org.eclipse.linuxtools.lttng2.kernel.core/META-INF/MANIFEST.MF b/lttng/org.eclipse.linuxtools.lttng2.kernel.core/META-INF/MANIFEST.MF
index 7e84ee5..2ba6f2e 100644
--- a/lttng/org.eclipse.linuxtools.lttng2.kernel.core/META-INF/MANIFEST.MF
+++ b/lttng/org.eclipse.linuxtools.lttng2.kernel.core/META-INF/MANIFEST.MF
@@ -14,4 +14,5 @@ Require-Bundle: org.eclipse.core.runtime,
org.eclipse.linuxtools.tmf.core;bundle-version="3.0.0"
Export-Package: org.eclipse.linuxtools.internal.lttng2.kernel.core;x-friends:="org.eclipse.linuxtools.lttng2.kernel.ui,org.eclipse.linuxtools.lttng2.kernel.core.tests",
org.eclipse.linuxtools.internal.lttng2.kernel.core.stateprovider;x-friends:="org.eclipse.linuxtools.lttng2.kernel.core.tests",
- org.eclipse.linuxtools.lttng2.kernel.core.trace
+ org.eclipse.linuxtools.lttng2.kernel.core.trace,
+ org.eclipse.linuxtools.lttng2.kernel.core.event.matching
diff --git a/lttng/org.eclipse.linuxtools.lttng2.kernel.core/src/org/eclipse/linuxtools/internal/lttng2/kernel/core/Activator.java b/lttng/org.eclipse.linuxtools.lttng2.kernel.core/src/org/eclipse/linuxtools/internal/lttng2/kernel/core/Activator.java
index d0270fd..8629784 100644
--- a/lttng/org.eclipse.linuxtools.lttng2.kernel.core/src/org/eclipse/linuxtools/internal/lttng2/kernel/core/Activator.java
+++ b/lttng/org.eclipse.linuxtools.lttng2.kernel.core/src/org/eclipse/linuxtools/internal/lttng2/kernel/core/Activator.java
@@ -15,6 +15,9 @@ package org.eclipse.linuxtools.internal.lttng2.kernel.core;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Plugin;
import org.eclipse.core.runtime.Status;
+import org.eclipse.linuxtools.lttng2.kernel.core.event.matching.TcpEventMatching;
+import org.eclipse.linuxtools.lttng2.kernel.core.event.matching.TcpLttngEventMatching;
+import org.eclipse.linuxtools.tmf.core.event.matching.TmfEventMatching;
import org.osgi.framework.BundleContext;
/**
@@ -69,6 +72,8 @@ public class Activator extends Plugin {
public void start(BundleContext context) throws Exception {
super.start(context);
plugin = this;
+ TmfEventMatching.registerMatchObject(new TcpEventMatching());
+ TmfEventMatching.registerMatchObject(new TcpLttngEventMatching());
}
@Override
diff --git a/lttng/org.eclipse.linuxtools.lttng2.kernel.core/src/org/eclipse/linuxtools/internal/lttng2/kernel/core/TcpEventStrings.java b/lttng/org.eclipse.linuxtools.lttng2.kernel.core/src/org/eclipse/linuxtools/internal/lttng2/kernel/core/TcpEventStrings.java
new file mode 100644
index 0000000..2891210
--- /dev/null
+++ b/lttng/org.eclipse.linuxtools.lttng2.kernel.core/src/org/eclipse/linuxtools/internal/lttng2/kernel/core/TcpEventStrings.java
@@ -0,0 +1,60 @@
+/*******************************************************************************
+ * Copyright (c) 2013 É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.linuxtools.internal.lttng2.kernel.core;
+
+/**
+ * This file defines all the known event and field names used to trace socket
+ * connection for both the addons module method (
+ * {@link org.eclipse.linuxtools.lttng2.kernel.core.event.matching.TcpEventMatching}
+ * ) and the net_data_experimental branch (
+ * {@link org.eclipse.linuxtools.lttng2.kernel.core.event.matching.TcpLttngEventMatching}
+ * ).
+ *
+ * These events should be eventually mainlined and when this happens, this class
+ * won't be necessary anymore and they should be moved to {@link LttngStrings}
+ * class
+ *
+ *
+ * @author Geneviève Bastien
+ */
+@SuppressWarnings({ "javadoc", "nls" })
+public interface TcpEventStrings {
+
+ /* Event names */
+ public static final String INET_CONNECT = "inet_connect";
+ public static final String INET_SOCK_CREATE = "inet_sock_create";
+ public static final String INET_SOCK_LOCAL_OUT = "inet_sock_local_out";
+ public static final String INET_SOCK_LOCAL_IN = "inet_sock_local_in";
+ public static final String INET_SOCK_CLONE = "inet_sock_clone";
+ public static final String INET_ACCEPT = "inet_accept";
+ public static final String INET_SOCK_DELETE = "inet_sock_delete";
+ public static final String NETIF_RECEIVE_SKB = "netif_receive_skb";
+ public static final String NET_DEV_QUEUE = "net_dev_queue";
+
+ /* Field names */
+ public static final String SEQ = "seq";
+ public static final String SK = "sk";
+ public static final String OSK = "osk";
+ public static final String NSK = "nsk";
+ public static final String SPORT = "sport";
+ public static final String DPORT = "dport";
+ public static final String SADDR = "saddr";
+ public static final String DADDR = "daddr";
+ public static final String ACKSEQ = "ack_seq";
+ public static final String CHECK = "check";
+ public static final String WINDOW = "window";
+ public static final String FLAGS = "flags";
+ public static final String TRANSPORT_FIELDS = "transport_fields";
+ public static final String TYPE_TCP = "thtype_tcp";
+
+}
diff --git a/lttng/org.eclipse.linuxtools.lttng2.kernel.core/src/org/eclipse/linuxtools/lttng2/kernel/core/event/matching/TcpEventMatching.java b/lttng/org.eclipse.linuxtools.lttng2.kernel.core/src/org/eclipse/linuxtools/lttng2/kernel/core/event/matching/TcpEventMatching.java
new file mode 100644
index 0000000..7f9952a
--- /dev/null
+++ b/lttng/org.eclipse.linuxtools.lttng2.kernel.core/src/org/eclipse/linuxtools/lttng2/kernel/core/event/matching/TcpEventMatching.java
@@ -0,0 +1,87 @@
+/*******************************************************************************
+ * Copyright (c) 2013 É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 implementation and API
+ *******************************************************************************/
+
+package org.eclipse.linuxtools.lttng2.kernel.core.event.matching;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.linuxtools.internal.lttng2.kernel.core.TcpEventStrings;
+import org.eclipse.linuxtools.tmf.core.ctfadaptor.CtfTmfTrace;
+import org.eclipse.linuxtools.tmf.core.event.ITmfEvent;
+import org.eclipse.linuxtools.tmf.core.event.matching.TmfEventMatching.MatchingType;
+import org.eclipse.linuxtools.tmf.core.event.matching.TmfNetworkEventMatching.Direction;
+import org.eclipse.linuxtools.tmf.core.event.matching.TmfNetworkMatchDefinition;
+import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace;
+
+/**
+ * Class to match tcp type events. This matching class applies to traces
+ * obtained with the 'addons' lttng module. This module can be obtained with
+ * lttng-modules to generate traces at
+ * https://github.com/giraldeau/lttng-modules/tree/addons
+ *
+ * Note: this module only allows to generate traces to be read and analyzed by
+ * TMF, no code from this module is being used here
+ *
+ * @author Geneviève Bastien
+ * @since 3.0
+ */
+public class TcpEventMatching extends TmfNetworkMatchDefinition {
+
+ @Override
+ public Direction getDirection(ITmfEvent event) {
+ String evname = event.getType().getName();
+ /* Is the event a tcp socket in or out event */
+ if (evname.equals(TcpEventStrings.INET_SOCK_LOCAL_IN)) {
+ return Direction.IN;
+ } else if (evname.equals(TcpEventStrings.INET_SOCK_LOCAL_OUT)) {
+ return Direction.OUT;
+ }
+ return null;
+ }
+
+ /**
+ * The key to uniquely identify a TCP packet depends on many fields. This
+ * method computes the key for a given event.
+ *
+ * @param event
+ * The event for which to compute the key
+ * @return the unique key for this event
+ */
+ @Override
+ public List<Object> getUniqueField(ITmfEvent event) {
+ List<Object> keys = new ArrayList<Object>();
+
+ keys.add(event.getContent().getField(TcpEventStrings.SEQ).getValue());
+ keys.add(event.getContent().getField(TcpEventStrings.ACKSEQ).getValue());
+ keys.add(event.getContent().getField(TcpEventStrings.FLAGS).getValue());
+
+ return keys;
+ }
+
+ @Override
+ public boolean canMatchTrace(ITmfTrace trace) {
+ if (!(trace instanceof CtfTmfTrace)) {
+ return false;
+ }
+ CtfTmfTrace ktrace = (CtfTmfTrace) trace;
+ String[] events = { TcpEventStrings.INET_SOCK_LOCAL_IN, TcpEventStrings.INET_SOCK_LOCAL_OUT };
+ return ktrace.hasAtLeastOneOfEvents(events);
+ }
+
+ @Override
+ public MatchingType[] getApplicableMatchingTypes() {
+ MatchingType[] types = { MatchingType.NETWORK };
+ return types;
+ }
+
+}
diff --git a/lttng/org.eclipse.linuxtools.lttng2.kernel.core/src/org/eclipse/linuxtools/lttng2/kernel/core/event/matching/TcpLttngEventMatching.java b/lttng/org.eclipse.linuxtools.lttng2.kernel.core/src/org/eclipse/linuxtools/lttng2/kernel/core/event/matching/TcpLttngEventMatching.java
new file mode 100644
index 0000000..ca9d95b
--- /dev/null
+++ b/lttng/org.eclipse.linuxtools.lttng2.kernel.core/src/org/eclipse/linuxtools/lttng2/kernel/core/event/matching/TcpLttngEventMatching.java
@@ -0,0 +1,116 @@
+/*******************************************************************************
+ * Copyright (c) 2013 É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 implementation and API
+ *******************************************************************************/
+
+package org.eclipse.linuxtools.lttng2.kernel.core.event.matching;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.linuxtools.internal.lttng2.kernel.core.TcpEventStrings;
+import org.eclipse.linuxtools.tmf.core.ctfadaptor.CtfTmfTrace;
+import org.eclipse.linuxtools.tmf.core.event.ITmfEvent;
+import org.eclipse.linuxtools.tmf.core.event.ITmfEventField;
+import org.eclipse.linuxtools.tmf.core.event.TmfEventField;
+import org.eclipse.linuxtools.tmf.core.event.matching.TmfEventMatching.MatchingType;
+import org.eclipse.linuxtools.tmf.core.event.matching.TmfNetworkEventMatching.Direction;
+import org.eclipse.linuxtools.tmf.core.event.matching.TmfNetworkMatchDefinition;
+import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace;
+
+/**
+ * Class to match tcp type events. This class applies to traces obtained with
+ * the full network tracepoint data available from an experimental branch of
+ * lttng-modules. This branch is often rebased on lttng-modules master and is
+ * available at
+ * http://git.dorsal.polymtl.ca/~gbastien?p=lttng-modules.git;a=summary
+ * net_data_experimental branch.
+ *
+ * @author Geneviève Bastien
+ * @since 3.0
+ */
+public class TcpLttngEventMatching extends TmfNetworkMatchDefinition {
+
+ private static final String[] key_seq = { TcpEventStrings.TRANSPORT_FIELDS, TcpEventStrings.TYPE_TCP, TcpEventStrings.SEQ };
+ private static final String[] key_ackseq = { TcpEventStrings.TRANSPORT_FIELDS, TcpEventStrings.TYPE_TCP, TcpEventStrings.ACKSEQ };
+ private static final String[] key_flags = { TcpEventStrings.TRANSPORT_FIELDS, TcpEventStrings.TYPE_TCP, TcpEventStrings.FLAGS };
+
+ private static boolean canMatchPacket(final ITmfEvent event) {
+ TmfEventField field = (TmfEventField) event.getContent();
+
+ String[] tcp_data = { TcpEventStrings.TRANSPORT_FIELDS, TcpEventStrings.TYPE_TCP };
+ ITmfEventField data = field.getSubField(tcp_data);
+ if (data != null) {
+ return (data.getValue() != null);
+ }
+ return false;
+ }
+
+ /**
+ * The key to uniquely identify a TCP packet depends on many fields. This
+ * method computes the key for a given event.
+ *
+ * @param event
+ * The event for which to compute the key
+ * @return the unique key for this event
+ */
+ @Override
+ public List<Object> getUniqueField(ITmfEvent event) {
+ List<Object> keys = new ArrayList<Object>();
+
+ TmfEventField field = (TmfEventField) event.getContent();
+ ITmfEventField data;
+
+ data = field.getSubField(key_seq);
+ if (data != null) {
+ keys.add(data.getValue());
+ }
+ data = field.getSubField(key_ackseq);
+ if (data != null) {
+ keys.add(data.getValue());
+ }
+ data = field.getSubField(key_flags);
+ if (data != null) {
+ keys.add(data.getValue());
+ }
+
+ return keys;
+ }
+
+ @Override
+ public boolean canMatchTrace(ITmfTrace trace) {
+ if (!(trace instanceof CtfTmfTrace)) {
+ return false;
+ }
+ CtfTmfTrace ktrace = (CtfTmfTrace) trace;
+ String[] events = { TcpEventStrings.NET_DEV_QUEUE, TcpEventStrings.NETIF_RECEIVE_SKB };
+ return (ktrace.hasAtLeastOneOfEvents(events));
+ }
+
+ @Override
+ public Direction getDirection(ITmfEvent event) {
+ String evname = event.getType().getName();
+
+ /* Is the event a tcp socket in or out event */
+ if (evname.equals(TcpEventStrings.NETIF_RECEIVE_SKB) && canMatchPacket(event)) {
+ return Direction.IN;
+ } else if (evname.equals(TcpEventStrings.NET_DEV_QUEUE) && canMatchPacket(event)) {
+ return Direction.OUT;
+ }
+ return null;
+ }
+
+ @Override
+ public MatchingType[] getApplicableMatchingTypes() {
+ MatchingType[] types = { MatchingType.NETWORK };
+ return types;
+ }
+
+}
diff --git a/lttng/org.eclipse.linuxtools.tmf.core.tests/shared/org/eclipse/linuxtools/tmf/core/tests/shared/CtfTmfTestTraces.java b/lttng/org.eclipse.linuxtools.tmf.core.tests/shared/org/eclipse/linuxtools/tmf/core/tests/shared/CtfTmfTestTraces.java
index 9f4146d..11de9ad 100644
--- a/lttng/org.eclipse.linuxtools.tmf.core.tests/shared/org/eclipse/linuxtools/tmf/core/tests/shared/CtfTmfTestTraces.java
+++ b/lttng/org.eclipse.linuxtools.tmf.core.tests/shared/org/eclipse/linuxtools/tmf/core/tests/shared/CtfTmfTestTraces.java
@@ -34,7 +34,7 @@ public final class CtfTmfTestTraces {
private static final File emptyFile = new File("");
private static CtfTmfTrace emptyTrace = new CtfTmfTrace();
- private static CtfTmfTrace[] testTraces = new CtfTmfTrace[3];
+ private static CtfTmfTrace[] testTraces = new CtfTmfTrace[5];
/**
* Get an empty File (new File("");)
diff --git a/lttng/org.eclipse.linuxtools.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/AllTmfCoreTests.java b/lttng/org.eclipse.linuxtools.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/AllTmfCoreTests.java
index 56ea7f2..35dac22 100644
--- a/lttng/org.eclipse.linuxtools.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/AllTmfCoreTests.java
+++ b/lttng/org.eclipse.linuxtools.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/AllTmfCoreTests.java
@@ -29,6 +29,7 @@ import org.junit.runners.Suite;
org.eclipse.linuxtools.tmf.core.tests.signal.AllTests.class,
org.eclipse.linuxtools.tmf.core.tests.statesystem.AllTests.class,
org.eclipse.linuxtools.tmf.core.tests.statistics.AllTests.class,
+ org.eclipse.linuxtools.tmf.core.tests.synchronization.AllTests.class,
org.eclipse.linuxtools.tmf.core.tests.trace.AllTests.class,
org.eclipse.linuxtools.tmf.core.tests.trace.indexer.checkpoint.AllTests.class,
org.eclipse.linuxtools.tmf.core.tests.trace.location.AllTests.class,
diff --git a/lttng/org.eclipse.linuxtools.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/synchronization/AllTests.java b/lttng/org.eclipse.linuxtools.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/synchronization/AllTests.java
new file mode 100644
index 0000000..6a264ab
--- /dev/null
+++ b/lttng/org.eclipse.linuxtools.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/synchronization/AllTests.java
@@ -0,0 +1,26 @@
+/*******************************************************************************
+ * Copyright (c) 2013 É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 implementation
+ *******************************************************************************/
+
+package org.eclipse.linuxtools.tmf.core.tests.synchronization;
+
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
+
+/**
+ * Test suite for org.eclipse.linuxtools.tmf.core.synchronization
+ */
+@RunWith(Suite.class)
+@Suite.SuiteClasses({ TsTransformTest.class,
+ SyncTest.class })
+public class AllTests {
+
+}
diff --git a/lttng/org.eclipse.linuxtools.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/synchronization/SyncTest.java b/lttng/org.eclipse.linuxtools.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/synchronization/SyncTest.java
new file mode 100644
index 0000000..46742f4
--- /dev/null
+++ b/lttng/org.eclipse.linuxtools.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/synchronization/SyncTest.java
@@ -0,0 +1,240 @@
+/*******************************************************************************
+ * Copyright (c) 2013 É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 implementation
+ *******************************************************************************/
+
+package org.eclipse.linuxtools.tmf.core.tests.synchronization;
+
+import static org.junit.Assert.assertEquals;
+
+import org.eclipse.linuxtools.tmf.core.event.matching.TmfEventDependency;
+import org.eclipse.linuxtools.tmf.core.synchronization.ITmfTimestampTransform;
+import org.eclipse.linuxtools.tmf.core.synchronization.SyncAlgorithmFullyIncremental;
+import org.eclipse.linuxtools.tmf.core.synchronization.SynchronizationAlgorithm;
+import org.eclipse.linuxtools.tmf.core.synchronization.SynchronizationAlgorithm.SyncQuality;
+import org.eclipse.linuxtools.tmf.core.synchronization.TmfTimestampTransform;
+import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimestamp;
+import org.eclipse.linuxtools.tmf.tests.stubs.event.TmfSyncEventStub;
+import org.eclipse.linuxtools.tmf.tests.stubs.trace.TmfTraceStub;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Tests for {@link SynchronizationAlgorithm} and its descendants
+ *
+ * @author Geneviève Bastien
+ */
+@SuppressWarnings("nls")
+public class SyncTest {
+
+ private TmfTraceStub t1, t2;
+ private TmfTraceStub[] fTraces;
+
+ /**
+ * Initializing the traces
+ */
+ @Before
+ public void init() {
+ t1 = new TmfTraceStub();
+ t1.init("t1");
+ t2 = new TmfTraceStub();
+ t2.init("t2");
+ TmfTraceStub[] traces = { t1, t2 };
+ fTraces = traces;
+ }
+
+ /**
+ * Testing fully incremental algorithm with communication between the two
+ * traces
+ */
+ @Test
+ public void testFullyIncremental() {
+
+ SynchronizationAlgorithm syncAlgo = new SyncAlgorithmFullyIncremental();
+
+ syncAlgo.init(fTraces);
+
+ assertEquals(SyncQuality.ABSENT, syncAlgo.getSynchronizationQuality(t1, t2));
+ syncAlgo.addMatch(
+ new TmfEventDependency(new TmfSyncEventStub(t2, new TmfTimestamp(1)),
+ new TmfSyncEventStub(t1, new TmfTimestamp(1))
+ ));
+ assertEquals("SyncAlgorithmFullyIncremental [Between t1 and t2 [ alpha 1 beta 0 ]]", syncAlgo.toString());
+ assertEquals(SyncQuality.INCOMPLETE, syncAlgo.getSynchronizationQuality(t1, t2));
+
+ syncAlgo.addMatch(
+ new TmfEventDependency(new TmfSyncEventStub(t1, new TmfTimestamp(1)),
+ new TmfSyncEventStub(t2, new TmfTimestamp(3))
+ ));
+ assertEquals("SyncAlgorithmFullyIncremental [Between t1 and t2 [ alpha 1 beta 0 ]]", syncAlgo.toString());
+ assertEquals(SyncQuality.INCOMPLETE, syncAlgo.getSynchronizationQuality(t1, t2));
+
+ syncAlgo.addMatch(
+ new TmfEventDependency(new TmfSyncEventStub(t2, new TmfTimestamp(2)),
+ new TmfSyncEventStub(t1, new TmfTimestamp(3))
+ ));
+ assertEquals("SyncAlgorithmFullyIncremental [Between t1 and t2 [ alpha 1 beta 0.5 ]]", syncAlgo.toString());
+ assertEquals(SyncQuality.APPROXIMATE, syncAlgo.getSynchronizationQuality(t1, t2));
+
+ syncAlgo.addMatch(
+ new TmfEventDependency(new TmfSyncEventStub(t1, new TmfTimestamp(3)),
+ new TmfSyncEventStub(t2, new TmfTimestamp(5))
+ ));
+ assertEquals("SyncAlgorithmFullyIncremental [Between t1 and t2 [ alpha 0.75 beta 1.25 ]]", syncAlgo.toString());
+ assertEquals(SyncQuality.ACCURATE, syncAlgo.getSynchronizationQuality(t1, t2));
+
+ syncAlgo.addMatch(
+ new TmfEventDependency(new TmfSyncEventStub(t1, new TmfTimestamp(4)),
+ new TmfSyncEventStub(t2, new TmfTimestamp(8))
+ ));
+ assertEquals("SyncAlgorithmFullyIncremental [Between t1 and t2 [ alpha 0.75 beta 1.25 ]]", syncAlgo.toString());
+ assertEquals(SyncQuality.ACCURATE, syncAlgo.getSynchronizationQuality(t1, t2));
+
+ syncAlgo.addMatch(
+ new TmfEventDependency(new TmfSyncEventStub(t2, new TmfTimestamp(4)),
+ new TmfSyncEventStub(t1, new TmfTimestamp(5))
+ ));
+ assertEquals("SyncAlgorithmFullyIncremental [Between t1 and t2 [ alpha 1.125 beta 0.875 ]]", syncAlgo.toString());
+ assertEquals(SyncQuality.ACCURATE, syncAlgo.getSynchronizationQuality(t1, t2));
+
+ syncAlgo.addMatch(
+ new TmfEventDependency(new TmfSyncEventStub(t2, new TmfTimestamp(4)),
+ new TmfSyncEventStub(t1, new TmfTimestamp(6))
+ ));
+ assertEquals("SyncAlgorithmFullyIncremental [Between t1 and t2 [ alpha 1.125 beta 0.875 ]]", syncAlgo.toString());
+ assertEquals(SyncQuality.ACCURATE, syncAlgo.getSynchronizationQuality(t1, t2));
+
+ syncAlgo.addMatch(
+ new TmfEventDependency(new TmfSyncEventStub(t1, new TmfTimestamp(6)),
+ new TmfSyncEventStub(t2, new TmfTimestamp(7))
+ ));
+ assertEquals("SyncAlgorithmFullyIncremental [Between t1 and t2 [ alpha 0.725 beta 1.275 ]]", syncAlgo.toString());
+ assertEquals(SyncQuality.ACCURATE, syncAlgo.getSynchronizationQuality(t1, t2));
+
+ ITmfTimestampTransform tt2 = syncAlgo.getTimestampTransform(t2);
+ ITmfTimestampTransform tt1 = syncAlgo.getTimestampTransform(t1);
+
+ assertEquals(syncAlgo.getTimestampTransform("t1"), tt1);
+ assertEquals(TmfTimestampTransform.IDENTITY, tt1);
+ assertEquals(syncAlgo.getTimestampTransform("t2"), tt2);
+
+ /* Make the two hulls intersect */
+ syncAlgo.addMatch(
+ new TmfEventDependency(new TmfSyncEventStub(t1, new TmfTimestamp(7)),
+ new TmfSyncEventStub(t2, new TmfTimestamp(4))
+ ));
+ syncAlgo.addMatch(
+ new TmfEventDependency(new TmfSyncEventStub(t2, new TmfTimestamp(7)),
+ new TmfSyncEventStub(t1, new TmfTimestamp(3))
+ ));
+ assertEquals(SyncQuality.FAIL, syncAlgo.getSynchronizationQuality(t1, t2));
+ }
+
+ /**
+ * Testing the fully incremental synchronization algorithm when
+ * communication goes in only one direction
+ */
+ @Test
+ public void testOneHull() {
+
+ SynchronizationAlgorithm syncAlgo = new SyncAlgorithmFullyIncremental();
+
+ syncAlgo.init(fTraces);
+
+ assertEquals(SyncQuality.ABSENT, syncAlgo.getSynchronizationQuality(t1, t2));
+
+ syncAlgo.addMatch(
+ new TmfEventDependency(new TmfSyncEventStub(t1, new TmfTimestamp(1)),
+ new TmfSyncEventStub(t2, new TmfTimestamp(3)))
+ );
+ assertEquals(SyncQuality.INCOMPLETE, syncAlgo.getSynchronizationQuality(t1, t2));
+
+ syncAlgo.addMatch(
+ new TmfEventDependency(new TmfSyncEventStub(t1, new TmfTimestamp(2)),
+ new TmfSyncEventStub(t2, new TmfTimestamp(5)))
+ );
+
+ assertEquals(SyncQuality.INCOMPLETE, syncAlgo.getSynchronizationQuality(t1, t2));
+
+ syncAlgo.addMatch(
+ new TmfEventDependency(new TmfSyncEventStub(t1, new TmfTimestamp(3)),
+ new TmfSyncEventStub(t2, new TmfTimestamp(5)))
+ );
+ assertEquals(SyncQuality.INCOMPLETE, syncAlgo.getSynchronizationQuality(t1, t2));
+
+ syncAlgo.addMatch(
+ new TmfEventDependency(new TmfSyncEventStub(t1, new TmfTimestamp(4)),
+ new TmfSyncEventStub(t2, new TmfTimestamp(7)))
+ );
+ assertEquals(SyncQuality.INCOMPLETE, syncAlgo.getSynchronizationQuality(t1, t2));
+ assertEquals("SyncAlgorithmFullyIncremental [Between t1 and t2 [ alpha 1 beta 0 ]]", syncAlgo.toString());
+
+ }
+
+ /**
+ * Testing the fully incremental synchronization algorithm when all
+ * communication from trace1 to trace2 happens before all communication from
+ * trace2 to trace1
+ */
+ @Test
+ public void testDisjoint() {
+
+ SynchronizationAlgorithm syncAlgo = new SyncAlgorithmFullyIncremental();
+
+ syncAlgo.init(fTraces);
+
+ assertEquals(SyncQuality.ABSENT, syncAlgo.getSynchronizationQuality(t1, t2));
+
+ syncAlgo.addMatch(
+ new TmfEventDependency(new TmfSyncEventStub(t1, new TmfTimestamp(1)),
+ new TmfSyncEventStub(t2, new TmfTimestamp(3)))
+ );
+ assertEquals(SyncQuality.INCOMPLETE, syncAlgo.getSynchronizationQuality(t1, t2));
+
+ syncAlgo.addMatch(
+ new TmfEventDependency(new TmfSyncEventStub(t1, new TmfTimestamp(2)),
+ new TmfSyncEventStub(t2, new TmfTimestamp(5)))
+ );
+
+ assertEquals(SyncQuality.INCOMPLETE, syncAlgo.getSynchronizationQuality(t1, t2));
+
+ syncAlgo.addMatch(
+ new TmfEventDependency(new TmfSyncEventStub(t1, new TmfTimestamp(3)),
+ new TmfSyncEventStub(t2, new TmfTimestamp(5)))
+ );
+ assertEquals(SyncQuality.INCOMPLETE, syncAlgo.getSynchronizationQuality(t1, t2));
+
+ syncAlgo.addMatch(
+ new TmfEventDependency(new TmfSyncEventStub(t1, new TmfTimestamp(4)),
+ new TmfSyncEventStub(t2, new TmfTimestamp(7)))
+ );
+ assertEquals(SyncQuality.INCOMPLETE, syncAlgo.getSynchronizationQuality(t1, t2));
+ assertEquals("SyncAlgorithmFullyIncremental [Between t1 and t2 [ alpha 1 beta 0 ]]", syncAlgo.toString());
+
+ syncAlgo.addMatch(
+ new TmfEventDependency(new TmfSyncEventStub(t2, new TmfTimestamp(7)),
+ new TmfSyncEventStub(t1, new TmfTimestamp(6)))
+ );
+ assertEquals(SyncQuality.APPROXIMATE, syncAlgo.getSynchronizationQuality(t1, t2));
+
+ syncAlgo.addMatch(
+ new TmfEventDependency(new TmfSyncEventStub(t2, new TmfTimestamp(8)),
+ new TmfSyncEventStub(t1, new TmfTimestamp(6)))
+ );
+ assertEquals(SyncQuality.APPROXIMATE, syncAlgo.getSynchronizationQuality(t1, t2));
+
+ syncAlgo.addMatch(
+ new TmfEventDependency(new TmfSyncEventStub(t2, new TmfTimestamp(10)),
+ new TmfSyncEventStub(t1, new TmfTimestamp(8)))
+ );
+ assertEquals(SyncQuality.APPROXIMATE, syncAlgo.getSynchronizationQuality(t1, t2));
+ assertEquals("SyncAlgorithmFullyIncremental [Between t1 and t2 [ alpha 1 beta 2.5 ]]", syncAlgo.toString());
+ }
+}
diff --git a/lttng/org.eclipse.linuxtools.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/synchronization/TsTransformTest.java b/lttng/org.eclipse.linuxtools.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/synchronization/TsTransformTest.java
new file mode 100644
index 0000000..4e91a4a
--- /dev/null
+++ b/lttng/org.eclipse.linuxtools.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/synchronization/TsTransformTest.java
@@ -0,0 +1,144 @@
+/*******************************************************************************
+ * Copyright (c) 2013 É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 implementation
+ *******************************************************************************/
+
+package org.eclipse.linuxtools.tmf.core.tests.synchronization;
+
+import static org.junit.Assert.*;
+
+import java.math.BigDecimal;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.linuxtools.tmf.core.synchronization.ITmfTimestampTransform;
+import org.eclipse.linuxtools.tmf.core.synchronization.TmfTimestampTransform;
+import org.eclipse.linuxtools.tmf.core.synchronization.TmfTimestampTransformLinear;
+import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp;
+import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimestamp;
+import org.junit.Test;
+
+/**
+ * Tests for {@link TmfTimestampTransform} and its descendants
+ *
+ * @author Geneviève Bastien
+ */
+@SuppressWarnings("nls")
+public class TsTransformTest {
+
+ private long ts = 1361657893526374091L;
+ private ITmfTimestamp oTs = new TmfTimestamp(ts);
+
+ /**
+ * Test the linear transform
+ */
+ @Test
+ public void testLinearTransform() {
+ /* Default constructor */
+ TmfTimestampTransformLinear ttl = new TmfTimestampTransformLinear();
+ assertEquals(1361657893526374091L, ttl.transform(ts));
+ assertEquals(1361657893526374091L, ttl.transform(oTs).getValue());
+
+ /* Just an offset */
+ ttl = new TmfTimestampTransformLinear(BigDecimal.valueOf(1.0), BigDecimal.valueOf(3));
+ assertEquals(1361657893526374094L, ttl.transform(ts));
+ assertEquals(1361657893526374094L, ttl.transform(oTs).getValue());
+
+ /* Just a slope */
+ ttl = new TmfTimestampTransformLinear(BigDecimal.valueOf(2.0), BigDecimal.valueOf(0));
+ assertEquals(2723315787052748182L, ttl.transform(ts));
+ assertEquals(2723315787052748182L, ttl.transform(oTs).getValue());
+
+ /* Offset and slope */
+ ttl = new TmfTimestampTransformLinear(BigDecimal.valueOf(2.0), BigDecimal.valueOf(3));
+ assertEquals(2723315787052748185L, ttl.transform(ts));
+ assertEquals(2723315787052748185L, ttl.transform(oTs).getValue());
+
+ /* Offset and slope */
+ ttl = new TmfTimestampTransformLinear(BigDecimal.valueOf(0.5), BigDecimal.valueOf(0));
+ assertEquals(680828946763187045L, ttl.transform(ts));
+ assertEquals(680828946763187045L, ttl.transform(oTs).getValue());
+ }
+
+ /**
+ * Test for the identity transform
+ */
+ @Test
+ public void testIdentityTransform() {
+ ITmfTimestampTransform tt = TmfTimestampTransform.IDENTITY;
+ assertEquals(ts, tt.transform(ts));
+ assertEquals(oTs, tt.transform(oTs));
+ }
+
+ /**
+ * Test hash and equals function
+ */
+ @Test
+ public void testEquality() {
+ Map<ITmfTimestampTransform, String> map = new HashMap<ITmfTimestampTransform, String>();
+ ITmfTimestampTransform ttl = new TmfTimestampTransformLinear(BigDecimal.valueOf(2.0), BigDecimal.valueOf(3));
+ ITmfTimestampTransform ttl2 = new TmfTimestampTransformLinear(BigDecimal.valueOf(2.0), BigDecimal.valueOf(3));
+ ITmfTimestampTransform ttl3 = new TmfTimestampTransformLinear(BigDecimal.valueOf(3), BigDecimal.valueOf(3));
+ assertEquals(ttl, ttl2);
+ assertFalse(ttl.equals(ttl3));
+ assertFalse(ttl2.equals(ttl3));
+
+ map.put(ttl, "a");
+ assertTrue(map.containsKey(ttl2));
+ assertEquals("a", map.get(ttl));
+
+ ITmfTimestampTransform ti = TmfTimestampTransform.IDENTITY;
+ assertEquals(TmfTimestampTransform.IDENTITY, ti);
+ assertFalse(TmfTimestampTransform.IDENTITY.equals(ttl));
+
+ map.put(ti, "b");
+ assertTrue(map.containsKey(TmfTimestampTransform.IDENTITY));
+ assertEquals("b", map.get(ti));
+
+ assertFalse(ti.equals(ttl));
+ assertFalse(ttl.equals(ti));
+
+ }
+
+ /**
+ * Test the transform composition function
+ */
+ @Test
+ public void testComposition() {
+ long t = 100;
+ ITmfTimestampTransform ti = TmfTimestampTransform.IDENTITY;
+ ITmfTimestampTransform ttl = new TmfTimestampTransformLinear(BigDecimal.valueOf(2.0), BigDecimal.valueOf(3));
+ ITmfTimestampTransform ttl2 = new TmfTimestampTransformLinear(BigDecimal.valueOf(1.5), BigDecimal.valueOf(8));
+
+ ITmfTimestampTransform tc1 = ti.composeWith(ttl);
+ /* Should be ttl */
+ assertEquals(ttl, tc1);
+ assertEquals(203, tc1.transform(t));
+
+ tc1 = ttl.composeWith(ti);
+ /* Should be ttl also */
+ assertEquals(ttl, tc1);
+ assertEquals(203, tc1.transform(t));
+
+ tc1 = ti.composeWith(ti);
+ /* Should be identity */
+ assertEquals(tc1, TmfTimestampTransform.IDENTITY);
+ assertEquals(100, tc1.transform(t));
+
+ tc1 = ttl.composeWith(ttl2);
+ assertEquals(ttl.transform(ttl2.transform(t)), tc1.transform(t));
+ assertEquals(319, tc1.transform(t));
+
+ tc1 = ttl2.composeWith(ttl);
+ assertEquals(ttl2.transform(ttl.transform(t)), tc1.transform(t));
+ assertEquals(312, tc1.transform(t));
+
+ }
+}
diff --git a/lttng/org.eclipse.linuxtools.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/trace/TmfTraceTest.java b/lttng/org.eclipse.linuxtools.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/trace/TmfTraceTest.java
index c105b47..7c05832 100644
--- a/lttng/org.eclipse.linuxtools.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/trace/TmfTraceTest.java
+++ b/lttng/org.eclipse.linuxtools.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/trace/TmfTraceTest.java
@@ -1364,15 +1364,15 @@ public class TmfTraceTest {
assertEquals("getInitialRangeOffset", defaultInitRange, trace.getInitialRangeOffset());
trace.setInitialRangeOffset(new TmfTimestamp(5, ITmfTimestamp.MILLISECOND_SCALE));
trace.indexTrace(true);
+
+ TmfTimestamp initRange = new TmfTimestamp(5, ITmfTimestamp.MILLISECOND_SCALE);
+ assertEquals("getInitialRangeOffset", initRange, trace.getInitialRangeOffset());
+
} catch (final URISyntaxException e) {
fail("URISyntaxException");
} catch (final IOException e) {
fail("IOException");
}
- assertFalse ("Open trace", trace == null);
-
- TmfTimestamp initRange = new TmfTimestamp(5, ITmfTimestamp.MILLISECOND_SCALE);
- assertEquals("getInitialRangeOffset", initRange, trace.getInitialRangeOffset());
}
/**
diff --git a/lttng/org.eclipse.linuxtools.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/event/TmfSyncEventStub.java b/lttng/org.eclipse.linuxtools.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/event/TmfSyncEventStub.java
new file mode 100644
index 0000000..b8a0166
--- /dev/null
+++ b/lttng/org.eclipse.linuxtools.tmf.core.tests/stubs/org/eclipse/linuxtools/tmf/tests/stubs/event/TmfSyncEventStub.java
@@ -0,0 +1,45 @@
+/*******************************************************************************
+ * Copyright (c) 2013 É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 implementation
+ *******************************************************************************/
+
+package org.eclipse.linuxtools.tmf.tests.stubs.event;
+
+import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp;
+import org.eclipse.linuxtools.tmf.core.event.TmfEvent;
+import org.eclipse.linuxtools.tmf.core.event.TmfEventField;
+import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace;
+
+/**
+ * Event stub used by the synchronization tests
+ *
+ * @author Geneviève Bastien
+ */
+public class TmfSyncEventStub extends TmfEvent {
+
+ private static final String stub = "stub"; //$NON-NLS-1$
+
+ /**
+ * Constructor
+ *
+ * @param trace
+ * The trace of this event
+ * @param timestamp
+ * The timestamp
+ */
+ public TmfSyncEventStub(final ITmfTrace trace, final ITmfTimestamp timestamp) {
+ super(trace,
+ timestamp,
+ stub,
+ new TmfEventTypeStub(),
+ new TmfEventField(stub, stub, null),
+ stub);
+ }
+}
diff --git a/lttng/org.eclipse.linuxtools.tmf.core/META-INF/MANIFEST.MF b/lttng/org.eclipse.linuxtools.tmf.core/META-INF/MANIFEST.MF
index 4364e38..518e117 100644
--- a/lttng/org.eclipse.linuxtools.tmf.core/META-INF/MANIFEST.MF
+++ b/lttng/org.eclipse.linuxtools.tmf.core/META-INF/MANIFEST.MF
@@ -25,6 +25,7 @@ Export-Package: org.eclipse.linuxtools.internal.tmf.core;x-friends:="org.eclipse
org.eclipse.linuxtools.tmf.core.ctfadaptor,
org.eclipse.linuxtools.tmf.core.event,
org.eclipse.linuxtools.tmf.core.event.lookup,
+ org.eclipse.linuxtools.tmf.core.event.matching,
org.eclipse.linuxtools.tmf.core.exceptions,
org.eclipse.linuxtools.tmf.core.filter,
org.eclipse.linuxtools.tmf.core.filter.model,
@@ -36,6 +37,7 @@ Export-Package: org.eclipse.linuxtools.internal.tmf.core;x-friends:="org.eclipse
org.eclipse.linuxtools.tmf.core.statesystem,
org.eclipse.linuxtools.tmf.core.statevalue,
org.eclipse.linuxtools.tmf.core.statistics,
+ org.eclipse.linuxtools.tmf.core.synchronization,
org.eclipse.linuxtools.tmf.core.timestamp,
org.eclipse.linuxtools.tmf.core.trace,
org.eclipse.linuxtools.tmf.core.trace.indexer,
diff --git a/lttng/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/ctfadaptor/CtfTmfEvent.java b/lttng/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/ctfadaptor/CtfTmfEvent.java
index ae002a0..fbefc03 100644
--- a/lttng/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/ctfadaptor/CtfTmfEvent.java
+++ b/lttng/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/ctfadaptor/CtfTmfEvent.java
@@ -77,6 +77,7 @@ public final class CtfTmfEvent extends TmfEvent
sourceCPU = cpu;
typeId = declaration.getId();
eventName = declaration.getName();
+
}
/**
diff --git a/lttng/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/ctfadaptor/CtfTmfEventFactory.java b/lttng/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/ctfadaptor/CtfTmfEventFactory.java
index ead5231..6e3dbb4 100644
--- a/lttng/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/ctfadaptor/CtfTmfEventFactory.java
+++ b/lttng/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/ctfadaptor/CtfTmfEventFactory.java
@@ -55,8 +55,7 @@ public final class CtfTmfEventFactory {
/* Prepare what to pass to CtfTmfEvent's constructor */
long ts = eventDef.getTimestamp();
- CtfTmfTimestamp timestamp = new CtfTmfTimestamp(
- originTrace.getCTFTrace().timestampCyclesToNanos(ts));
+ CtfTmfTimestamp timestamp = originTrace.createTimestamp(originTrace.getCTFTrace().timestampCyclesToNanos(ts));
int sourceCPU = eventDef.getCPU();
diff --git a/lttng/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/ctfadaptor/CtfTmfTrace.java b/lttng/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/ctfadaptor/CtfTmfTrace.java
index 2ed9072..5edb8cd 100644
--- a/lttng/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/ctfadaptor/CtfTmfTrace.java
+++ b/lttng/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/ctfadaptor/CtfTmfTrace.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2012, 2013 Ericsson
+ * Copyright (c) 2012, 2013 Ericsson, É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
@@ -9,6 +9,7 @@
* Contributors:
* Matthew Khouzam - Initial API and implementation
* Patrick Tasse - Updated for removal of context clone
+ * Geneviève Bastien - Added the createTimestamp function
*******************************************************************************/
package org.eclipse.linuxtools.tmf.core.ctfadaptor;
@@ -434,4 +435,16 @@ public class CtfTmfTrace extends TmfTrace
public CtfIterator createIterator() {
return new CtfIterator(this);
}
+
+ // ------------------------------------------------------------------------
+ // Timestamp transformation functions
+ // ------------------------------------------------------------------------
+
+ /**
+ * @since 3.0
+ */
+ @Override
+ public CtfTmfTimestamp createTimestamp(long ts) {
+ return new CtfTmfTimestamp(getTimestampTransform().transform(ts));
+ }
}
diff --git a/lttng/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/event/matching/IMatchProcessingUnit.java b/lttng/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/event/matching/IMatchProcessingUnit.java
new file mode 100644
index 0000000..063f15c
--- /dev/null
+++ b/lttng/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/event/matching/IMatchProcessingUnit.java
@@ -0,0 +1,56 @@
+/*******************************************************************************
+ * Copyright (c) 2013 É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 implementation and API
+ *******************************************************************************/
+
+package org.eclipse.linuxtools.tmf.core.event.matching;
+
+import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace;
+
+/**
+ * This class represent an action to be done when event matches are found. This
+ * interface needs to be implemented by all classes that want to be warned when
+ * new event matches are found. They need to register to an instance of
+ * TmfEventMatches class in order to be informed of matches.
+ *
+ * @author Geneviève Bastien
+ * @since 3.0
+ */
+public interface IMatchProcessingUnit {
+
+ /**
+ * Once the traces are known, hook function to initialize some things
+ *
+ * @param fTraces the set of traces that will be synchronized
+ */
+ void init(ITmfTrace[] fTraces);
+
+ /**
+ * Function called when a match is found
+ *
+ * @param match
+ * The event match
+ */
+ void addMatch(TmfEventDependency match);
+
+ /**
+ * Function called after all matching has been done, to do any post-match
+ * treatment
+ */
+ void matchingEnded();
+
+ /**
+ * Counts the matches
+ *
+ * @return the number of matches
+ */
+ int countMatches();
+
+}
diff --git a/lttng/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/event/matching/ITmfEventMatching.java b/lttng/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/event/matching/ITmfEventMatching.java
new file mode 100644
index 0000000..1714ca8
--- /dev/null
+++ b/lttng/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/event/matching/ITmfEventMatching.java
@@ -0,0 +1,31 @@
+/*******************************************************************************
+ * Copyright (c) 2013 É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 implementation and API
+ *******************************************************************************/
+
+package org.eclipse.linuxtools.tmf.core.event.matching;
+
+
+/**
+ * Interface for matching trace events
+ *
+ * @author Geneviève Bastien
+ * @since 3.0
+ */
+public interface ITmfEventMatching {
+
+ /**
+ * Method that start the process of matching events
+ *
+ * @return Whether the match was completed correctly or not
+ */
+ boolean matchEvents();
+
+}
diff --git a/lttng/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/event/matching/ITmfMatchEventDefinition.java b/lttng/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/event/matching/ITmfMatchEventDefinition.java
new file mode 100644
index 0000000..caba635
--- /dev/null
+++ b/lttng/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/event/matching/ITmfMatchEventDefinition.java
@@ -0,0 +1,56 @@
+/*******************************************************************************
+ * Copyright (c) 2013 É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 implementation and API
+ *******************************************************************************/
+
+package org.eclipse.linuxtools.tmf.core.event.matching;
+
+import java.util.List;
+
+import org.eclipse.linuxtools.tmf.core.event.ITmfEvent;
+import org.eclipse.linuxtools.tmf.core.event.matching.TmfEventMatching.MatchingType;
+import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace;
+
+/**
+ * This interface describe a concrete method to match events. Typically it
+ * manages for a given matching type what events/fields are used to match events
+ *
+ * @author Geneviève Bastien
+ * @since 3.0
+ */
+public interface ITmfMatchEventDefinition {
+
+ /**
+ * Returns a list of values for an event that uniquely identifies this event
+ *
+ * @param event
+ * The event for which to compute the key
+ * @return the unique key for this event
+ */
+ List<Object> getUniqueField(ITmfEvent event);
+
+ /**
+ * Verifies whether a trace has all required events to match using this
+ * class
+ *
+ * @param trace
+ * The trace
+ * @return Whether the trace has all required information
+ */
+ boolean canMatchTrace(ITmfTrace trace);
+
+ /**
+ * Return all matching types this definition covers
+ *
+ * @return an array of matching types
+ */
+ MatchingType[] getApplicableMatchingTypes();
+
+}
diff --git a/lttng/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/event/matching/TmfEventDependency.java b/lttng/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/event/matching/TmfEventDependency.java
new file mode 100644
index 0000000..1350250
--- /dev/null
+++ b/lttng/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/event/matching/TmfEventDependency.java
@@ -0,0 +1,60 @@
+/*******************************************************************************
+ * Copyright (c) 2013 É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 implementation and API
+ *******************************************************************************/
+
+package org.eclipse.linuxtools.tmf.core.event.matching;
+
+import org.eclipse.linuxtools.tmf.core.event.ITmfEvent;
+
+/**
+ * Represents a dependency (match) between two events, where source event leads
+ * to destination event
+ *
+ * @author Geneviève Bastien
+ * @since 3.0
+ */
+public class TmfEventDependency {
+
+ private final ITmfEvent fSourceEvent;
+ private final ITmfEvent fDestEvent;
+
+ /**
+ * Constructor
+ *
+ * @param source
+ * The source event of this dependency
+ * @param destination
+ * The destination event of this dependency
+ */
+ public TmfEventDependency(final ITmfEvent source, final ITmfEvent destination) {
+ fSourceEvent = source;
+ fDestEvent = destination;
+ }
+
+ /**
+ * Getter for fSourceEvent
+ *
+ * @return The source event
+ */
+ public ITmfEvent getSourceEvent() {
+ return fSourceEvent;
+ }
+
+ /**
+ * Getter for fDestEvent
+ *
+ * @return the Destination event
+ */
+ public ITmfEvent getDestinationEvent() {
+ return fDestEvent;
+ }
+
+}
diff --git a/lttng/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/event/matching/TmfEventMatches.java b/lttng/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/event/matching/TmfEventMatches.java
new file mode 100644
index 0000000..8cf3e5e
--- /dev/null
+++ b/lttng/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/event/matching/TmfEventMatches.java
@@ -0,0 +1,82 @@
+/*******************************************************************************
+ * Copyright (c) 2013 É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 implementation and API
+ *******************************************************************************/
+
+package org.eclipse.linuxtools.tmf.core.event.matching;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace;
+
+/**
+ * Class that does something with a match.
+ *
+ * This default implementation of the class just adds it to a list of matches
+ *
+ * @author Geneviève Bastien
+ * @since 3.0
+ */
+public class TmfEventMatches implements IMatchProcessingUnit {
+
+ /**
+ * The list of matches found
+ */
+ private final List<TmfEventDependency> fMatches;
+
+ /**
+ * Constructor
+ */
+ public TmfEventMatches() {
+ fMatches = new ArrayList<TmfEventDependency>();
+ }
+
+ /**
+ * IMatchProcessingUnit overrides
+ */
+
+ @Override
+ public void init(ITmfTrace[] fTraces) {
+
+ }
+
+ @Override
+ public void addMatch(TmfEventDependency match) {
+ fMatches.add(match);
+ }
+
+ @Override
+ public void matchingEnded() {
+
+ }
+
+ @Override
+ public int countMatches() {
+ return fMatches.size();
+ }
+
+ /**
+ * Returns the match at the specified index
+ *
+ * @param index
+ * The index of the match to get
+ * @return The match at index or null or not present
+ */
+ public TmfEventDependency getMatch(int index) {
+ return fMatches.get(index);
+ }
+
+ @Override
+ public String toString() {
+ return getClass().getSimpleName() + " [ Number of matches found: " + fMatches.size() + " ]"; //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+}
diff --git a/lttng/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/event/matching/TmfEventMatching.java b/lttng/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/event/matching/TmfEventMatching.java
new file mode 100644
index 0000000..fe694f6
--- /dev/null
+++ b/lttng/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/event/matching/TmfEventMatching.java
@@ -0,0 +1,275 @@
+/*******************************************************************************
+ * Copyright (c) 2013 É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 implementation and API
+ *******************************************************************************/
+
+package org.eclipse.linuxtools.tmf.core.event.matching;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.linuxtools.internal.tmf.core.Activator;
+import org.eclipse.linuxtools.tmf.core.ctfadaptor.CtfTmfEvent;
+import org.eclipse.linuxtools.tmf.core.event.ITmfEvent;
+import org.eclipse.linuxtools.tmf.core.request.ITmfDataRequest;
+import org.eclipse.linuxtools.tmf.core.request.TmfDataRequest;
+import org.eclipse.linuxtools.tmf.core.request.TmfEventRequest;
+import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimeRange;
+import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace;
+
+/**
+ * Abstract class to extend to match certain type of events in a trace
+ *
+ * @author Geneviève Bastien
+ * @since 3.0
+ */
+public abstract class TmfEventMatching implements ITmfEventMatching {
+
+ /**
+ * The matching type
+ *
+ * FIXME Not the best place to put this. Have an array of match types as a
+ * parameter of each trace?
+ */
+ public enum MatchingType {
+ /**
+ * NETWORK, match network events
+ */
+ NETWORK
+ }
+
+ /**
+ * The array of traces to match
+ */
+ private final ITmfTrace[] fTraces;
+
+ /**
+ * The class to call once a match is found
+ */
+ private final IMatchProcessingUnit fMatches;
+
+ private static final Map<MatchingType, List<ITmfMatchEventDefinition>> fMatchDefinitions = new HashMap<MatchingType, List<ITmfMatchEventDefinition>>();
+
+ private final Map<ITmfTrace, ITmfMatchEventDefinition> fMatchMap = new HashMap<ITmfTrace, ITmfMatchEventDefinition>();
+
+ /**
+ * Constructor with multiple traces and a match processing object
+ *
+ * @param traces
+ * The set of traces for which to match events
+ * @param tmfEventMatches
+ * The match processing class
+ */
+ public TmfEventMatching(ITmfTrace[] traces, IMatchProcessingUnit tmfEventMatches) {
+ if (tmfEventMatches == null) {
+ throw new IllegalArgumentException();
+ }
+ fTraces = traces;
+ fMatches = tmfEventMatches;
+ }
+
+ /**
+ * Returns the traces to process
+ *
+ * @return The traces
+ */
+ protected ITmfTrace[] getTraces() {
+ return fTraces;
+ }
+
+ /**
+ * Returns the match processing unit
+ *
+ * @return The match processing unit
+ */
+ protected IMatchProcessingUnit getProcessingUnit() {
+ return fMatches;
+ }
+
+ /**
+ * Returns the match event definition corresponding to the trace
+ *
+ * @param trace
+ * The trace
+ * @return The match event definition object
+ */
+ protected ITmfMatchEventDefinition getEventDefinition(ITmfTrace trace) {
+ return fMatchMap.get(trace);
+ }
+
+ /**
+ * Method that initializes any data structure for the event matching. It
+ * also assigns to each trace an event matching definition instance that
+ * applies to the trace
+ */
+ protected void initMatching() {
+ fMatches.init(fTraces);
+ List<ITmfMatchEventDefinition> deflist = fMatchDefinitions.get(getMatchingType());
+ if (deflist == null) {
+ return;
+ }
+ for (ITmfTrace trace : fTraces) {
+ for (ITmfMatchEventDefinition def : deflist) {
+ if (def.canMatchTrace(trace)) {
+ fMatchMap.put(trace, def);
+ break;
+ }
+ }
+ }
+ }
+
+ /**
+ * Calls any post matching methods of the processing class
+ */
+ protected void finalizeMatching() {
+ fMatches.matchingEnded();
+ }
+
+ /**
+ * Prints stats from the matching
+ *
+ * @return string of statistics
+ */
+ @SuppressWarnings("nls")
+ @Override
+ public String toString() {
+ return getClass().getSimpleName() + " [ " + fMatches + " ]";
+ }
+
+ /**
+ * Matches one event
+ *
+ * @param event
+ * The event to match
+ * @param traceno
+ * The number of the trace this event belongs to
+ */
+ protected abstract void matchEvent(ITmfEvent event, int traceno);
+
+ /**
+ * Returns the matching type this class implements
+ *
+ * @return A matching type
+ */
+ protected abstract MatchingType getMatchingType();
+
+ /**
+ * Method that start the process of matching events
+ *
+ * @return Whether the match was completed correctly or not
+ */
+ @Override
+ public boolean matchEvents() {
+
+ /* Are there traces to match? If no, return false */
+ if (!(fTraces.length > 0)) {
+ return false;
+ }
+
+ // TODO Start a new thread here?
+ initMatching();
+
+ /**
+ * For each trace, get the events and for each event, call the
+ * MatchEvent method
+ *
+ * FIXME This would use a lot of memory if the traces are big, because
+ * all involved events from first trace will have to be kept before a
+ * first match is possible with second trace.
+ *
+ * <pre>
+ * Other possible matching strategy:
+ * Incremental:
+ * Sliding window:
+ * Other strategy: start with the shortest trace, take a few events
+ * at the beginning and at the end
+ * Experiment strategy: have the experiment do the request, then events will
+ * come from both traces chronologically, but then instead of ITmfTrace[], it
+ * would be preferable to have experiment
+ * </pre>
+ */
+ for (int i = 0; i < fTraces.length; i++) {
+
+ EventMatchingBuildRequest request = new EventMatchingBuildRequest(this, i);
+
+ /*
+ * Send the request to the trace here, since there is probably no
+ * experiment.
+ */
+ fTraces[i].sendRequest(request);
+ try {
+ request.waitForCompletion();
+ } catch (InterruptedException e) {
+ Activator.logInfo(e.getMessage());
+ }
+ }
+
+ finalizeMatching();
+
+ return true;
+ }
+
+ /**
+ * Registers an event match definition to be used for a certain match type
+ *
+ * @param match
+ * The event matching definition
+ */
+ public static void registerMatchObject(ITmfMatchEventDefinition match) {
+ for (MatchingType type : match.getApplicableMatchingTypes()) {
+ if (!fMatchDefinitions.containsKey(type)) {
+ fMatchDefinitions.put(type, new ArrayList<ITmfMatchEventDefinition>());
+ }
+ fMatchDefinitions.get(type).add(match);
+ }
+ }
+
+}
+
+class EventMatchingBuildRequest extends TmfEventRequest {
+
+ private final TmfEventMatching matching;
+ private final int traceno;
+
+ EventMatchingBuildRequest(TmfEventMatching matching, int traceno) {
+ super(CtfTmfEvent.class,
+ TmfTimeRange.ETERNITY,
+ 0,
+ TmfDataRequest.ALL_DATA,
+ ITmfDataRequest.ExecutionType.FOREGROUND);
+ this.matching = matching;
+ this.traceno = traceno;
+ }
+
+ @Override
+ public void handleData(final ITmfEvent event) {
+ super.handleData(event);
+ if (event != null) {
+ matching.matchEvent(event, traceno);
+ }
+ }
+
+ @Override
+ public void handleSuccess() {
+ super.handleSuccess();
+ }
+
+ @Override
+ public void handleCancel() {
+ super.handleCancel();
+ }
+
+ @Override
+ public void handleFailure() {
+ super.handleFailure();
+ }
+}
diff --git a/lttng/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/event/matching/TmfNetworkEventMatching.java b/lttng/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/event/matching/TmfNetworkEventMatching.java
new file mode 100644
index 0000000..06536f4
--- /dev/null
+++ b/lttng/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/event/matching/TmfNetworkEventMatching.java
@@ -0,0 +1,226 @@
+/*******************************************************************************
+ * Copyright (c) 2013 É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 implementation and API
+ *******************************************************************************/
+
+package org.eclipse.linuxtools.tmf.core.event.matching;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.linuxtools.tmf.core.event.ITmfEvent;
+import org.eclipse.linuxtools.tmf.core.event.matching.IMatchProcessingUnit;
+import org.eclipse.linuxtools.tmf.core.event.matching.TmfEventDependency;
+import org.eclipse.linuxtools.tmf.core.event.matching.TmfEventMatching;
+import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace;
+
+/**
+ * This class matches events typically network-style, ie. where some events are
+ * 'send' events and the other 'receive' events or out/in events
+ *
+ * @author Geneviève Bastien
+ * @since 3.0
+ */
+public class TmfNetworkEventMatching extends TmfEventMatching {
+
+ /**
+ * Hashtables for unmatches incoming events
+ */
+ private final List<Map<List<Object>, ITmfEvent>> fUnmatchedIn = new ArrayList<Map<List<Object>, ITmfEvent>>();
+
+ /**
+ * Hashtables for unmatches outgoing events
+ */
+ private final List<Map<List<Object>, ITmfEvent>> fUnmatchedOut = new ArrayList<Map<List<Object>, ITmfEvent>>();
+
+ /**
+ * Enum for in and out types
+ */
+ public enum Direction {
+ /**
+ * The event is a 'receive' type of event
+ */
+ IN,
+ /**
+ * The event is a 'send' type of event
+ */
+ OUT,
+ }
+
+ /**
+ * Constructor with multiple traces and match processing object
+ *
+ * @param traces
+ * The set of traces for which to match events
+ */
+ public TmfNetworkEventMatching(ITmfTrace[] traces) {
+ this(traces, new TmfEventMatches());
+ }
+
+ /**
+ * Constructor with multiple traces and match processing object
+ *
+ * @param traces
+ * The set of traces for which to match events
+ * @param tmfEventMatches
+ * The match processing class
+ */
+ public TmfNetworkEventMatching(ITmfTrace[] traces, IMatchProcessingUnit tmfEventMatches) {
+ super(traces, tmfEventMatches);
+ }
+
+ /**
+ * Method that initializes any data structure for the event matching
+ */
+ @Override
+ public void initMatching() {
+ // Initialize the matching infrastructure (unmatched event lists)
+ fUnmatchedIn.clear();
+ fUnmatchedOut.clear();
+ for (int i = 0; i < getTraces().length; i++) {
+ fUnmatchedIn.add(new HashMap<List<Object>, ITmfEvent>());
+ fUnmatchedOut.add(new HashMap<List<Object>, ITmfEvent>());
+ }
+ super.initMatching();
+ }
+
+ /**
+ * Function that counts the events in a hashtable.
+ *
+ * @param tbl
+ * The table to count events for
+ * @return The number of events
+ */
+ protected int countEvents(Map<List<Object>, ITmfEvent> tbl) {
+ return tbl.size();
+ }
+
+ @Override
+ protected MatchingType getMatchingType() {
+ return MatchingType.NETWORK;
+ }
+
+ /**
+ * Matches one event
+ *
+ * @param event
+ * The event to match
+ * @param traceno
+ * The number of the trace this event belongs to
+ */
+ @Override
+ public void matchEvent(ITmfEvent event, int traceno) {
+ /*
+ * TODO: Should find a way to assert the type is right here. For now we
+ * just hope developers register NetworkMatchDefinition for Network
+ * match types...
+ */
+ TmfNetworkMatchDefinition def = (TmfNetworkMatchDefinition) getEventDefinition(event.getTrace());
+ if (def == null) {
+ return;
+ }
+
+ Direction evType = def.getDirection(event);
+ if (evType == null) {
+ return;
+ }
+
+ /* Get the event's unique fields */
+ List<Object> eventKey = def.getUniqueField(event);
+ List<Map<List<Object>, ITmfEvent>> unmatchedTbl, companionTbl;
+
+ /* Point to the appropriate table */
+ switch (evType) {
+ case IN:
+ unmatchedTbl = fUnmatchedIn;
+ companionTbl = fUnmatchedOut;
+ break;
+ case OUT:
+ unmatchedTbl = fUnmatchedOut;
+ companionTbl = fUnmatchedIn;
+ break;
+ default:
+ return;
+ }
+
+ boolean found = false;
+ TmfEventDependency dep = null;
+ /* Search for the event in the companion table */
+ for (Map<List<Object>, ITmfEvent> map : companionTbl) {
+ if (map.containsKey(eventKey)) {
+ found = true;
+ ITmfEvent companionEvent = map.get(eventKey);
+
+ /* Remove the element from the companion table */
+ map.remove(eventKey);
+
+ /* Create the dependency object */
+ switch (evType) {
+ case IN:
+ dep = new TmfEventDependency(companionEvent, event);
+ break;
+ case OUT:
+ dep = new TmfEventDependency(event, companionEvent);
+ break;
+ default:
+ break;
+
+ }
+ }
+ }
+
+ /*
+ * If no companion was found, add the event to the appropriate unMatched
+ * lists
+ */
+ if (found) {
+ getProcessingUnit().addMatch(dep);
+ } else {
+ /*
+ * If an event is already associated with this key, do not add it
+ * again, we keep the first event chronologically, so if its match
+ * is eventually found, it is associated with the first send or
+ * receive event. At best, it is a good guess, at worst, the match
+ * will be too far off to be accurate. Too bad!
+ *
+ * TODO: maybe instead of just one event, we could have a list of
+ * events as value for the unmatched table. Not necessary right now
+ * though
+ */
+ if (!unmatchedTbl.get(traceno).containsKey(eventKey)) {
+ unmatchedTbl.get(traceno).put(eventKey, event);
+ }
+ }
+
+ }
+
+ /**
+ * Prints stats from the matching
+ *
+ * @return string of statistics
+ */
+ @SuppressWarnings("nls")
+ @Override
+ public String toString() {
+ final String cr = System.getProperty("line.separator");
+ StringBuilder b = new StringBuilder();
+ b.append(getProcessingUnit());
+ for (int i = 0; i < getTraces().length; i++) {
+ b.append("Trace " + i + ":" + cr +
+ " " + countEvents(fUnmatchedIn.get(i)) + " unmatched incoming events" + cr +
+ " " + countEvents(fUnmatchedOut.get(i)) + " unmatched outgoing events" + cr);
+ }
+
+ return b.toString();
+ }
+
+}
diff --git a/lttng/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/event/matching/TmfNetworkMatchDefinition.java b/lttng/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/event/matching/TmfNetworkMatchDefinition.java
new file mode 100644
index 0000000..1a0d2e1
--- /dev/null
+++ b/lttng/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/event/matching/TmfNetworkMatchDefinition.java
@@ -0,0 +1,37 @@
+/*******************************************************************************
+ * Copyright (c) 2013 É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 implementation and API
+ *******************************************************************************/
+
+package org.eclipse.linuxtools.tmf.core.event.matching;
+
+import org.eclipse.linuxtools.tmf.core.event.ITmfEvent;
+import org.eclipse.linuxtools.tmf.core.event.matching.TmfNetworkEventMatching.Direction;
+
+/**
+ * Base class for all network match definitions, ie traces with send and receive
+ * events
+ *
+ * @author Geneviève Bastien
+ * @since 3.0
+ */
+public abstract class TmfNetworkMatchDefinition implements ITmfMatchEventDefinition {
+
+ /**
+ * Returns the direction of this event, whether 'send', 'receive' or null if
+ * event is neither
+ *
+ * @param event
+ * The event to check
+ * @return The direction of this event, null if uninteresting event
+ */
+ public abstract Direction getDirection(ITmfEvent event);
+
+}
diff --git a/lttng/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/signal/TmfTraceSynchronizedSignal.java b/lttng/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/signal/TmfTraceSynchronizedSignal.java
new file mode 100644
index 0000000..fa24bbf
--- /dev/null
+++ b/lttng/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/signal/TmfTraceSynchronizedSignal.java
@@ -0,0 +1,53 @@
+/*******************************************************************************
+ * Copyright (c) 2013 É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 implementation
+ *******************************************************************************/
+
+package org.eclipse.linuxtools.tmf.core.signal;
+
+import org.eclipse.linuxtools.tmf.core.synchronization.SynchronizationAlgorithm;
+
+/**
+ * Signal indicating a trace synchronization has been done
+ *
+ * @author Geneviève Bastien
+ * @since 3.0
+ */
+public class TmfTraceSynchronizedSignal extends TmfSignal {
+
+ private final SynchronizationAlgorithm fAlgoSync;
+
+ /**
+ * Constructor
+ *
+ * @param source
+ * Object sending this signal
+ * @param algoSync
+ * The synchronization algorithm used
+ */
+ public TmfTraceSynchronizedSignal(Object source, SynchronizationAlgorithm algoSync) {
+ super(source);
+ fAlgoSync = algoSync;
+ }
+
+ /**
+ * Synchronization algorithm getter
+ *
+ * @return The algorithm object
+ */
+ public SynchronizationAlgorithm getSyncAlgo() {
+ return fAlgoSync;
+ }
+
+ @Override
+ public String toString() {
+ return "[" + getClass().getSimpleName() + " (" + fAlgoSync.toString() + ")]"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ }
+}
diff --git a/lttng/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/synchronization/ITmfTimestampTransform.java b/lttng/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/synchronization/ITmfTimestampTransform.java
new file mode 100644
index 0000000..55bc9e9
--- /dev/null
+++ b/lttng/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/synchronization/ITmfTimestampTransform.java
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ * Copyright (c) 2013 É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 implementation and API
+ *******************************************************************************/
+
+package org.eclipse.linuxtools.tmf.core.synchronization;
+
+import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp;
+
+/**
+ * This class contains a formula to transform the value of a timestamp, for
+ * example after trace synchronization
+ *
+ * @author Geneviève Bastien
+ * @since 3.0
+ */
+public interface ITmfTimestampTransform {
+
+ /**
+ * Transforms a timestamp
+ *
+ * @param timestamp
+ * The timestamp to transform
+ * @return the transformed timestamp
+ */
+ ITmfTimestamp transform(ITmfTimestamp timestamp);
+
+ /**
+ * Transforms a timestamp value
+ *
+ * @param timestamp
+ * The timestamp to transform
+ * @return the transformed value
+ */
+ long transform(long timestamp);
+
+ /**
+ * Returns a timestamp transform that is the composition of two timestamp
+ * transforms.
+ *
+ * @param composeWith
+ * The transform to first apply on the timestamp before applying
+ * the current object
+ * @return A new timestamp transform object with the resulting composition.
+ */
+ ITmfTimestampTransform composeWith(ITmfTimestampTransform composeWith);
+
+}
diff --git a/lttng/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/synchronization/Messages.java b/lttng/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/synchronization/Messages.java
new file mode 100644
index 0000000..c520981
--- /dev/null
+++ b/lttng/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/synchronization/Messages.java
@@ -0,0 +1,53 @@
+/*******************************************************************************
+ * Copyright (c) 2013 É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 implementation
+ *******************************************************************************/
+
+package org.eclipse.linuxtools.tmf.core.synchronization;
+
+import org.eclipse.osgi.util.NLS;
+
+/**
+ * Messages class
+ *
+ * @since 3.0
+ */
+@SuppressWarnings("javadoc")
+public class Messages extends NLS {
+ private static final String BUNDLE_NAME = "org.eclipse.linuxtools.tmf.core.synchronization.messages"; //$NON-NLS-1$
+ public static String SyncAlgorithmFullyIncremental_absent;
+ public static String SyncAlgorithmFullyIncremental_alpha;
+ public static String SyncAlgorithmFullyIncremental_beta;
+ public static String SyncAlgorithmFullyIncremental_T_;
+ public static String SyncAlgorithmFullyIncremental_otherformula;
+ public static String SyncAlgorithmFullyIncremental_mult;
+ public static String SyncAlgorithmFullyIncremental_add;
+ public static String SyncAlgorithmFullyIncremental_ub;
+ public static String SyncAlgorithmFullyIncremental_lb;
+ public static String SyncAlgorithmFullyIncremental_accuracy;
+ public static String SyncAlgorithmFullyIncremental_accurate;
+ public static String SyncAlgorithmFullyIncremental_approx;
+ public static String SyncAlgorithmFullyIncremental_fail;
+ public static String SyncAlgorithmFullyIncremental_incomplete;
+ public static String SyncAlgorithmFullyIncremental_nbmatch;
+ public static String SyncAlgorithmFullyIncremental_nbacc;
+ public static String SyncAlgorithmFullyIncremental_reftrace;
+ public static String SyncAlgorithmFullyIncremental_othertrace;
+ public static String SyncAlgorithmFullyIncremental_refformula;
+ public static String SyncAlgorithmFullyIncremental_NA;
+ public static String SyncAlgorithmFullyIncremental_quality;
+ static {
+ // initialize resource bundle
+ NLS.initializeMessages(BUNDLE_NAME, Messages.class);
+ }
+
+ private Messages() {
+ }
+}
diff --git a/lttng/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/synchronization/SyncAlgorithmFullyIncremental.java b/lttng/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/synchronization/SyncAlgorithmFullyIncremental.java
new file mode 100644
index 0000000..7360e7f
--- /dev/null
+++ b/lttng/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/synchronization/SyncAlgorithmFullyIncremental.java
@@ -0,0 +1,572 @@
+/*******************************************************************************
+ * Copyright (c) 2013 É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 implementation and API
+ *******************************************************************************/
+
+package org.eclipse.linuxtools.tmf.core.synchronization;
+
+import java.io.IOException;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.math.MathContext;
+import java.util.LinkedHashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.linuxtools.tmf.core.event.ITmfEvent;
+import org.eclipse.linuxtools.tmf.core.event.matching.TmfEventDependency;
+import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp;
+import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace;
+
+/**
+ * Class implementing fully incremental trace synchronization approach as
+ * described in
+ *
+ * Masoume Jabbarifar, Michel Dagenais and Alireza Shameli-Sendi,
+ * "Streaming Mode Incremental Clock Synchronization"
+ *
+ * Since the algorithm itself applies to two traces, it is implemented in a
+ * private class, while this public class manages the synchronization between
+ * all traces.
+ *
+ * @author Geneviève Bastien
+ * @since 3.0
+ */
+public class SyncAlgorithmFullyIncremental extends SynchronizationAlgorithm {
+
+ /**
+ * Auto-generated serial UID
+ */
+ private static final long serialVersionUID = -1782788842774838830L;
+
+ private static final MathContext fMc = MathContext.DECIMAL128;
+
+ private final List<ConvexHull> fSyncs;
+
+ /**
+ * Initialization of the attributes
+ */
+ public SyncAlgorithmFullyIncremental() {
+ fSyncs = new LinkedList<ConvexHull>();
+ }
+
+ /**
+ * Function called after all matching has been done, to do any post-match
+ * treatment. For this class, it calculates stats, while the data is
+ * available
+ */
+ @Override
+ public void matchingEnded() {
+ getStats();
+ }
+
+ @Override
+ public void init(ITmfTrace[] fTraces) {
+ fSyncs.clear();
+ /* Create a convex hull for all trace pairs */
+ for (int i = 0; i < fTraces.length; i++) {
+ for (int j = i + 1; j < fTraces.length; j++) {
+ ConvexHull algo = new ConvexHull(fTraces[i].getName(), fTraces[j].getName());
+ fSyncs.add(algo);
+ }
+ }
+ }
+
+ @Override
+ protected void processMatch(TmfEventDependency match) {
+ String trace1 = match.getSourceEvent().getTrace().getName();
+ String trace2 = match.getDestinationEvent().getTrace().getName();
+
+ /* Process only if source and destination are different */
+ if (trace1.equals(trace2)) {
+ return;
+ }
+
+ /* Check if a convex hull algorithm already exists for these 2 traces */
+ ConvexHull algo = null;
+ for (ConvexHull traceSync : fSyncs) {
+ if (traceSync.isForTraces(trace1, trace2)) {
+ algo = traceSync;
+ }
+ }
+ if (algo == null) {
+ algo = new ConvexHull(trace1, trace2);
+ fSyncs.add(algo);
+ }
+ algo.processMatch(match);
+
+ }
+
+ @Override
+ public ITmfTimestampTransform getTimestampTransform(ITmfTrace trace) {
+ return getTimestampTransform(trace.getName());
+ }
+
+ @Override
+ public ITmfTimestampTransform getTimestampTransform(String name) {
+ for (ConvexHull traceSync : fSyncs) {
+ if (traceSync.isTraceSynced(name)) {
+ /*
+ * Since there are many traces, maybe the reference trace is
+ * also synchronized, so we need to chain sync formulas
+ */
+ ITmfTimestampTransform refTt = getTimestampTransform(traceSync.getReferenceTrace());
+ return refTt.composeWith(traceSync.getTimestampTransform(name));
+ }
+ }
+ return TmfTimestampTransform.IDENTITY;
+ }
+
+ @Override
+ public SyncQuality getSynchronizationQuality(ITmfTrace trace1, ITmfTrace trace2) {
+ for (ConvexHull traceSync : fSyncs) {
+ if (traceSync.isForTraces(trace1.getName(), trace2.getName())) {
+ return traceSync.getQuality();
+ }
+ }
+ return SyncQuality.ABSENT;
+ }
+
+ @Override
+ public boolean isTraceSynced(String name) {
+ boolean traceSynced = false;
+ for (ConvexHull traceSync : fSyncs) {
+ traceSynced = traceSynced || traceSync.isTraceSynced(name);
+ }
+ return traceSynced;
+ }
+
+ /**
+ * Rename one of the traces in the synchronization
+ *
+ * @param oldname
+ * The name of the original trace
+ * @param newname
+ * The new name of the trace
+ */
+ @Override
+ public void renameTrace(String oldname, String newname) {
+ for (ConvexHull traceSync : fSyncs) {
+ traceSync.renameTrace(oldname, newname);
+ }
+ }
+
+ @Override
+ public Map<String, Map<String, Object>> getStats() {
+ Map<String, Map<String, Object>> statmap = new LinkedHashMap<String, Map<String, Object>>();
+ for (ConvexHull traceSync : fSyncs) {
+ statmap.put(traceSync.getReferenceTrace() + " <==> " + traceSync.getOtherTrace(), traceSync.getStats()); //$NON-NLS-1$
+ }
+ return statmap;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder b = new StringBuilder();
+ b.append(getClass().getSimpleName() + " "); //$NON-NLS-1$
+ b.append(fSyncs);
+ return b.toString();
+ }
+
+ /**
+ * This is the actual synchronization algorithm between two traces using
+ * convex hull
+ */
+ private class ConvexHull implements Serializable {
+
+ private static final long serialVersionUID = 8309351175030935291L;
+
+ /**
+ * The list of meaningful points on the upper hull (received by the
+ * reference trace, below in a graph)
+ */
+ private final LinkedList<SyncPoint> fUpperBoundList = new LinkedList<SyncPoint>();
+
+ /**
+ * The list of meaninful points on the lower hull (sent by the reference
+ * trace, above in a graph)
+ */
+ private final LinkedList<SyncPoint> fLowerBoundList = new LinkedList<SyncPoint>();
+
+ /** Points forming the line with maximum slope */
+ private final SyncPoint[] fLmax;
+
+ /** Points forming the line with minimum slope */
+ private final SyncPoint[] fLmin;
+
+ /**
+ * Slopes and ordinate at origin of respectively fLmin, fLmax and the
+ * bisector
+ */
+ private BigDecimal fAlphamin, fBetamax, fAlphamax, fBetamin, fAlpha, fBeta;
+
+ private int fNbMatches, fNbAccurateMatches;
+ private String fReferenceTrace = "", fOtherTrace = ""; //$NON-NLS-1$//$NON-NLS-2$
+ private SyncQuality fQuality;
+
+ private Map<String, Object> fStats = new LinkedHashMap<String, Object>();
+
+ /**
+ * Initialization of the attributes
+ *
+ * @param trace1
+ * Name of the first trace
+ * @param trace2
+ * Name of the second trace
+ */
+ public ConvexHull(String trace1, String trace2) {
+ if (trace1.compareTo(trace2) > 0) {
+ fReferenceTrace = trace2;
+ fOtherTrace = trace1;
+ } else {
+ fReferenceTrace = trace1;
+ fOtherTrace = trace2;
+ }
+ fLmax = new SyncPoint[2];
+ fLmin = new SyncPoint[2];
+ fAlpha = BigDecimal.ONE;
+ fAlphamax = BigDecimal.ONE;
+ fAlphamin = BigDecimal.ONE;
+ fBeta = BigDecimal.ZERO;
+ fBetamax = BigDecimal.ZERO;
+ fBetamin = BigDecimal.ZERO;
+ fNbMatches = 0;
+ fNbAccurateMatches = 0;
+ fQuality = SyncQuality.ABSENT;
+ }
+
+ protected void processMatch(TmfEventDependency match) {
+
+ LinkedList<SyncPoint> boundList, otherBoundList;
+
+ SyncPoint[] line, otherLine;
+ SyncPoint p;
+ int inversionFactor = 1;
+ boolean qualify = false;
+ fNbMatches++;
+
+ /* Initialize data depending on the which hull the match is part of */
+ if (match.getSourceEvent().getTrace().getName().compareTo(match.getDestinationEvent().getTrace().getName()) > 0) {
+ boundList = fUpperBoundList;
+ otherBoundList = fLowerBoundList;
+ line = fLmin;
+ otherLine = fLmax;
+ p = new SyncPoint(match.getDestinationEvent(), match.getSourceEvent());
+ inversionFactor = 1;
+ } else {
+ boundList = fLowerBoundList;
+ otherBoundList = fUpperBoundList;
+ line = fLmax;
+ otherLine = fLmin;
+ p = new SyncPoint(match.getSourceEvent(), match.getDestinationEvent());
+ inversionFactor = -1;
+ }
+
+ /*
+ * Does the message qualify for the hull, or is in on the wrong side
+ * of the reference line
+ */
+ if ((line[0] == null) || (line[1] == null) || (p.crossProduct(line[0], line[1]) * inversionFactor > 0)) {
+ /*
+ * If message qualifies, verify if points need to be removed
+ * from the hull and add the new point as the maximum reference
+ * point for the line. Also clear the stats that are not good
+ * anymore
+ */
+ fNbAccurateMatches++;
+ qualify = true;
+ removeUselessPoints(p, boundList, inversionFactor);
+ line[1] = p;
+ fStats.clear();
+ }
+
+ /*
+ * Adjust the boundary of the reference line and if one of the
+ * reference point of the other line was removed from the hull, also
+ * adjust the other line
+ */
+ adjustBound(line, otherBoundList, inversionFactor);
+ if ((otherLine[1] != null) && !boundList.contains(otherLine[0])) {
+ adjustBound(otherLine, boundList, inversionFactor * -1);
+ }
+
+ if (qualify) {
+ approximateSync();
+ }
+
+ }
+
+ /**
+ * Calculates slopes and ordinate at origin of fLmax and fLmin to obtain
+ * and approximation of the synchronization at this time
+ */
+ private void approximateSync() {
+ /**
+ * Line slopes functions
+ *
+ * Lmax = alpha_max T + beta_min
+ *
+ * Lmin = alpha_min T + beta_max
+ */
+ if ((fLmax[0] != null) || (fLmin[0] != null)) {
+ fAlphamax = fLmax[1].getAlpha(fLmax[0]);
+ fBetamin = fLmax[1].getBeta(fAlphamax);
+ fAlphamin = fLmin[1].getAlpha(fLmin[0]);
+ fBetamax = fLmin[1].getBeta(fAlphamin);
+ fAlpha = fAlphamax.add(fAlphamin).divide(BigDecimal.valueOf(2), fMc);
+ fBeta = fBetamin.add(fBetamax).divide(BigDecimal.valueOf(2), fMc);
+ if ((fLmax[0] == null) || (fLmin[0] == null)) {
+ fQuality = SyncQuality.APPROXIMATE;
+ }
+ else if (fAlphamax.compareTo(fAlphamin) > 0) {
+ fQuality = SyncQuality.ACCURATE;
+ } else {
+ /* Lines intersect, not good */
+ fQuality = SyncQuality.FAIL;
+ }
+ } else if (((fLmax[0] == null) && (fLmin[1] == null))
+ || ((fLmax[1] == null) && (fLmin[0] == null))) {
+ /* Either there is no upper hull point or no lower hull */
+ fQuality = SyncQuality.INCOMPLETE;
+ }
+ }
+
+ /*
+ * Verify if the line should be adjusted to be more accurate give the
+ * hull
+ */
+ private void adjustBound(SyncPoint[] line, LinkedList<SyncPoint> otherBoundList, int inversionFactor) {
+ SyncPoint minPoint = null, nextPoint;
+ boolean finishedSearch = false;
+
+ /*
+ * Find in the other bound, the origin point of the line, start from
+ * the beginning if the point was lost
+ */
+ int i = Math.max(0, otherBoundList.indexOf(line[0]));
+
+ while ((i < otherBoundList.size() - 1) && !finishedSearch) {
+ minPoint = otherBoundList.get(i);
+ nextPoint = otherBoundList.get(i + 1);
+
+ /*
+ * If the rotation (cross-product) is not optimal, move to next
+ * point as reference for the line (if available)
+ *
+ * Otherwise, the current minPoint is the minPoint of the line
+ */
+ if (minPoint.crossProduct(nextPoint, line[1]) * inversionFactor > 0) {
+ if (nextPoint.getTimeX() < line[1].getTimeX()) {
+ i++;
+ } else {
+ line[0] = null;
+ finishedSearch = true;
+ }
+ } else {
+ line[0] = minPoint;
+ finishedSearch = true;
+ }
+ }
+
+ if (line[0] == null) {
+ line[0] = minPoint;
+ }
+
+ /* Make sure point 0 is before point 1 */
+ if ((line[0] != null) && (line[0].getTimeX() > line[1].getTimeX())) {
+ line[0] = null;
+ }
+ }
+
+ /*
+ * When a point qualifies to be in a hull, we verify if any of the
+ * existing points need to be removed from the hull
+ */
+ private void removeUselessPoints(final SyncPoint p, final LinkedList<SyncPoint> boundList, final int inversionFactor) {
+
+ boolean checkRemove = true;
+
+ while (checkRemove && boundList.size() >= 2) {
+ if (p.crossProduct(boundList.get(boundList.size() - 2), boundList.getLast()) * inversionFactor > 0) {
+ boundList.removeLast();
+ } else {
+ checkRemove = false;
+ }
+ }
+ boundList.addLast(p);
+ }
+
+ public ITmfTimestampTransform getTimestampTransform(String name) {
+ if (name.equals(fOtherTrace) && (fQuality == SyncQuality.ACCURATE || fQuality == SyncQuality.APPROXIMATE || fQuality == SyncQuality.FAIL)) {
+ /* alpha: beta => 1 / fAlpha, -1 * fBeta / fAlpha); */
+ return new TmfTimestampTransformLinear(BigDecimal.ONE.divide(fAlpha, fMc), BigDecimal.valueOf(-1).multiply(fBeta).divide(fAlpha, fMc));
+ }
+ return TmfTimestampTransform.IDENTITY;
+ }
+
+ public SyncQuality getQuality() {
+ return fQuality;
+ }
+
+ public Map<String, Object> getStats() {
+ if (fStats.size() == 0) {
+ String syncQuality;
+ switch (fQuality) {
+ case ABSENT:
+ syncQuality = Messages.SyncAlgorithmFullyIncremental_absent;
+ break;
+ case ACCURATE:
+ syncQuality = Messages.SyncAlgorithmFullyIncremental_accurate;
+ break;
+ case APPROXIMATE:
+ syncQuality = Messages.SyncAlgorithmFullyIncremental_approx;
+ break;
+ case INCOMPLETE:
+ syncQuality = Messages.SyncAlgorithmFullyIncremental_incomplete;
+ break;
+ case FAIL:
+ default:
+ syncQuality = Messages.SyncAlgorithmFullyIncremental_fail;
+ break;
+ }
+
+ fStats.put(Messages.SyncAlgorithmFullyIncremental_reftrace, fReferenceTrace);
+ fStats.put(Messages.SyncAlgorithmFullyIncremental_othertrace, fOtherTrace);
+ fStats.put(Messages.SyncAlgorithmFullyIncremental_quality, syncQuality);
+ fStats.put(Messages.SyncAlgorithmFullyIncremental_alpha, fAlpha);
+ fStats.put(Messages.SyncAlgorithmFullyIncremental_beta, fBeta);
+ fStats.put(Messages.SyncAlgorithmFullyIncremental_ub, (fUpperBoundList.size() == 0) ? Messages.SyncAlgorithmFullyIncremental_NA : fUpperBoundList.size());
+ fStats.put(Messages.SyncAlgorithmFullyIncremental_lb, (fLowerBoundList.size() == 0) ? Messages.SyncAlgorithmFullyIncremental_NA : fLowerBoundList.size());
+ fStats.put(Messages.SyncAlgorithmFullyIncremental_accuracy, fAlphamax.subtract(fAlphamin).doubleValue()); // -
+ // fAlphamin);
+ fStats.put(Messages.SyncAlgorithmFullyIncremental_nbmatch, (fNbMatches == 0) ? Messages.SyncAlgorithmFullyIncremental_NA : fNbMatches);
+ fStats.put(Messages.SyncAlgorithmFullyIncremental_nbacc, (fNbAccurateMatches == 0) ? Messages.SyncAlgorithmFullyIncremental_NA : fNbAccurateMatches);
+ fStats.put(Messages.SyncAlgorithmFullyIncremental_refformula, Messages.SyncAlgorithmFullyIncremental_T_ + fReferenceTrace);
+ fStats.put(Messages.SyncAlgorithmFullyIncremental_otherformula, fAlpha + Messages.SyncAlgorithmFullyIncremental_mult + Messages.SyncAlgorithmFullyIncremental_T_ + fReferenceTrace + Messages.SyncAlgorithmFullyIncremental_add + fBeta);
+ }
+ return fStats;
+
+ }
+
+ public String getReferenceTrace() {
+ return fReferenceTrace;
+ }
+
+ public String getOtherTrace() {
+ return fOtherTrace;
+ }
+
+ public boolean isTraceSynced(String name) {
+ /* Returns true if the timestamp transform is not identity */
+ return (name.equals(fOtherTrace) && (fQuality == SyncQuality.ACCURATE || fQuality == SyncQuality.APPROXIMATE || fQuality == SyncQuality.FAIL));
+ }
+
+ public boolean isForTraces(String trace1, String trace2) {
+ return ((fReferenceTrace.equals(trace1) && fOtherTrace.equals(trace2)) || (fReferenceTrace.equals(trace2) && fOtherTrace.equals(trace1)));
+ }
+
+ public void renameTrace(String oldname, String newname) {
+ if (oldname.equals(fOtherTrace)) {
+ fOtherTrace = newname;
+ } else if (oldname.equals(fReferenceTrace)) {
+ fReferenceTrace = newname;
+ }
+ }
+
+ private void writeObject(ObjectOutputStream s)
+ throws IOException {
+ /*
+ * Remove calculation data because most of it is not serializable.
+ * We have the statistics anyway
+ */
+ fUpperBoundList.clear();
+ fLowerBoundList.clear();
+ fLmin[0] = null;
+ fLmin[1] = null;
+ fLmax[0] = null;
+ fLmax[1] = null;
+ s.defaultWriteObject();
+
+ }
+
+ @SuppressWarnings("nls")
+ @Override
+ public String toString() {
+ StringBuilder b = new StringBuilder();
+ b.append("Between " + fReferenceTrace + " and " + fOtherTrace + " [");
+ b.append(" alpha " + fAlpha + " beta " + fBeta + " ]");
+ return b.toString();
+ }
+ }
+
+ /**
+ * Private class representing a point to synchronize on a graph. The x axis
+ * is the timestamp of the event from the reference trace while the y axis
+ * is the timestamp of the event on the other trace
+ */
+ private class SyncPoint {
+ private final ITmfTimestamp x, y;
+
+ public SyncPoint(ITmfEvent ex, ITmfEvent ey) {
+ x = ex.getTimestamp();
+ y = ey.getTimestamp();
+ }
+
+ public long getTimeX() {
+ return x.getValue();
+ }
+
+ /**
+ * Calculate a cross product of 3 points:
+ *
+ * If the cross-product < 0, then p, pa, pb are clockwise
+ *
+ * If the cross-product > 0, then p, pa, pb are counter-clockwise
+ *
+ * If cross-product == 0, then they are in a line
+ *
+ * @param pa
+ * First point
+ * @param pb
+ * Second point
+ * @return The cross product
+ */
+ public long crossProduct(SyncPoint pa, SyncPoint pb) {
+ long cp = ((pa.x.getValue() - x.getValue()) * (pb.y.getValue() - y.getValue()) - (pa.y.getValue() - y.getValue()) * (pb.x.getValue() - x.getValue()));
+ return cp;
+ }
+
+ /*
+ * Gets the alpha (slope) between two points
+ */
+ public BigDecimal getAlpha(SyncPoint p1) {
+ if (p1 == null) {
+ return BigDecimal.ONE;
+ }
+ BigDecimal deltay = BigDecimal.valueOf(y.getValue() - p1.y.getValue());
+ BigDecimal deltax = BigDecimal.valueOf(x.getValue() - p1.x.getValue());
+ if (deltax.equals(BigDecimal.ZERO)) {
+ return BigDecimal.ONE;
+ }
+ return deltay.divide(deltax, fMc);
+ }
+
+ /*
+ * Get the beta value (when x = 0) of the line given alpha
+ */
+ public BigDecimal getBeta(BigDecimal alpha) {
+ return BigDecimal.valueOf(y.getValue()).subtract(alpha.multiply(BigDecimal.valueOf(x.getValue()), fMc));
+ }
+
+ }
+
+}
diff --git a/lttng/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/synchronization/SynchronizationAlgorithm.java b/lttng/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/synchronization/SynchronizationAlgorithm.java
new file mode 100644
index 0000000..d744bcf
--- /dev/null
+++ b/lttng/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/synchronization/SynchronizationAlgorithm.java
@@ -0,0 +1,135 @@
+/*******************************************************************************
+ * Copyright (c) 2013 É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 implementation and API
+ *******************************************************************************/
+
+package org.eclipse.linuxtools.tmf.core.synchronization;
+
+import java.io.Serializable;
+import java.util.Map;
+
+import org.eclipse.linuxtools.tmf.core.event.matching.TmfEventDependency;
+import org.eclipse.linuxtools.tmf.core.event.matching.TmfEventMatches;
+import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace;
+
+/**
+ * Abstract class for synchronization algorithm
+ *
+ * @author Geneviève Bastien
+ * @since 3.0
+ */
+public abstract class SynchronizationAlgorithm extends TmfEventMatches implements Serializable {
+
+ private static final long serialVersionUID = -3083906749528872196L;
+
+ /**
+ * Quality of the result obtained by the synchronization algorithm
+ */
+ public enum SyncQuality {
+ /**
+ * Algorithm returned a result satisfying all hypothesis for the
+ * algorithm
+ */
+ ACCURATE,
+ /**
+ * Best effort of the algorithm
+ */
+ APPROXIMATE,
+ /**
+ * There is communication only in one direction
+ */
+ INCOMPLETE,
+ /**
+ * No communication between two traces
+ */
+ ABSENT,
+ /**
+ * Hypothesis of the algorithm are not satisfied for some reason
+ */
+ FAIL
+ }
+
+ @Override
+ public void addMatch(TmfEventDependency match) {
+ super.addMatch(match);
+ processMatch(match);
+ }
+
+ /**
+ * Function for synchronization algorithm to do something with the received
+ * match
+ *
+ * @param match
+ * The match of events
+ */
+ protected abstract void processMatch(TmfEventDependency match);
+
+ /**
+ * Returns a map of staticstics relating to this algorithm. Those stats
+ * could be used to be displayed in a view for example.
+ *
+ * @return A map of statistics for this algorithm
+ */
+ public abstract Map<String, Map<String, Object>> getStats();
+
+ /**
+ * Returns a timestamp transformation algorithm
+ *
+ * @param trace
+ * The trace to get the transform for
+ * @return The timestamp transformation formula
+ */
+ public abstract ITmfTimestampTransform getTimestampTransform(ITmfTrace trace);
+
+ /**
+ * Returns a timestamp transformation algorithm
+ *
+ * @param name
+ * The name of the trace to get the transform for
+ * @return The timestamp transformation formula
+ */
+ public abstract ITmfTimestampTransform getTimestampTransform(String name);
+
+ /**
+ * Gets the quality of the synchronization between two given traces
+ *
+ * @param trace1
+ * First trace
+ * @param trace2
+ * Second trace
+ * @return The synchronization quality
+ */
+ public abstract SyncQuality getSynchronizationQuality(ITmfTrace trace1, ITmfTrace trace2);
+
+ /**
+ * Returns whether a given trace has a synchronization formula that is not
+ * identity. This function returns true if the synchronization algorithm has
+ * failed for some reason
+ *
+ * @param name
+ * The name of the trace
+ * @return true if trace has formula
+ */
+ public abstract boolean isTraceSynced(String name);
+
+ /**
+ * Rename a trace involved in this algorithm. This function is necessary
+ * because after synchronization, the trace whose timestamp changes is
+ * copied with a new name and the synchronization needs to keep track of the
+ * new name.
+ *
+ * @param oldname
+ * Original name of the trace
+ * @param newname
+ * New name of the trace
+ */
+ public abstract void renameTrace(String oldname, String newname);
+
+}
diff --git a/lttng/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/synchronization/SynchronizationBackend.java b/lttng/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/synchronization/SynchronizationBackend.java
new file mode 100644
index 0000000..1950b3a
--- /dev/null
+++ b/lttng/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/synchronization/SynchronizationBackend.java
@@ -0,0 +1,219 @@
+/*******************************************************************************
+ * Copyright (c) 2013 É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 implementation and API
+ *******************************************************************************/
+
+package org.eclipse.linuxtools.tmf.core.synchronization;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.nio.ByteBuffer;
+import java.nio.channels.FileChannel;
+
+import org.eclipse.linuxtools.internal.tmf.core.Activator;
+
+/**
+ * Class to fetch and save synchronization information between traces
+ *
+ * @author Geneviève Bastien
+ * @since 3.0
+ */
+public class SynchronizationBackend {
+
+ private static final int SYNC_FILE_MAGIC_NUMBER = 0x0DECAF00;
+
+ private static final int FILE_VERSION = 1;
+
+ private static final int HEADER_SIZE = 20;
+
+ private final File fSyncFile;
+
+ /**
+ * Constructor
+ *
+ * @param syncFile
+ * The file containing synchronization information
+ * @throws IOException
+ * If the file couldn't be opened for some reason
+ */
+ public SynchronizationBackend(File syncFile) throws IOException {
+ this(syncFile, true);
+ }
+
+ /**
+ * Constructor with possibility to tell whether to throw errors on exception
+ * or not
+ *
+ * @param syncFile
+ * The file containing synchronization information
+ * @param throwErrors
+ * Whether to throw exceptions or not
+ * @throws IOException
+ * If the file couldn't be opened for some reason
+ */
+ public SynchronizationBackend(File syncFile, boolean throwErrors) throws IOException {
+ /*
+ * Open the file ourselves, get the header information we need, then
+ * pass on the descriptor.
+ */
+ int res;
+
+ fSyncFile = syncFile;
+
+ if (syncFile == null) {
+ return;
+ }
+
+ if (!syncFile.exists()) {
+ if (throwErrors) {
+ throw new IOException("Selected synchronization file does not exist"); //$NON-NLS-1$
+ }
+ return;
+ }
+ if (syncFile.length() <= 0) {
+ if (throwErrors) {
+ throw new IOException("Invalid synchronization file selected, " + //$NON-NLS-1$
+ "target file is empty"); //$NON-NLS-1$
+ }
+ return;
+ }
+
+ FileInputStream fis = new FileInputStream(syncFile);
+ ByteBuffer buffer = ByteBuffer.allocate(HEADER_SIZE);
+ FileChannel fc = fis.getChannel();
+ buffer.clear();
+ fc.read(buffer);
+ buffer.flip();
+
+ /*
+ * Check the magic number,to make sure we're opening the right type of
+ * file
+ */
+ res = buffer.getInt();
+ if (res != SYNC_FILE_MAGIC_NUMBER) {
+ fc.close();
+ fis.close();
+ throw new IOException("Selected file does not" + //$NON-NLS-1$
+ "look like a synchronization file"); //$NON-NLS-1$
+ }
+
+ res = buffer.getInt(); /* Major version number */
+ if (res != FILE_VERSION) {
+ fc.close();
+ fis.close();
+ throw new IOException("Select synchronization file is of an older " //$NON-NLS-1$
+ + "format. Synchronization will have to be computed again."); //$NON-NLS-1$
+ }
+
+ res = buffer.getInt(); /* Minor version number */
+
+ fc.close();
+ fis.close();
+ }
+
+ /**
+ * Opens an existing synchronization file
+ *
+ * @return The synchronization algorithm contained in the file
+ * @throws IOException
+ * Exception returned file functions
+ */
+ public SynchronizationAlgorithm openExistingSync() throws IOException {
+
+ if (fSyncFile == null) {
+ return null;
+ }
+
+ /* Set the position after the header */
+ FileInputStream fis = new FileInputStream(fSyncFile);
+ FileChannel fc = fis.getChannel().position(HEADER_SIZE);
+
+ /* Read the input stream */
+ ObjectInputStream ois = new ObjectInputStream(fis);
+ SyncAlgorithmFullyIncremental syncAlgo = null;
+ try {
+ syncAlgo = (SyncAlgorithmFullyIncremental) ois.readObject();
+ } catch (ClassNotFoundException e) {
+
+ }
+ ois.close();
+ fc.close();
+
+ fis.close();
+
+ return syncAlgo;
+ }
+
+ /**
+ * Saves the synchronization algorithm object to file
+ *
+ * @param syncAlgo
+ * The algorithm to save
+ * @throws FileNotFoundException
+ * propagate callee's exceptions
+ */
+ public void saveSync(SynchronizationAlgorithm syncAlgo) throws FileNotFoundException {
+
+ if (fSyncFile == null) {
+ return;
+ }
+
+ FileChannel fc;
+ FileOutputStream fos;
+ ObjectOutputStream oos;
+ ByteBuffer buffer;
+ int res;
+
+ fos = new FileOutputStream(fSyncFile, false);
+ fc = fos.getChannel();
+
+ buffer = ByteBuffer.allocate(HEADER_SIZE);
+ buffer.clear();
+
+ /* Save the header of the file */
+ try {
+ fc.position(0);
+
+ buffer.putInt(SYNC_FILE_MAGIC_NUMBER);
+
+ buffer.putInt(FILE_VERSION);
+
+ buffer.flip();
+ res = fc.write(buffer);
+ assert (res <= HEADER_SIZE);
+ /* done writing the file header */
+
+ fc.position(HEADER_SIZE);
+
+ oos = new ObjectOutputStream(fos);
+ oos.writeObject(syncAlgo);
+ oos.close();
+
+ } catch (IOException e) {
+ /* We should not have any problems at this point... */
+ Activator.logError("Error saving trace synchronization data", e); //$NON-NLS-1$
+ } finally {
+ try {
+ fc.close();
+ fos.close();
+ } catch (IOException e) {
+ Activator.logError("Error closing synchronization file", e); //$NON-NLS-1$
+ }
+ }
+ return;
+
+ }
+
+}
diff --git a/lttng/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/synchronization/SynchronizationManager.java b/lttng/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/synchronization/SynchronizationManager.java
new file mode 100644
index 0000000..fac5133
--- /dev/null
+++ b/lttng/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/synchronization/SynchronizationManager.java
@@ -0,0 +1,133 @@
+/*******************************************************************************
+ * Copyright (c) 2013 É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 implementation and API
+ *******************************************************************************/
+
+package org.eclipse.linuxtools.tmf.core.synchronization;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.eclipse.linuxtools.internal.tmf.core.Activator;
+import org.eclipse.linuxtools.tmf.core.component.TmfComponent;
+import org.eclipse.linuxtools.tmf.core.event.matching.ITmfEventMatching;
+import org.eclipse.linuxtools.tmf.core.event.matching.TmfNetworkEventMatching;
+import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace;
+
+/**
+ * This abstract manager class handles loading trace synchronization data or
+ * otherwise their calculation.
+ *
+ * @author Geneviève Bastien
+ * @since 3.0
+ */
+public abstract class SynchronizationManager extends TmfComponent {
+
+ /**
+ * Function called to synchronize traces using the fully incremental
+ * synchronization algorithm
+ *
+ * @param syncFile
+ * The target name of the synchronization file. If it exists, it
+ * will be opened, otherwise it will be created and data from
+ * this synchro run will be saved there
+ * @param traces
+ * The list of traces to synchronize
+ * @param doSync
+ * Whether to actually synchronize or just try opening a sync
+ * file
+ * @return The synchronization object
+ */
+ public static SynchronizationAlgorithm synchronizeTraces(final File syncFile, final ITmfTrace[] traces, boolean doSync) {
+
+ SynchronizationAlgorithm syncAlgo;
+ if (doSync) {
+ syncAlgo = synchronize(syncFile, traces, new SyncAlgorithmFullyIncremental());
+ } else {
+ syncAlgo = openExisting(syncFile);
+ if (syncAlgo == null) {
+ syncAlgo = new SyncAlgorithmFullyIncremental();
+ }
+ }
+ return syncAlgo;
+ }
+
+ /**
+ * Function called to synchronize traces with a specific synchronization
+ * algorithm. If a synchronization already exists, but is not the requested
+ * algorithm, the synchronization is done again using the new algorithm
+ *
+ * @param syncFile
+ * The target name of the synchronization file. If it exists, it
+ * will be opened, otherwise it will be created and data from
+ * this synchro run will be saved there
+ * @param traces
+ * The list of traces to synchronize
+ * @param algo
+ * A synchronization algorithm object to determine the algorithm
+ * used to synchronization.
+ * @param doSync
+ * Whether to actually synchronize or just try opening a sync
+ * file
+ * @return The synchronization object
+ */
+ public static SynchronizationAlgorithm synchronizeTraces(final File syncFile, final ITmfTrace[] traces, SynchronizationAlgorithm algo, boolean doSync) {
+
+ SynchronizationAlgorithm syncAlgo;
+ if (doSync) {
+ syncAlgo = synchronize(syncFile, traces, algo);
+ } else {
+ syncAlgo = openExisting(syncFile);
+ if (syncAlgo == null || (syncAlgo.getClass() != algo.getClass())) {
+ if (algo != null) {
+ syncAlgo = algo;
+ } else {
+ syncAlgo = new SyncAlgorithmFullyIncremental();
+ }
+ }
+ }
+
+ return syncAlgo;
+ }
+
+ private static SynchronizationAlgorithm openExisting(final File syncFile) {
+ if ((syncFile != null) && syncFile.exists()) {
+ /* Load an existing history */
+ try {
+ SynchronizationBackend syncBackend = new SynchronizationBackend(syncFile);
+ SynchronizationAlgorithm algo = syncBackend.openExistingSync();
+ return algo;
+ } 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.
+ */
+ Activator.logInfo("Problem opening existing trace synchronization file", e); //$NON-NLS-1$
+ }
+ }
+ return null;
+ }
+
+ private static SynchronizationAlgorithm synchronize(final File syncFile, final ITmfTrace[] traces, SynchronizationAlgorithm syncAlgo) {
+ ITmfEventMatching matching = new TmfNetworkEventMatching(traces, syncAlgo);
+ matching.matchEvents();
+
+ SynchronizationBackend syncBackend;
+ try {
+ syncBackend = new SynchronizationBackend(syncFile, false);
+ syncBackend.saveSync(syncAlgo);
+ } catch (IOException e) {
+ Activator.logError("Error while saving trace synchronization file", e); //$NON-NLS-1$
+ }
+ return syncAlgo;
+ }
+
+}
diff --git a/lttng/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/synchronization/TmfTimestampTransform.java b/lttng/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/synchronization/TmfTimestampTransform.java
new file mode 100644
index 0000000..73ce661
--- /dev/null
+++ b/lttng/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/synchronization/TmfTimestampTransform.java
@@ -0,0 +1,79 @@
+/*******************************************************************************
+ * Copyright (c) 2013 É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 implementation and API
+ *******************************************************************************/
+
+package org.eclipse.linuxtools.tmf.core.synchronization;
+
+import java.io.Serializable;
+
+import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp;
+
+/**
+ * A default simple, identity timestamp transform. It is a singleton class and
+ * returns the timestamp itself
+ *
+ * @author Geneviève Bastien
+ * @since 3.0
+ */
+public class TmfTimestampTransform implements ITmfTimestampTransform, Serializable {
+
+ /**
+ * Generated serial UID
+ */
+ private static final long serialVersionUID = -1480581417493073304L;
+
+ /**
+ * The unique instance of this transform, since it is always the same
+ */
+ public static final TmfTimestampTransform IDENTITY = new TmfTimestampTransform();
+
+ /**
+ * Default constructor
+ */
+ protected TmfTimestampTransform() {
+
+ }
+
+ @Override
+ public ITmfTimestamp transform(ITmfTimestamp timestamp) {
+ return timestamp;
+ }
+
+ @Override
+ public long transform(long timestamp) {
+ return timestamp;
+ }
+
+ @Override
+ public ITmfTimestampTransform composeWith(ITmfTimestampTransform composeWith) {
+ /* Since this transform will not modify anything, return the other */
+ return composeWith;
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ return other.getClass().equals(TmfTimestampTransform.class);
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = (prime * result) + TmfTimestampTransform.class.hashCode();
+ return result;
+ }
+
+ @Override
+ public String toString() {
+ return "TmfTimestampTransform [ IDENTITY ]"; //$NON-NLS-1$
+ }
+
+}
diff --git a/lttng/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/synchronization/TmfTimestampTransformLinear.java b/lttng/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/synchronization/TmfTimestampTransformLinear.java
new file mode 100644
index 0000000..1a20ea2
--- /dev/null
+++ b/lttng/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/synchronization/TmfTimestampTransformLinear.java
@@ -0,0 +1,148 @@
+/*******************************************************************************
+ * Copyright (c) 2013 É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 implementation and API
+ *******************************************************************************/
+
+package org.eclipse.linuxtools.tmf.core.synchronization;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.math.MathContext;
+
+import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp;
+import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimestamp;
+
+/**
+ * Class implementing a linear timestamp transform, with a slope and/or offset
+ *
+ * f(t) = alpha*t + beta
+ *
+ * @author Geneviève Bastien
+ * @since 3.0
+ */
+public class TmfTimestampTransformLinear implements ITmfTimestampTransform, Serializable {
+
+ /**
+ * Generated serial UID
+ */
+ private static final long serialVersionUID = -4756608071358979461L;
+
+ /**
+ * Respectively the slope and offset and this linear equation.
+ *
+ * FIXME: Maybe doubles will be enough, for the whole synchronization
+ * package as well, I think BigDecimal is a remnant of past trials and
+ * errors
+ */
+ private final BigDecimal fAlpha;
+ private final BigDecimal fBeta;
+
+ private static final MathContext fMc = MathContext.DECIMAL128;
+
+ /**
+ * Default constructor
+ */
+ public TmfTimestampTransformLinear() {
+ fAlpha = BigDecimal.ONE;
+ fBeta = BigDecimal.ZERO;
+ }
+
+ /**
+ * Constructor with alpha and beta
+ *
+ * @param alpha
+ * The slope of the linear transform
+ * @param beta
+ * The initial offset of the linear transform
+ */
+ public TmfTimestampTransformLinear(final double alpha, final double beta) {
+ fAlpha = BigDecimal.valueOf(alpha);
+ fBeta = BigDecimal.valueOf(beta);
+ }
+
+ /**
+ * Constructor with alpha and beta in big decimal
+ *
+ * @param fAlpha2
+ * The slope of the linear transform
+ * @param fBeta2
+ * The initial offset of the linear transform
+ */
+ public TmfTimestampTransformLinear(final BigDecimal fAlpha2, final BigDecimal fBeta2) {
+ if (fAlpha2 != null) {
+ fAlpha = fAlpha2;
+ } else {
+ fAlpha = BigDecimal.ONE;
+ }
+ if (fBeta2 != null) {
+ fBeta = fBeta2;
+ } else {
+ fBeta = BigDecimal.ZERO;
+ }
+ }
+
+ @Override
+ public ITmfTimestamp transform(ITmfTimestamp timestamp) {
+ BigDecimal newvalue = BigDecimal.valueOf(timestamp.getValue()).multiply(fAlpha, fMc).add(fBeta);
+ return new TmfTimestamp(timestamp, newvalue.longValue());
+ }
+
+ @Override
+ public long transform(long timestamp) {
+ BigDecimal t = BigDecimal.valueOf(timestamp).multiply(fAlpha, fMc).add(fBeta);
+ return t.longValue();
+ }
+
+ @Override
+ public ITmfTimestampTransform composeWith(ITmfTimestampTransform composeWith) {
+ if (composeWith.equals(TmfTimestampTransform.IDENTITY)) {
+ /* If composing with identity, just return this */
+ return this;
+ } else if (composeWith instanceof TmfTimestampTransformLinear) {
+ /* If composeWith is a linear transform, add the two together */
+ TmfTimestampTransformLinear ttl = (TmfTimestampTransformLinear) composeWith;
+ BigDecimal newAlpha = fAlpha.multiply(ttl.fAlpha, fMc);
+ BigDecimal newBeta = fAlpha.multiply(ttl.fBeta, fMc).add(fBeta);
+ return new TmfTimestampTransformLinear(newAlpha, newBeta);
+ } else {
+ /*
+ * We do not know what to do with this kind of transform, just
+ * return this
+ */
+ return this;
+ }
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ boolean result = false;
+ if (other instanceof TmfTimestampTransformLinear) {
+ TmfTimestampTransformLinear that = (TmfTimestampTransformLinear) other;
+ result = ((that.fAlpha.equals(fAlpha)) && (that.fBeta.equals(fBeta)));
+ }
+ return result;
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = (prime * result) + (fBeta.multiply(fAlpha).intValue());
+ return result;
+ }
+
+ @Override
+ public String toString() {
+ return "TmfTimestampLinear [ alpha = " + fAlpha.toString() + //$NON-NLS-1$
+ ", beta = " + fBeta.toString() + //$NON-NLS-1$
+ " ]"; //$NON-NLS-1$
+ }
+
+}
diff --git a/lttng/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/synchronization/messages.properties b/lttng/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/synchronization/messages.properties
new file mode 100644
index 0000000..fb5cd46
--- /dev/null
+++ b/lttng/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/synchronization/messages.properties
@@ -0,0 +1,21 @@
+SyncAlgorithmFullyIncremental_absent=Absent
+SyncAlgorithmFullyIncremental_alpha=Alpha
+SyncAlgorithmFullyIncremental_beta=Beta
+SyncAlgorithmFullyIncremental_T_=T_
+SyncAlgorithmFullyIncremental_otherformula=C_T1(t)
+SyncAlgorithmFullyIncremental_mult=*
+SyncAlgorithmFullyIncremental_add=\ +
+SyncAlgorithmFullyIncremental_ub=Number of points in upper hull
+SyncAlgorithmFullyIncremental_lb=Number of points in lower hull
+SyncAlgorithmFullyIncremental_accuracy=Accuracy
+SyncAlgorithmFullyIncremental_accurate=Accurate
+SyncAlgorithmFullyIncremental_approx=Approximate
+SyncAlgorithmFullyIncremental_fail=Fail
+SyncAlgorithmFullyIncremental_incomplete=Incomplete
+SyncAlgorithmFullyIncremental_nbmatch=Number of matching packets received
+SyncAlgorithmFullyIncremental_nbacc=Number of accurate packets
+SyncAlgorithmFullyIncremental_reftrace=T0
+SyncAlgorithmFullyIncremental_othertrace=T1
+SyncAlgorithmFullyIncremental_refformula=C_T0(t)
+SyncAlgorithmFullyIncremental_NA=N/A
+SyncAlgorithmFullyIncremental_quality=Quality \ No newline at end of file
diff --git a/lttng/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/timestamp/TmfTimestamp.java b/lttng/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/timestamp/TmfTimestamp.java
index 13ee08a..7fbe99c 100644
--- a/lttng/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/timestamp/TmfTimestamp.java
+++ b/lttng/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/timestamp/TmfTimestamp.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2009, 2013 Ericsson
+ * Copyright (c) 2009, 2013 Ericsson, É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
@@ -11,6 +11,7 @@
* Thomas Gatterweh - Updated scaling / synchronization
* Francois Chouinard - Refactoring to align with TMF Event Model 1.0
* Francois Chouinard - Implement augmented interface
+ * Geneviève Bastien - Added copy constructor with new value
*******************************************************************************/
package org.eclipse.linuxtools.tmf.core.timestamp;
@@ -134,6 +135,24 @@ public class TmfTimestamp implements ITmfTimestamp {
fPrecision = timestamp.getPrecision();
}
+ /**
+ * Copies a timestamp but with a new time value
+ *
+ * @param timestamp
+ * The timestamp to copy
+ * @param newvalue
+ * The value the new timestamp will have
+ * @since 3.0
+ */
+ public TmfTimestamp(ITmfTimestamp timestamp, long newvalue) {
+ if (timestamp == null) {
+ throw new IllegalArgumentException();
+ }
+ fValue = newvalue;
+ fScale = timestamp.getScale();
+ fPrecision = timestamp.getPrecision();
+ }
+
// ------------------------------------------------------------------------
// ITmfTimestamp
// ------------------------------------------------------------------------
diff --git a/lttng/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/ITmfTrace.java b/lttng/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/ITmfTrace.java
index 6abe837..b0f0a38 100644
--- a/lttng/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/ITmfTrace.java
+++ b/lttng/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/ITmfTrace.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2009, 2013 Ericsson
+ * Copyright (c) 2009, 2013 Ericsson, É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
@@ -9,6 +9,8 @@
* Contributors:
* Francois Chouinard - Initial API and implementation
* Francois Chouinard - Updated as per TMF Trace Model 1.0
+ * Geneviève Bastien - Added timestamp transforms and timestamp
+ * creation functions
*******************************************************************************/
package org.eclipse.linuxtools.tmf.core.trace;
@@ -24,6 +26,7 @@ import org.eclipse.linuxtools.tmf.core.event.ITmfEvent;
import org.eclipse.linuxtools.tmf.core.exceptions.TmfTraceException;
import org.eclipse.linuxtools.tmf.core.statesystem.ITmfStateSystem;
import org.eclipse.linuxtools.tmf.core.statistics.ITmfStatistics;
+import org.eclipse.linuxtools.tmf.core.synchronization.ITmfTimestampTransform;
import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp;
import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimeRange;
import org.eclipse.linuxtools.tmf.core.trace.indexer.ITmfTraceIndexer;
@@ -39,9 +42,9 @@ import org.eclipse.linuxtools.tmf.core.trace.location.ITmfLocation;
* <li> the time range (span) of the events it contains
* </ul>
* Concrete ITmfTrace classes have to provide a parameter-less constructor and
- * an initialization method (<i>initTrace</i>) if they are to be opened from
- * the Project View. Also, a validation method (<i>validate</i>) has to be
- * provided to ensure that the trace is of the correct type.
+ * an initialization method (<i>initTrace</i>) if they are to be opened from the
+ * Project View. Also, a validation method (<i>validate</i>) has to be provided
+ * to ensure that the trace is of the correct type.
* <p>
* A trace can be accessed simultaneously from multiple threads by various
* application components. To avoid obvious multi-threading issues, the trace
@@ -82,19 +85,22 @@ import org.eclipse.linuxtools.tmf.core.trace.location.ITmfLocation;
* event = trace.getNext(context);
* }
* </pre>
+ *
* A trace is also an event provider so it can process event requests
* asynchronously (and coalesce compatible, concurrent requests).
* <p>
- * </pre>
- * <b>Example 4</b>: Process a whole trace (see ITmfEventRequest for variants)
+ *
+ * <b>Example 4</b>: Process a whole trace (see ITmfEventRequest for
+ * variants)
* <pre>
* ITmfRequest request = new TmfEventRequest&lt;MyEventType&gt;(MyEventType.class) {
- * &#64;Override
+ * &#064;Override
* public void handleData(MyEventType event) {
* super.handleData(event);
* processEvent(event);
* }
- * &#64;Override
+ *
+ * &#064;Override
* public void handleCompleted() {
* finish();
* super.handleCompleted();
@@ -135,23 +141,29 @@ public interface ITmfTrace extends ITmfDataProvider {
* properly parameterize an ITmfTrace instantiated with its parameterless
* constructor.
* <p>
- * Typically, the parameterless constructor will provide the block size
- * and its associated parser and indexer.
+ * Typically, the parameterless constructor will provide the block size and
+ * its associated parser and indexer.
*
- * @param resource the trace resource
- * @param path the trace path
- * @param type the trace event type
- * @throws TmfTraceException If we couldn't open the trace
+ * @param resource
+ * the trace resource
+ * @param path
+ * the trace path
+ * @param type
+ * the trace event type
+ * @throws TmfTraceException
+ * If we couldn't open the trace
*/
void initTrace(IResource resource, String path, Class<? extends ITmfEvent> type) throws TmfTraceException;
/**
* Validate that the trace is of the correct type.
*
- * @param project the eclipse project
- * @param path the trace path
- *
- * @return an IStatus object with validation result. Use severity OK to indicate success.
+ * @param project
+ * the eclipse project
+ * @param path
+ * the trace path
+ * @return an IStatus object with validation result. Use severity OK to
+ * indicate success.
* @since 2.0
*/
IStatus validate(IProject project, String path);
@@ -268,7 +280,8 @@ public interface ITmfTrace extends ITmfDataProvider {
/**
* Returns the ratio (proportion) corresponding to the specified location.
*
- * @param location a trace specific location
+ * @param location
+ * a trace specific location
* @return a floating-point number between 0.0 (beginning) and 1.0 (end)
* @since 3.0
*/
@@ -287,7 +300,9 @@ public interface ITmfTrace extends ITmfDataProvider {
* If not null, the location requested must be valid otherwise the returned
* context is undefined (up to the implementation to recover if possible).
* <p>
- * @param location the trace specific location
+ *
+ * @param location
+ * the trace specific location
* @return a context which can later be used to read the corresponding event
* @since 3.0
*/
@@ -296,21 +311,21 @@ public interface ITmfTrace extends ITmfDataProvider {
/**
* Position the trace at the 'rank'th event in the trace.
* <p>
- * A rank <= 0 is interpreted as seeking for the first event of the
- * trace.
+ * A rank <= 0 is interpreted as seeking for the first event of the trace.
* <p>
* If the requested rank is beyond the last trace event, the context
* returned will yield a null event if used in a subsequent read.
*
- * @param rank the event rank
+ * @param rank
+ * the event rank
* @return a context which can later be used to read the corresponding event
*/
ITmfContext seekEvent(long rank);
/**
* Position the trace at the first event with the specified timestamp. If
- * there is no event with the requested timestamp, a context pointing to
- * the next chronological event is returned.
+ * there is no event with the requested timestamp, a context pointing to the
+ * next chronological event is returned.
* <p>
* A null timestamp is interpreted as seeking for the first event of the
* trace.
@@ -318,7 +333,8 @@ public interface ITmfTrace extends ITmfDataProvider {
* If the requested timestamp is beyond the last trace event, the context
* returned will yield a null event if used in a subsequent read.
*
- * @param timestamp the timestamp of desired event
+ * @param timestamp
+ * the timestamp of desired event
* @return a context which can later be used to read the corresponding event
* @since 2.0
*/
@@ -332,7 +348,8 @@ public interface ITmfTrace extends ITmfDataProvider {
* voluntarily vague. Typically, it would refer to the event proportional
* rank (arguably more intuitive) or timestamp in the trace file.
*
- * @param ratio the proportional 'rank' in the trace
+ * @param ratio
+ * the proportional 'rank' in the trace
* @return a context which can later be used to read the corresponding event
*/
ITmfContext seekEvent(double ratio);
@@ -356,6 +373,37 @@ public interface ITmfTrace extends ITmfDataProvider {
* @return The host id of this trace
* @since 3.0
*/
- String getHostId();
+ String getHostId();
+
+ // ------------------------------------------------------------------------
+ // Timestamp transformation functions
+ // ------------------------------------------------------------------------
+
+ /**
+ * Returns the timestamp transformation for this trace
+ *
+ * @return the timestamp transform
+ * @since 3.0
+ */
+ ITmfTimestampTransform getTimestampTransform();
+
+ /**
+ * Sets the trace's timestamp transform
+ *
+ * @param tt
+ * The timestamp transform for all timestamps of this trace
+ * @since 3.0
+ */
+ void setTimestampTransform(final ITmfTimestampTransform tt);
+
+ /**
+ * Creates a timestamp for this trace, using the transformation formula
+ *
+ * @param ts
+ * The time in long with which to create the timestamp
+ * @return The new timestamp
+ * @since 3.0
+ */
+ ITmfTimestamp createTimestamp(long ts);
}
diff --git a/lttng/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/TmfExperiment.java b/lttng/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/TmfExperiment.java
index 8ecd7ed..8f5d2c6 100644
--- a/lttng/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/TmfExperiment.java
+++ b/lttng/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/TmfExperiment.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2009, 2013 Ericsson
+ * Copyright (c) 2009, 2013 Ericsson, É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
@@ -11,18 +11,24 @@
* Francois Chouinard - Updated as per TMF Trace Model 1.0
* Patrick Tasse - Updated for removal of context clone
* Patrick Tasse - Updated for ranks in experiment location
+ * Geneviève Bastien - Added support of experiment synchronization
*******************************************************************************/
package org.eclipse.linuxtools.tmf.core.trace;
+import java.io.File;
+
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
+import org.eclipse.linuxtools.internal.tmf.core.Activator;
import org.eclipse.linuxtools.internal.tmf.core.trace.TmfExperimentContext;
import org.eclipse.linuxtools.internal.tmf.core.trace.TmfExperimentLocation;
import org.eclipse.linuxtools.internal.tmf.core.trace.TmfLocationArray;
+import org.eclipse.linuxtools.tmf.core.TmfCommonConstants;
import org.eclipse.linuxtools.tmf.core.event.ITmfEvent;
import org.eclipse.linuxtools.tmf.core.exceptions.TmfTraceException;
import org.eclipse.linuxtools.tmf.core.request.ITmfDataRequest;
@@ -30,6 +36,9 @@ import org.eclipse.linuxtools.tmf.core.request.ITmfEventRequest;
import org.eclipse.linuxtools.tmf.core.signal.TmfSignalHandler;
import org.eclipse.linuxtools.tmf.core.signal.TmfTraceOpenedSignal;
import org.eclipse.linuxtools.tmf.core.signal.TmfTraceRangeUpdatedSignal;
+import org.eclipse.linuxtools.tmf.core.signal.TmfTraceSynchronizedSignal;
+import org.eclipse.linuxtools.tmf.core.synchronization.SynchronizationAlgorithm;
+import org.eclipse.linuxtools.tmf.core.synchronization.SynchronizationManager;
import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp;
import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimeRange;
import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimestamp;
@@ -50,6 +59,13 @@ public class TmfExperiment extends TmfTrace implements ITmfEventParser {
// ------------------------------------------------------------------------
/**
+ * The file name of the Synchronization
+ *
+ * @since 3.0
+ */
+ public final static String SYNCHRONIZATION_FILE_NAME = "synchronization.bin"; //$NON-NLS-1$
+
+ /**
* The default index page size
*/
public static final int DEFAULT_INDEX_PAGE_SIZE = 5000;
@@ -78,9 +94,12 @@ public class TmfExperiment extends TmfTrace implements ITmfEventParser {
// ------------------------------------------------------------------------
/**
- * @param type the event type
- * @param id the experiment id
- * @param traces the experiment set of traces
+ * @param type
+ * the event type
+ * @param id
+ * the experiment id
+ * @param traces
+ * the experiment set of traces
*/
public TmfExperiment(final Class<? extends ITmfEvent> type, final String id, final ITmfTrace[] traces) {
this(type, id, traces, DEFAULT_INDEX_PAGE_SIZE, null);
@@ -102,12 +121,15 @@ public class TmfExperiment extends TmfTrace implements ITmfEventParser {
this(type, id, traces, DEFAULT_INDEX_PAGE_SIZE, resource);
}
-
/**
- * @param type the event type
- * @param path the experiment path
- * @param traces the experiment set of traces
- * @param indexPageSize the experiment index page size
+ * @param type
+ * the event type
+ * @param path
+ * the experiment path
+ * @param traces
+ * the experiment set of traces
+ * @param indexPageSize
+ * the experiment index page size
*/
public TmfExperiment(final Class<? extends ITmfEvent> type, final String path, final ITmfTrace[] traces, final int indexPageSize) {
this(type, path, traces, indexPageSize, null);
@@ -140,6 +162,14 @@ public class TmfExperiment extends TmfTrace implements ITmfEventParser {
}
fTraces = traces;
+
+ if (resource != null) {
+ try {
+ this.synchronizeTraces();
+ } catch (TmfTraceException e) {
+ Activator.logError("Error synchronizing experiment", e); //$NON-NLS-1$
+ }
+ }
}
/**
@@ -195,7 +225,8 @@ public class TmfExperiment extends TmfTrace implements ITmfEventParser {
* Returns the timestamp of the event at the requested index. If none,
* returns null.
*
- * @param index the event index (rank)
+ * @param index
+ * the event index (rank)
* @return the corresponding event timestamp
* @since 2.0
*/
@@ -209,7 +240,8 @@ public class TmfExperiment extends TmfTrace implements ITmfEventParser {
/**
* Set the file to be used for bookmarks on this experiment
*
- * @param file the bookmarks file
+ * @param file
+ * the bookmarks file
*/
public void setBookmarksFile(final IFile file) {
fBookmarksFile = file;
@@ -240,8 +272,8 @@ public class TmfExperiment extends TmfTrace implements ITmfEventParser {
}
if (request instanceof ITmfEventRequest
- && !TmfTimestamp.BIG_BANG.equals(((ITmfEventRequest) request).getRange().getStartTime())
- && request.getIndex() == 0)
+ && !TmfTimestamp.BIG_BANG.equals(((ITmfEventRequest) request).getRange().getStartTime())
+ && request.getIndex() == 0)
{
final ITmfContext context = seekEvent(((ITmfEventRequest) request).getRange().getStartTime());
((ITmfEventRequest) request).setStartIndex((int) context.getRank());
@@ -362,7 +394,8 @@ public class TmfExperiment extends TmfTrace implements ITmfEventParser {
TmfExperimentContext expContext = (TmfExperimentContext) context;
- // If an event was consumed previously, first get the next one from that trace
+ // If an event was consumed previously, first get the next one from that
+ // trace
final int lastTrace = expContext.getLastTrace();
if (lastTrace != TmfExperimentContext.NO_TRACE) {
final ITmfContext traceContext = expContext.getContexts()[lastTrace];
@@ -425,6 +458,62 @@ public class TmfExperiment extends TmfTrace implements ITmfEventParser {
return initTs;
}
+ /**
+ * Synchronizes the traces of an experiment. By default it only tries to
+ * read a synchronization file if it exists
+ *
+ * @return The synchronization object
+ * @throws TmfTraceException
+ * propagate TmfTraceExceptions
+ * @since 3.0
+ */
+ public synchronized SynchronizationAlgorithm synchronizeTraces() throws TmfTraceException {
+ return synchronizeTraces(false);
+ }
+
+ /**
+ * Synchronizes the traces of an experiment.
+ *
+ * @param doSync
+ * Whether to actually synchronize or just try opening a sync
+ * file
+ * @return The synchronization object
+ * @throws TmfTraceException
+ * propagate TmfTraceExceptions
+ * @since 3.0
+ */
+ public synchronized SynchronizationAlgorithm synchronizeTraces(boolean doSync) throws TmfTraceException {
+
+ /* Set up the path to the synchronization file we'll use */
+ IResource resource = this.getResource();
+ String supplDirectory = null;
+
+ try {
+ /* get the directory where the file will be stored. */
+ if (resource != null) {
+ supplDirectory = resource.getPersistentProperty(TmfCommonConstants.TRACE_SUPPLEMENTARY_FOLDER);
+ }
+ } catch (CoreException e) {
+ throw new TmfTraceException(e.toString(), e);
+ }
+
+ final File syncFile = (supplDirectory != null) ? new File(supplDirectory + File.separator + SYNCHRONIZATION_FILE_NAME) : null;
+
+ final SynchronizationAlgorithm syncAlgo = SynchronizationManager.synchronizeTraces(syncFile, fTraces, doSync);
+
+ final TmfTraceSynchronizedSignal signal = new TmfTraceSynchronizedSignal(this, syncAlgo);
+
+ /* Broadcast in separate thread to prevent deadlock */
+ new Thread() {
+ @Override
+ public void run() {
+ broadcast(signal);
+ }
+ }.start();
+
+ return syncAlgo;
+ }
+
@Override
@SuppressWarnings("nls")
public synchronized String toString() {
diff --git a/lttng/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/TmfTrace.java b/lttng/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/TmfTrace.java
index 817d852..ea3f7b5 100644
--- a/lttng/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/TmfTrace.java
+++ b/lttng/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/TmfTrace.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2009, 2013 Ericsson
+ * Copyright (c) 2009, 2013 Ericsson, É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
@@ -10,15 +10,24 @@
* Francois Chouinard - Initial API and implementation
* Francois Chouinard - Updated as per TMF Trace Model 1.0
* Patrick Tasse - Updated for removal of context clone
+ * Geneviève Bastien - Added timestamp transforms, its saving to file and
+ * timestamp creation functions
*******************************************************************************/
package org.eclipse.linuxtools.tmf.core.trace;
import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.Map;
+import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
@@ -26,6 +35,7 @@ import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.MultiStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.linuxtools.internal.tmf.core.Activator;
+import org.eclipse.linuxtools.tmf.core.TmfCommonConstants;
import org.eclipse.linuxtools.tmf.core.component.TmfEventProvider;
import org.eclipse.linuxtools.tmf.core.event.ITmfEvent;
import org.eclipse.linuxtools.tmf.core.exceptions.TmfTraceException;
@@ -38,6 +48,8 @@ import org.eclipse.linuxtools.tmf.core.signal.TmfTraceRangeUpdatedSignal;
import org.eclipse.linuxtools.tmf.core.statesystem.ITmfStateSystem;
import org.eclipse.linuxtools.tmf.core.statistics.ITmfStatistics;
import org.eclipse.linuxtools.tmf.core.statistics.TmfStateStatistics;
+import org.eclipse.linuxtools.tmf.core.synchronization.ITmfTimestampTransform;
+import org.eclipse.linuxtools.tmf.core.synchronization.TmfTimestampTransform;
import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp;
import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimeRange;
import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimestamp;
@@ -116,6 +128,10 @@ public abstract class TmfTrace extends TmfEventProvider implements ITmfTrace {
protected final Map<String, ITmfStateSystem> fStateSystems =
new LinkedHashMap<String, ITmfStateSystem>();
+ private ITmfTimestampTransform fTsTransform;
+
+ private static final String SYNCHRONIZATION_FORMULA_FILE = "sync_formula"; //$NON-NLS-1$
+
// ------------------------------------------------------------------------
// Construction
// ------------------------------------------------------------------------
@@ -737,6 +753,102 @@ public abstract class TmfTrace extends TmfEventProvider implements ITmfTrace {
}
}
+ /**
+ * Returns the file resource used to store synchronization formula. The file
+ * may not exist.
+ *
+ * @return the synchronization file
+ */
+ private File getSyncFormulaFile() {
+ File file = null;
+ if (fResource instanceof IFolder) {
+ try {
+ String supplDirectory;
+
+ supplDirectory = fResource.getPersistentProperty(TmfCommonConstants.TRACE_SUPPLEMENTARY_FOLDER);
+
+ file = new File(supplDirectory + File.separator + SYNCHRONIZATION_FORMULA_FILE);
+
+ } catch (CoreException e) {
+
+ }
+ }
+ return file;
+ }
+
+ // ------------------------------------------------------------------------
+ // Timestamp transformation functions
+ // ------------------------------------------------------------------------
+
+ /**
+ * @since 3.0
+ */
+ @Override
+ public ITmfTimestampTransform getTimestampTransform() {
+ if (fTsTransform == null) {
+ /* Check if a formula is stored somewhere in the resources */
+ File sync_file = getSyncFormulaFile();
+ if (sync_file != null && sync_file.exists()) {
+
+ try {
+ FileInputStream fis = new FileInputStream(sync_file);
+ ObjectInputStream ois = new ObjectInputStream(fis);
+ fTsTransform = (ITmfTimestampTransform) ois.readObject();
+
+ ois.close();
+ fis.close();
+ } catch (ClassNotFoundException e1) {
+ fTsTransform = TmfTimestampTransform.IDENTITY;
+ } catch (FileNotFoundException e1) {
+ fTsTransform = TmfTimestampTransform.IDENTITY;
+ } catch (IOException e1) {
+ fTsTransform = TmfTimestampTransform.IDENTITY;
+ }
+ } else {
+ fTsTransform = TmfTimestampTransform.IDENTITY;
+ }
+ }
+ return fTsTransform;
+ }
+
+ /**
+ * @since 3.0
+ */
+ @Override
+ public void setTimestampTransform(final ITmfTimestampTransform tt) {
+ fTsTransform = tt;
+
+ /* Save the timestamp transform to a file */
+ File sync_file = getSyncFormulaFile();
+ if (sync_file != null) {
+ if (sync_file.exists()) {
+ sync_file.delete();
+ }
+ FileOutputStream fos;
+ ObjectOutputStream oos;
+
+ /* Save the header of the file */
+ try {
+ fos = new FileOutputStream(sync_file, false);
+ oos = new ObjectOutputStream(fos);
+
+ oos.writeObject(fTsTransform);
+ oos.close();
+ fos.close();
+ } catch (IOException e1) {
+ Activator.logError("Error writing timestamp transform for trace", e1); //$NON-NLS-1$
+ }
+ }
+ }
+
+ /**
+ * @since 3.0
+ */
+ @Override
+ public ITmfTimestamp createTimestamp(long ts) {
+ return new TmfTimestamp(getTimestampTransform().transform(ts));
+ }
+
// ------------------------------------------------------------------------
// toString
// ------------------------------------------------------------------------
diff --git a/lttng/org.eclipse.linuxtools.tmf.ui/META-INF/MANIFEST.MF b/lttng/org.eclipse.linuxtools.tmf.ui/META-INF/MANIFEST.MF
index 7d9e01a..19659e2 100644
--- a/lttng/org.eclipse.linuxtools.tmf.ui/META-INF/MANIFEST.MF
+++ b/lttng/org.eclipse.linuxtools.tmf.ui/META-INF/MANIFEST.MF
@@ -43,6 +43,7 @@ Export-Package: org.eclipse.linuxtools.internal.tmf.ui;x-friends:="org.eclipse.l
org.eclipse.linuxtools.tmf.ui.views.histogram,
org.eclipse.linuxtools.tmf.ui.views.statesystem,
org.eclipse.linuxtools.tmf.ui.views.statistics,
+ org.eclipse.linuxtools.tmf.ui.views.synchronization,
org.eclipse.linuxtools.tmf.ui.views.timechart,
org.eclipse.linuxtools.tmf.ui.views.timegraph,
org.eclipse.linuxtools.tmf.ui.views.uml2sd,
diff --git a/lttng/org.eclipse.linuxtools.tmf.ui/icons/eview16/synced.gif b/lttng/org.eclipse.linuxtools.tmf.ui/icons/eview16/synced.gif
new file mode 100644
index 0000000..870934b
--- /dev/null
+++ b/lttng/org.eclipse.linuxtools.tmf.ui/icons/eview16/synced.gif
Binary files differ
diff --git a/lttng/org.eclipse.linuxtools.tmf.ui/plugin.properties b/lttng/org.eclipse.linuxtools.tmf.ui/plugin.properties
index 4d662a4..363e56b 100644
--- a/lttng/org.eclipse.linuxtools.tmf.ui/plugin.properties
+++ b/lttng/org.eclipse.linuxtools.tmf.ui/plugin.properties
@@ -27,6 +27,8 @@ uml2sd.view.name = Sequence Diagram
histogram.view.name = Histogram
ssvisualizer.view.name = State System Explorer
callstack.view.name = Call Stack
+synchronization.view.name = Synchronization
+
# Tracing wizards
project.new.category.name = Tracing
@@ -90,6 +92,10 @@ command.batch_import = Batch Import...
command.batch_import.mnemonic = B
command.batch_import.descriptio = Batch Import
+command.synchronize_traces = Synchronize Traces
+command.synchronize_traces.mnemonic = y
+command.synchronize_traces.description = Synchronize 2 or more traces
+
## Trace menu
# Open, Copy, Rename, Delete, Delete Supplementary Files, Select Trace Type
diff --git a/lttng/org.eclipse.linuxtools.tmf.ui/plugin.xml b/lttng/org.eclipse.linuxtools.tmf.ui/plugin.xml
index 6cfe041..93eaaae 100644
--- a/lttng/org.eclipse.linuxtools.tmf.ui/plugin.xml
+++ b/lttng/org.eclipse.linuxtools.tmf.ui/plugin.xml
@@ -88,6 +88,15 @@
name="%callstack.view.name"
restorable="true">
</view>
+ <view
+ allowMultiple="false"
+ category="org.eclipse.linuxtools.tmf.ui.views.category"
+ class="org.eclipse.linuxtools.tmf.ui.views.synchronization.TmfSynchronizationView"
+ icon="icons/eview16/synced.gif"
+ id="org.eclipse.linuxtools.tmf.ui.views.synchronization"
+ name="%synchronization.view.name"
+ restorable="true">
+ </view>
</extension>
<extension
point="org.eclipse.ui.editors">
@@ -663,6 +672,30 @@
</with>
</visibleWhen>
</command>
+ <command
+ commandId="org.eclipse.linuxtools.tmf.ui.command.synchronize_traces"
+ icon="icons/obj16/add_obj.gif"
+ label="%command.synchronize_traces"
+ mnemonic="%command.synchronize_traces.mnemonic"
+ style="push"
+ tooltip="%commands.synchronize_traces.description">
+ <visibleWhen
+ checkEnabled="false">
+ <with
+ variable="selection">
+ <count
+ value="1">
+ </count>
+ <iterate
+ ifEmpty="false"
+ operator="and">
+ <instanceof
+ value="org.eclipse.linuxtools.tmf.ui.project.model.TmfExperimentElement">
+ </instanceof>
+ </iterate>
+ </with>
+ </visibleWhen>
+ </command>
<separator
name="org.eclipse.linuxtools.tmf.ui.separator5"
visible="true">
@@ -744,6 +777,12 @@
id="org.eclipse.linuxtools.tmf.ui.command.select_traces"
name="%command.select_traces">
</command>
+ <command
+ categoryId="org.eclipse.linuxtools.tmf.ui.commands.category"
+ description="%command.synchronize_traces.description"
+ id="org.eclipse.linuxtools.tmf.ui.command.synchronize_traces"
+ name="%command.synchronize_traces">
+ </command>
<category
description="%commands.parser.category.description"
id="org.eclipse.linuxtools.tmf.ui.commands.parser.category"
@@ -1064,6 +1103,23 @@
</activeWhen>
</handler>
<handler
+ class="org.eclipse.linuxtools.internal.tmf.ui.project.handlers.SynchronizeTracesHandler"
+ commandId="org.eclipse.linuxtools.tmf.ui.command.synchronize_traces">
+ <activeWhen>
+ <and>
+ <count
+ value="1">
+ </count>
+ <iterate
+ operator="and">
+ <instanceof
+ value="org.eclipse.linuxtools.tmf.ui.project.model.TmfExperimentElement">
+ </instanceof>
+ </iterate>
+ </and>
+ </activeWhen>
+ </handler>
+ <handler
class="org.eclipse.linuxtools.internal.tmf.ui.commands.ManageCustomParsersCommandHandler"
commandId="org.eclipse.linuxtools.tmf.ui.command.managecustomparsers">
</handler>
diff --git a/lttng/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/handlers/Messages.java b/lttng/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/handlers/Messages.java
index 5f9ac1c..a7dd632 100644
--- a/lttng/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/handlers/Messages.java
+++ b/lttng/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/handlers/Messages.java
@@ -43,17 +43,22 @@ public class Messages extends NLS {
public static String DeleteExperimentHandler_Error;
public static String SelectTraceTypeHandler_ErrorSelectingTrace;
-
public static String SelectTraceTypeHandler_Title;
-
public static String SelectTraceTypeHandler_TraceFailedValidation;
-
public static String SelectTraceTypeHandler_TracesFailedValidation;
public static String SelectTraceTypeHandler_InvalidTraceType;
public static String DropAdapterAssistant_RenameTraceTitle;
public static String DropAdapterAssistant_RenameTraceMessage;
+ public static String SynchronizeTracesHandler_CopyProblem;
+ public static String SynchronizeTracesHandler_WrongType;
+ public static String SynchronizeTracesHandler_WrongTraceNumber;
+ public static String SynchronizeTracesHandler_Title;
+ public static String SynchronizeTracesHandler_Error;
+ public static String SynchronizeTracesHandler_ErrorSynchingExperiment;
+ public static String SynchronizeTracesHandler_ErrorSynchingForTrace;
+
static {
// initialize resource bundle
NLS.initializeMessages(BUNDLE_NAME, Messages.class);
diff --git a/lttng/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/handlers/OpenExperimentHandler.java b/lttng/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/handlers/OpenExperimentHandler.java
index 4b70c4a..c4dbfbe 100644
--- a/lttng/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/handlers/OpenExperimentHandler.java
+++ b/lttng/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/handlers/OpenExperimentHandler.java
@@ -120,7 +120,7 @@ public class OpenExperimentHandler extends AbstractHandler {
return;
}
- /* Unlike traces, there is no instanceExperiment, so we call this function
+ /* FIXME Unlike traces, there is no instanceExperiment, so we call this function
* here alone. Maybe it would be better to do this on experiment's element
* constructor?
*/
@@ -128,6 +128,7 @@ public class OpenExperimentHandler extends AbstractHandler {
// Instantiate the experiment's traces
final List<TmfTraceElement> traceEntries = experimentElement.getTraces();
+ experimentElement.refreshSupplementaryFolder();
final int nbTraces = traceEntries.size();
int cacheSize = Integer.MAX_VALUE;
String commonEditorId = null;
diff --git a/lttng/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/handlers/SynchronizeTracesHandler.java b/lttng/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/handlers/SynchronizeTracesHandler.java
new file mode 100644
index 0000000..9ac1c4c
--- /dev/null
+++ b/lttng/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/handlers/SynchronizeTracesHandler.java
@@ -0,0 +1,250 @@
+/*******************************************************************************
+ * Copyright (c) 2013 É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 implementation and API
+ *******************************************************************************/
+
+package org.eclipse.linuxtools.internal.tmf.ui.project.handlers;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+
+import org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.ISelectionProvider;
+import org.eclipse.jface.viewers.TreeSelection;
+import org.eclipse.linuxtools.internal.tmf.ui.Activator;
+import org.eclipse.linuxtools.tmf.core.event.ITmfEvent;
+import org.eclipse.linuxtools.tmf.core.exceptions.TmfTraceException;
+import org.eclipse.linuxtools.tmf.core.synchronization.SynchronizationAlgorithm;
+import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace;
+import org.eclipse.linuxtools.tmf.core.trace.TmfExperiment;
+import org.eclipse.linuxtools.tmf.ui.project.model.ITmfProjectModelElement;
+import org.eclipse.linuxtools.tmf.ui.project.model.TmfExperimentElement;
+import org.eclipse.linuxtools.tmf.ui.project.model.TmfTraceElement;
+import org.eclipse.linuxtools.tmf.ui.project.model.TraceUtils;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.ui.IWorkbenchPage;
+import org.eclipse.ui.IWorkbenchPart;
+import org.eclipse.ui.IWorkbenchWindow;
+import org.eclipse.ui.PlatformUI;
+
+/**
+ * Handles the synchronization of an experiment, when the user selects this
+ * option in the menu
+ */
+public class SynchronizeTracesHandler extends AbstractHandler {
+
+ // ------------------------------------------------------------------------
+ // Attributes
+ // ------------------------------------------------------------------------
+
+ private TreeSelection fSelection = null;
+ private static final String CR = System.getProperty("line.separator"); //$NON-NLS-1$
+
+ // ------------------------------------------------------------------------
+ // Validation
+ // ------------------------------------------------------------------------
+
+ @Override
+ public boolean isEnabled() {
+ return true;
+ }
+
+ // ------------------------------------------------------------------------
+ // Execution
+ // ------------------------------------------------------------------------
+
+ @Override
+ public Object execute(ExecutionEvent event) throws ExecutionException {
+
+ // Check if we are closing down
+ IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
+ if (window == null) {
+ return null;
+ }
+
+ // Get the selection
+ IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
+ IWorkbenchPart part = page.getActivePart();
+ if (part == null) {
+ return false;
+ }
+ ISelectionProvider selectionProvider = part.getSite().getSelectionProvider();
+ if (selectionProvider == null) {
+ return false;
+ }
+ ISelection selection = selectionProvider.getSelection();
+
+ // Make sure selection contains only traces
+ fSelection = null;
+ final ArrayList<TmfTraceElement> tl = new ArrayList<TmfTraceElement>();
+ final ArrayList<TmfExperimentElement> uiexperiment = new ArrayList<TmfExperimentElement>();
+ if (selection instanceof TreeSelection) {
+ fSelection = (TreeSelection) selection;
+ Iterator<Object> iterator = fSelection.iterator();
+ while (iterator.hasNext()) {
+ Object element = iterator.next();
+ if (element instanceof TmfTraceElement) {
+ tl.add((TmfTraceElement) element);
+ } else if (element instanceof TmfExperimentElement) {
+ TmfExperimentElement exp = (TmfExperimentElement) element;
+ uiexperiment.add(exp);
+ for (TmfTraceElement trace : exp.getTraces()) {
+ tl.add(trace);
+ }
+ }
+ }
+ }
+
+ if ((uiexperiment.size() == 1) && (tl.size() > 1)) {
+
+ Thread thread = new Thread() {
+ @Override
+ public void run() {
+
+ final ITmfTrace[] traces = new ITmfTrace[tl.size()];
+ final TmfExperimentElement exp = uiexperiment.get(0);
+
+ for (int i = 0; i < tl.size(); i++) {
+ ITmfTrace trace = tl.get(i).instantiateTrace();
+ ITmfEvent traceEvent = tl.get(i).instantiateEvent();
+ if (trace == null) {
+ TraceUtils.displayErrorMsg(Messages.SynchronizeTracesHandler_Title, Messages.SynchronizeTracesHandler_WrongType + tl.get(i).getName());
+ for (int j = 0; j < i; j++) {
+ traces[j].dispose();
+ }
+ return;
+ }
+ try {
+ trace.initTrace(tl.get(i).getResource(), tl.get(i).getLocation().getPath(), traceEvent.getClass());
+ } catch (TmfTraceException e) {
+ TraceUtils.displayErrorMsg(Messages.SynchronizeTracesHandler_Title, Messages.OpenTraceHandler_InitError + CR + CR + e);
+ trace.dispose();
+ for (int j = 0; j < i; j++) {
+ traces[j].dispose();
+ }
+ return;
+ }
+ traces[i] = trace;
+ }
+
+ /*
+ * FIXME Unlike traces, there is no instanceExperiment, so
+ * we call this function here alone. Maybe it would be
+ * better to do this on experiment's element constructor?
+ */
+ exp.refreshSupplementaryFolder();
+ final TmfExperiment experiment = new TmfExperiment(ITmfEvent.class, exp.getName(), traces, exp.getResource());
+
+ try {
+ final SynchronizationAlgorithm syncAlgo = experiment.synchronizeTraces(true);
+
+ Display.getDefault().asyncExec(new Runnable() {
+ @Override
+ public void run() {
+ /*
+ * For each trace in the experiment, if there is
+ * a transform equation, copy the original
+ * trace, so that a new state system will be
+ * generated with sync time.
+ */
+ for (int i = 0; i < tl.size(); i++) {
+ TmfTraceElement traceel = tl.get(i);
+ try {
+ if (syncAlgo.isTraceSynced(traceel.getName())) {
+
+ /* Find the original trace */
+ TmfTraceElement origtrace = null;
+ for (ITmfProjectModelElement el : traceel.getProject().getTracesFolder().getTraces()) {
+ if (el.getName().equals(traceel.getName())) {
+ origtrace = (TmfTraceElement) el;
+ }
+ }
+
+ if (origtrace != null) {
+ /*
+ * Make sure a trace with the
+ * new name does not exist
+ */
+ String newname = traceel.getName();
+ boolean traceexists;
+ do {
+ traceexists = false;
+ newname += "_"; //$NON-NLS-1$
+ for (ITmfProjectModelElement el : traceel.getProject().getTracesFolder().getTraces()) {
+ if (el.getName().equals(newname)) {
+ traceexists = true;
+ }
+ }
+ } while (traceexists);
+
+ /* Copy the original trace */
+ TmfTraceElement newtrace = origtrace.copy(newname);
+
+ if (newtrace != null) {
+
+ syncAlgo.renameTrace(origtrace.getName(), newtrace.getName());
+
+ /*
+ * Instantiate the new trace
+ * and set its sync formula
+ */
+ ITmfTrace trace = newtrace.instantiateTrace();
+ ITmfEvent traceEvent = newtrace.instantiateEvent();
+
+ trace.initTrace(newtrace.getResource(), newtrace.getLocation().getPath(), traceEvent.getClass());
+ trace.setTimestampTransform(syncAlgo.getTimestampTransform(trace));
+
+ /*
+ * Add the new trace to the
+ * experiment
+ */
+ exp.addTrace(newtrace);
+
+ /*
+ * Delete the original trace
+ * element
+ */
+ exp.removeTrace(traceel);
+ } else {
+ TraceUtils.displayErrorMsg(Messages.SynchronizeTracesHandler_Title, Messages.SynchronizeTracesHandler_Error + CR + CR + String.format(Messages.SynchronizeTracesHandler_CopyProblem, origtrace.getName()));
+ }
+ }
+ }
+ } catch (CoreException e) {
+ Activator.getDefault().logError(String.format(Messages.SynchronizeTracesHandler_ErrorSynchingForTrace, exp.getName(), traceel.getName()), e);
+ TraceUtils.displayErrorMsg(Messages.SynchronizeTracesHandler_Title, Messages.SynchronizeTracesHandler_Error + CR + CR + e.getMessage());
+ } catch (TmfTraceException e) {
+ Activator.getDefault().logError(String.format(Messages.SynchronizeTracesHandler_ErrorSynchingForTrace, exp.getName(), traceel.getName()), e);
+ TraceUtils.displayErrorMsg(Messages.SynchronizeTracesHandler_Title, Messages.SynchronizeTracesHandler_Error + CR + CR + e.getMessage());
+ }
+ }
+ }
+ });
+
+ } catch (TmfTraceException e) {
+ Activator.getDefault().logError(String.format(Messages.SynchronizeTracesHandler_ErrorSynchingExperiment, exp.getName()), e);
+ TraceUtils.displayErrorMsg(Messages.SynchronizeTracesHandler_Title, Messages.OpenExperimentHandler_Error + CR + CR + e.getMessage());
+ }
+ }
+ };
+ thread.start();
+
+ } else {
+ TraceUtils.displayErrorMsg(Messages.SynchronizeTracesHandler_Title, Messages.SynchronizeTracesHandler_WrongTraceNumber);
+ }
+
+ return null;
+ }
+
+}
diff --git a/lttng/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/handlers/messages.properties b/lttng/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/handlers/messages.properties
index 3161c0f..e8cfa94 100644
--- a/lttng/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/handlers/messages.properties
+++ b/lttng/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/internal/tmf/ui/project/handlers/messages.properties
@@ -39,3 +39,13 @@ SelectTraceTypeHandler_InvalidTraceType = Type could not be set for one or more
# Drag and drop
DropAdapterAssistant_RenameTraceTitle=Confirm rename trace
DropAdapterAssistant_RenameTraceMessage=A trace with the name ''{0}'' already exists in the target project.\nRename the dropped trace?
+
+# Trace synchronization
+SynchronizeTracesHandler_CopyProblem=Couldn't copy the original trace %s
+SynchronizeTracesHandler_WrongTraceNumber=Experiment must have more than one trace
+SynchronizeTracesHandler_Title=Synchronize traces
+SynchronizeTracesHandler_WrongType=Trace is not a kernel trace:\n
+SynchronizeTracesHandler_Error=Error synchronizing experiment
+
+SynchronizeTracesHandler_ErrorSynchingExperiment=Error synchronizing experiment %s
+SynchronizeTracesHandler_ErrorSynchingForTrace=Error synchronizing experiment %s for trace %s
diff --git a/lttng/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/model/TmfWithFolderElement.java b/lttng/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/model/TmfWithFolderElement.java
index a2ca20e..8fdf445 100644
--- a/lttng/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/model/TmfWithFolderElement.java
+++ b/lttng/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/model/TmfWithFolderElement.java
@@ -29,7 +29,7 @@ import org.eclipse.linuxtools.tmf.core.trace.TmfTrace;
* Base class for project elements who will have folder elements
* under them to store supplementary files.
*
- * @author gbastien
+ * @author Geneviève Bastien
* @since 2.0
*/
public abstract class TmfWithFolderElement extends TmfProjectModelElement {
@@ -239,7 +239,7 @@ public abstract class TmfWithFolderElement extends TmfProjectModelElement {
if (TmfTrace.class.getCanonicalName().equals(member.getPersistentProperty(TmfCommonConstants.TRACETYPE))) {
member.delete(true, null);
}
- if (TmfExperiment.class.getCanonicalName().equals(member.getPersistentProperty(TmfCommonConstants.TRACETYPE))) {
+ else if (TmfExperiment.class.getCanonicalName().equals(member.getPersistentProperty(TmfCommonConstants.TRACETYPE))) {
member.delete(true, null);
}
}
diff --git a/lttng/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/synchronization/Messages.java b/lttng/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/synchronization/Messages.java
new file mode 100644
index 0000000..41351a0
--- /dev/null
+++ b/lttng/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/synchronization/Messages.java
@@ -0,0 +1,33 @@
+/*******************************************************************************
+ * Copyright (c) 2013 É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 implementation and API
+ *******************************************************************************/
+
+package org.eclipse.linuxtools.tmf.ui.views.synchronization;
+
+import org.eclipse.osgi.util.NLS;
+
+/**
+ * Message file for the synchronization view
+ * @since 3.0
+ */
+@SuppressWarnings("javadoc")
+public class Messages extends NLS {
+ private static final String BUNDLE_NAME = "org.eclipse.linuxtools.tmf.ui.views.synchronization.messages"; //$NON-NLS-1$
+ public static String TmfSynchronizationView_NameColumn;
+ public static String TmfSynchronizationView_ValueColumn;
+ static {
+ // initialize resource bundle
+ NLS.initializeMessages(BUNDLE_NAME, Messages.class);
+ }
+
+ private Messages() {
+ }
+}
diff --git a/lttng/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/synchronization/TmfSynchronizationView.java b/lttng/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/synchronization/TmfSynchronizationView.java
new file mode 100644
index 0000000..ce06df9
--- /dev/null
+++ b/lttng/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/synchronization/TmfSynchronizationView.java
@@ -0,0 +1,127 @@
+/*******************************************************************************
+ * Copyright (c) 2013 É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 implementation and API
+ *******************************************************************************/
+
+package org.eclipse.linuxtools.tmf.ui.views.synchronization;
+
+import java.util.Map;
+
+import org.eclipse.linuxtools.tmf.core.signal.TmfSignalHandler;
+import org.eclipse.linuxtools.tmf.core.signal.TmfTraceSynchronizedSignal;
+import org.eclipse.linuxtools.tmf.core.synchronization.SynchronizationAlgorithm;
+import org.eclipse.linuxtools.tmf.ui.views.TmfView;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Tree;
+import org.eclipse.swt.widgets.TreeColumn;
+import org.eclipse.swt.widgets.TreeItem;
+
+/**
+ * Small view to display statistics about a synchronization
+ *
+ * @author Geneviève Bastien
+ * @since 3.0
+ */
+public class TmfSynchronizationView extends TmfView {
+
+ /**
+ * The ID corresponds to the package in which this class is embedded.
+ */
+ public static final String ID = "org.eclipse.linuxtools.tmf.ui.views.synchronization"; //$NON-NLS-1$
+
+ /**
+ * The view name.
+ */
+ public static final String TMF_SYNCHRONIZATION_VIEW = "SynchronizationView"; //$NON-NLS-1$
+
+ /**
+ * The synchronization algorithm to display stats for
+ */
+ private SynchronizationAlgorithm fAlgoSync;
+
+ private Tree fTree;
+
+ /**
+ * Default constructor
+ */
+ public TmfSynchronizationView() {
+ super(TMF_SYNCHRONIZATION_VIEW);
+ }
+
+ @Override
+ public void createPartControl(Composite parent) {
+ fTree = new Tree(parent, SWT.NONE);
+ TreeColumn nameCol = new TreeColumn(fTree, SWT.NONE, 0);
+ TreeColumn valueCol = new TreeColumn(fTree, SWT.NONE, 1);
+ nameCol.setText(Messages.TmfSynchronizationView_NameColumn);
+ valueCol.setText(Messages.TmfSynchronizationView_ValueColumn);
+
+ fTree.setItemCount(0);
+
+ fTree.setHeaderVisible(true);
+ nameCol.pack();
+ valueCol.pack();
+
+ }
+
+ private void updateTable() {
+ fTree.setItemCount(0);
+ if (fAlgoSync == null) {
+ return;
+ }
+
+ for (Map.Entry<String, Map<String, Object>> entry : fAlgoSync.getStats().entrySet()) {
+ TreeItem item = new TreeItem(fTree, SWT.NONE);
+ item.setText(0, entry.getKey().toString());
+ item.setText(1, entry.getValue().toString());
+
+ for (Map.Entry<String, Object> subentry : entry.getValue().entrySet()) {
+ TreeItem subitem = new TreeItem(item, SWT.NONE);
+ subitem.setText(0, subentry.getKey().toString());
+ subitem.setText(1, subentry.getValue().toString());
+ }
+ }
+
+ /* Expand the tree items */
+ for (int i = 0; i < fTree.getItemCount(); i++) {
+ fTree.getItem(i).setExpanded(true);
+ }
+
+ for (TreeColumn column : fTree.getColumns()) {
+ column.pack();
+ }
+ }
+
+ @Override
+ public void setFocus() {
+ fTree.setFocus();
+ }
+
+ /**
+ * Handler called when traces are synchronized
+ *
+ * @param signal
+ * Contains the information about the selection.
+ */
+ @TmfSignalHandler
+ public void traceSynchronized(TmfTraceSynchronizedSignal signal) {
+ if (signal.getSyncAlgo() != fAlgoSync) {
+ fAlgoSync = signal.getSyncAlgo();
+ Display.getDefault().asyncExec(new Runnable() {
+ @Override
+ public void run() {
+ updateTable();
+ }
+ });
+ }
+ }
+}
diff --git a/lttng/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/synchronization/messages.properties b/lttng/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/synchronization/messages.properties
new file mode 100644
index 0000000..9f44658
--- /dev/null
+++ b/lttng/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/views/synchronization/messages.properties
@@ -0,0 +1,2 @@
+TmfSynchronizationView_NameColumn=Synchronization Information
+TmfSynchronizationView_ValueColumn=Value