ctf: Add streamIntersection() method for CTF traces
authorAlexandre Montplaisir <alexmonthy@efficios.com>
Fri, 7 Jul 2017 20:59:16 +0000 (16:59 -0400)
committerAlexandre Montplaisir <alexmonthy@efficios.com>
Fri, 7 Jul 2017 20:59:16 +0000 (16:59 -0400)
Stream intersection consists of trimming the trace to the time range
intersecting all CTF streams. This allows dropping events from areas
where only partial data is available.

This would be a good contender for re-using the trim() method. However
since trim() is currently implemented by calling Babeltrace, and
Babeltrace already has a stream intersection function, we can simply
call Babeltrace's function.

Change-Id: I9d38fbddccb2bee88aa4bca3f068efed24c295d5
Signed-off-by: Alexandre Montplaisir <alexmonthy@efficios.com>
ctf/org.eclipse.tracecompass.tmf.ctf.core/src/org/eclipse/tracecompass/tmf/ctf/core/trace/CtfTmfTrace.java

index e51558c6d6dd60ad78d51dc1e72f3d9d9784e6de..7168acb181c97554c521a4f385a93f52be79edbb 100644 (file)
@@ -755,22 +755,72 @@ public class CtfTmfTrace extends TmfTrace
     }
 
     /**
+     * Perform stream intersection on the current trace. This means trimming the
+     * trace to the largest time range for which all CTF streams have events
+     * present in them.
+     *
+     * Since the initial trace needs to be imported/initialized in Trace
+     * Compass, it works by creating a new trace which results from the stream
+     * intersection operation.
+     *
+     * A typical use case is for analyzing snapshot traces, where some
+     * low-activity streams may go back in time very far, and others with more
+     * events don't go very far in time. By doing a stream intersection we drop
+     * events from less interesting periods.
+     *
+     * @param destinationPath
+     *            The location where the new trace will be created.
+     * @param monitor
+     *            Progress monitor for cases where the operation is ran from
+     *            inside a Job. You can use a
+     *            {@link org.eclipse.core.runtime.NullProgressMonitor} if none
+     *            is available.
+     * @throws CoreException
+     *             Optional exception indicating an error during the execution
+     *             of the operation.
      * @since 2.2
      */
-    @Override
     @SuppressWarnings("nls")
-    public void trim(@NonNull TmfTimeRange range, @NonNull Path destinationPath, @NonNull IProgressMonitor monitor) throws CoreException {
-        List<@NonNull String> command;
-        @Nullable List<String> output;
+    public void streamIntersection(@NonNull Path destinationPath,  @NonNull IProgressMonitor monitor) throws CoreException {
+        /* Perform the stream intersection reading + outputting by Babeltrace */
+        verifyBabeltrace2Present();
 
-        /* Verify that Babeltrace 2.0 is installed and available */
-        command = Arrays.asList("babeltrace", "--version");
-        output = ProcessUtils.getOutputFromCommand(command);
-        if (output == null || output.isEmpty() || !output.get(0).contains("Babeltrace 2")) {
-            IStatus status = new Status(IStatus.ERROR, Activator.PLUGIN_ID, Messages.CtfTmfTrace_BabelTrace2NotFound);
-            throw new CoreException(status);
+        /*
+         * NOTE Querying the stream ranges could be done on the Trace Compass side.
+         * However since we need Babeltrace atm for the trace trimming, we might as well
+         * just call Babeltrace's stream intersection operation. If a Babeltrace-free
+         * trim() is implemented, this here could be modified to call trim() instead.
+         */
+        String originPath = getPath();
+        if (!originPath.endsWith(File.separator)) {
+            originPath = originPath + File.separator;
         }
 
+        List<@NonNull String> command = Arrays.asList("bash", "-c",
+                "babeltrace"
+                + " \"" + originPath + "\""
+                + " --stream-intersection"
+                + " --no-debug-info"
+                + " --component sink.ctf.fs"
+                + " --path \"" + destinationPath.toString() + '\"'
+                + " -p single-trace=true"
+                );
+
+        ProcessUtils.getOutputFromCommandCancellable(command,
+                monitor,
+                nullToEmptyString(Messages.CtfTmfTrace_InvokingBabeltrace),
+                /* We don't need to process the output. */
+                (r, m) -> Collections.emptyList());
+    }
+
+    /**
+     * @since 2.2
+     */
+    @Override
+    @SuppressWarnings("nls")
+    public void trim(@NonNull TmfTimeRange range, @NonNull Path destinationPath, @NonNull IProgressMonitor monitor) throws CoreException {
+        verifyBabeltrace2Present();
+
         /* Trim and save the new trace */
         String originPath = getPath();
         if (!originPath.endsWith(File.separator)) {
@@ -780,7 +830,7 @@ public class CtfTmfTrace extends TmfTrace
         String rangeStart = TS_FORMAT.format(range.getStartTime().toNanos());
         String rangeEnd = TS_FORMAT.format(range.getEndTime().toNanos());
 
-        command = Arrays.asList("bash", "-c",
+        List<@NonNull String> command = Arrays.asList("bash", "-c",
                 "babeltrace"
                 + " \"" + originPath + "\""
                 + " --begin " + rangeStart
@@ -804,4 +854,20 @@ public class CtfTmfTrace extends TmfTrace
                 (r, m) -> Collections.emptyList());
     }
 
+    /**
+     * Verify that Babeltrace 2.0 is installed and available.
+     *
+     * @throws CoreException
+     *             Reports this error if Babeltrace 2 is not found
+     */
+    @SuppressWarnings("nls")
+    private static void verifyBabeltrace2Present() throws CoreException {
+        List<@NonNull String> command = Arrays.asList("babeltrace", "--version");
+        @Nullable List<String> output = ProcessUtils.getOutputFromCommand(command);
+        if (output == null || output.isEmpty() || !output.get(0).contains("Babeltrace 2")) {
+            IStatus status = new Status(IStatus.ERROR, Activator.PLUGIN_ID, Messages.CtfTmfTrace_BabelTrace2NotFound);
+            throw new CoreException(status);
+        }
+    }
+
 }
This page took 0.026696 seconds and 5 git commands to generate.