}
/**
+ * 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)) {
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
(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);
+ }
+ }
+
}