ftrace: Introduce 'Trimmed' ftrace

New CPUs may be made available as buffers come online.
The trace format announces these new resources as
`#comments`

There are now two implementations of text ftrace readers.
1- classic, read the entire trace
2- trimmed, discard everything before the last comment.

Both trace types have a certain value and so they should be kept.

Change-Id: I0b21ddda85c43a948c9a67bde98b8f9093fc5657
Signed-off-by: Matthew Khouzam <matthew.khouzam@ericsson.com>
Reviewed-on: https://git.eclipse.org/r/c/tracecompass.incubator/org.eclipse.tracecompass.incubator/+/183384
Tested-by: Trace Compass Bot <tracecompass-bot@eclipse.org>
Tested-by: Patrick Tasse <patrick.tasse@gmail.com>
Reviewed-by: Patrick Tasse <patrick.tasse@gmail.com>
diff --git a/tracetypes/org.eclipse.tracecompass.incubator.ftrace.core.tests/src/org/eclipse/tracecompass/incubator/ftrace/core/tests/trace/FtraceTraceTest.java b/tracetypes/org.eclipse.tracecompass.incubator.ftrace.core.tests/src/org/eclipse/tracecompass/incubator/ftrace/core/tests/trace/FtraceTraceTest.java
index cc10bb4..8474533 100644
--- a/tracetypes/org.eclipse.tracecompass.incubator.ftrace.core.tests/src/org/eclipse/tracecompass/incubator/ftrace/core/tests/trace/FtraceTraceTest.java
+++ b/tracetypes/org.eclipse.tracecompass.incubator.ftrace.core.tests/src/org/eclipse/tracecompass/incubator/ftrace/core/tests/trace/FtraceTraceTest.java
@@ -15,6 +15,7 @@
 import org.eclipse.core.runtime.IStatus;
 import org.eclipse.tracecompass.incubator.ftrace.core.tests.ActivatorTest;
 import org.eclipse.tracecompass.incubator.internal.ftrace.core.trace.FtraceTrace;
+import org.eclipse.tracecompass.incubator.internal.ftrace.core.trace.TextFtraceTrace;
 import org.junit.Test;
 
 import static org.junit.Assert.assertEquals;
@@ -45,7 +46,7 @@
 
         File[] traceFiles = file.listFiles();
         assertTrue(traceFiles.length > 0);
-        FtraceTrace ftraceTrace = new FtraceTrace();
+        FtraceTrace ftraceTrace = new TextFtraceTrace();
         for (File f : traceFiles) {
             IStatus status = ftraceTrace.validate(null, f.getAbsolutePath());
 
@@ -58,7 +59,7 @@
      */
     @Test
     public void testValidateFileDoesNotExist() {
-        FtraceTrace ftraceTrace = new FtraceTrace();
+        FtraceTrace ftraceTrace = new TextFtraceTrace();
 
         IStatus status = ftraceTrace.validate(null, "");
 
@@ -70,7 +71,7 @@
      */
     @Test
     public void testValidateDirectory() {
-        FtraceTrace ftraceTrace = new FtraceTrace();
+        FtraceTrace ftraceTrace = new TextFtraceTrace();
 
         IStatus status = ftraceTrace.validate(null, "res/");
 
diff --git a/tracetypes/org.eclipse.tracecompass.incubator.ftrace.core.tests/src/org/eclipse/tracecompass/incubator/ftrace/core/tests/trace/TrimmedFtraceTraceTest.java b/tracetypes/org.eclipse.tracecompass.incubator.ftrace.core.tests/src/org/eclipse/tracecompass/incubator/ftrace/core/tests/trace/TrimmedFtraceTraceTest.java
new file mode 100644
index 0000000..c3b4e00
--- /dev/null
+++ b/tracetypes/org.eclipse.tracecompass.incubator.ftrace.core.tests/src/org/eclipse/tracecompass/incubator/ftrace/core/tests/trace/TrimmedFtraceTraceTest.java
@@ -0,0 +1,76 @@
+/*******************************************************************************
+ * Copyright (c) 2021 Ericsson
+ *
+ * All rights reserved. This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0 which
+ * accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *******************************************************************************/
+
+package org.eclipse.tracecompass.incubator.ftrace.core.tests.trace;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.io.File;
+
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.tracecompass.incubator.ftrace.core.tests.ActivatorTest;
+import org.eclipse.tracecompass.incubator.internal.ftrace.core.trace.FtraceTrace;
+import org.eclipse.tracecompass.incubator.internal.ftrace.core.trace.TrimmedFtraceTrace;
+import org.junit.Test;
+
+/**
+ * Ftrace Trace Test Class
+ *
+ * @author Matthew Khouzam
+ */
+public class TrimmedFtraceTraceTest {
+
+    private static final String TRACE_PATH = "res";
+
+    /**
+     * Test validation of ftrace traces
+     */
+    @Test
+    public void testValidate() {
+        IPath path = ActivatorTest.getAbsoluteFilePath(TRACE_PATH);
+        File file = path.toFile();
+
+        File[] traceFiles = file.listFiles();
+        assertTrue(traceFiles.length > 0);
+        FtraceTrace ftraceTrace = new TrimmedFtraceTrace();
+        for (File f : traceFiles) {
+            IStatus status = ftraceTrace.validate(null, f.getAbsolutePath());
+
+            assertEquals("trace " + f, 0, status.getSeverity());
+        }
+    }
+
+    /**
+     * Test validation using file that does not exist
+     */
+    @Test
+    public void testValidateFileDoesNotExist() {
+        FtraceTrace ftraceTrace = new TrimmedFtraceTrace();
+
+        IStatus status = ftraceTrace.validate(null, "");
+
+        assertEquals(0x04, status.getSeverity());
+    }
+
+    /**
+     * Test validation if a directory is passed
+     */
+    @Test
+    public void testValidateDirectory() {
+        FtraceTrace ftraceTrace = new TrimmedFtraceTrace();
+
+        IStatus status = ftraceTrace.validate(null, "res/");
+
+        assertEquals(0x04, status.getSeverity());
+    }
+}
diff --git a/tracetypes/org.eclipse.tracecompass.incubator.ftrace.core/plugin.properties b/tracetypes/org.eclipse.tracecompass.incubator.ftrace.core/plugin.properties
index f207790..46b104b 100644
--- a/tracetypes/org.eclipse.tracecompass.incubator.ftrace.core/plugin.properties
+++ b/tracetypes/org.eclipse.tracecompass.incubator.ftrace.core/plugin.properties
@@ -13,3 +13,4 @@
 Bundle-Name = Trace Compass ftrace Core Plug-in (Incubator)
 trace.ftrace = Raw Textual Ftrace
 trace.ftrace.bin = Binary Ftrace
+trace.ftrace.trimmed = Trimmed Ftrace
\ No newline at end of file
diff --git a/tracetypes/org.eclipse.tracecompass.incubator.ftrace.core/plugin.xml b/tracetypes/org.eclipse.tracecompass.incubator.ftrace.core/plugin.xml
index fe96cd8..18699c4 100644
--- a/tracetypes/org.eclipse.tracecompass.incubator.ftrace.core/plugin.xml
+++ b/tracetypes/org.eclipse.tracecompass.incubator.ftrace.core/plugin.xml
@@ -13,7 +13,7 @@
             id="org.eclipse.tracecompass.incubator.ftrace.core"
             isDirectory="false"
             name="%trace.ftrace"
-            trace_type="org.eclipse.tracecompass.incubator.internal.ftrace.core.trace.FtraceTrace">
+            trace_type="org.eclipse.tracecompass.incubator.internal.ftrace.core.trace.TextFtraceTrace">
       </type>
       <type
             category="org.eclipse.tracecompass.incubator.ftrace.core"
@@ -23,6 +23,14 @@
             name="%trace.ftrace.bin"
             trace_type="org.eclipse.tracecompass.incubator.internal.ftrace.core.trace.BinaryFTrace">
       </type>
+      <type
+            category="org.eclipse.tracecompass.incubator.ftrace.core"
+            event_type="org.eclipse.tracecompass.tmf.core.event.TmfEvent"
+            id="org.eclipse.tracecompass.incubator.ftrace.core.trimmed"
+            isDirectory="false"
+            name="%trace.ftrace.trimmed"
+            trace_type="org.eclipse.tracecompass.incubator.internal.ftrace.core.trace.TrimmedFtraceTrace">
+      </type>
    </extension>
    <extension
          point="org.eclipse.linuxtools.tmf.ui.tracetypeui">
@@ -34,6 +42,10 @@
             icon="icons/ftrace.png"
             tracetype="org.eclipse.tracecompass.incubator.ftrace.core.bin">
       </type>
+      <type
+            icon="icons/ftrace.png"
+            tracetype="org.eclipse.tracecompass.incubator.ftrace.core.trimmed">
+      </type>
    </extension>
    <extension
          point="org.eclipse.linuxtools.tmf.analysis.xml.core.files">
diff --git a/tracetypes/org.eclipse.tracecompass.incubator.ftrace.core/src/org/eclipse/tracecompass/incubator/internal/ftrace/core/trace/FtraceTrace.java b/tracetypes/org.eclipse.tracecompass.incubator.ftrace.core/src/org/eclipse/tracecompass/incubator/internal/ftrace/core/trace/FtraceTrace.java
index 32878ba..6aae70c 100644
--- a/tracetypes/org.eclipse.tracecompass.incubator.ftrace.core/src/org/eclipse/tracecompass/incubator/internal/ftrace/core/trace/FtraceTrace.java
+++ b/tracetypes/org.eclipse.tracecompass.incubator.ftrace.core/src/org/eclipse/tracecompass/incubator/internal/ftrace/core/trace/FtraceTrace.java
@@ -34,7 +34,7 @@
  * @author Pierre-Yves Lajoie
  * @author Eva Terriault
  */
-public class FtraceTrace extends GenericFtrace {
+public abstract class FtraceTrace extends GenericFtrace {
 
     private static final int MAX_LINES = 100;
     private static final int MAX_CONFIDENCE = 100;
diff --git a/tracetypes/org.eclipse.tracecompass.incubator.ftrace.core/src/org/eclipse/tracecompass/incubator/internal/ftrace/core/trace/GenericFtrace.java b/tracetypes/org.eclipse.tracecompass.incubator.ftrace.core/src/org/eclipse/tracecompass/incubator/internal/ftrace/core/trace/GenericFtrace.java
index 48ef3f0..227a4dd 100644
--- a/tracetypes/org.eclipse.tracecompass.incubator.ftrace.core/src/org/eclipse/tracecompass/incubator/internal/ftrace/core/trace/GenericFtrace.java
+++ b/tracetypes/org.eclipse.tracecompass.incubator.ftrace.core/src/org/eclipse/tracecompass/incubator/internal/ftrace/core/trace/GenericFtrace.java
@@ -55,6 +55,7 @@
     private static final int ESTIMATED_EVENT_SIZE = 90;
     private static final TmfLongLocation NULL_LOCATION = new TmfLongLocation(-1L);
     private static final TmfContext INVALID_CONTEXT = new TmfContext(NULL_LOCATION, ITmfContext.UNKNOWN_RANK);
+    private long fFileStart = 0;
 
     /**
      * Trace file locations
@@ -82,11 +83,29 @@
         try {
             fFile = new File(path);
             fFileInput = new BufferedRandomAccessFile(fFile, "r"); //$NON-NLS-1$
+            fFileStart = getFileStart();
         } catch (IOException e) {
             throw new TmfTraceException(e.getMessage(), e);
         }
     }
 
+    /**
+     * Gets the file start
+     *
+     * @return the file start
+     * @throws IOException
+     *             read error
+     */
+    protected long getFileStart() throws IOException {
+        long start = 0;
+        String line = fFileInput.readLine();
+        while (line != null && line.trim().startsWith("#")) { //$NON-NLS-1$
+            start = fFileInput.getFilePointer();
+            line = fFileInput.readLine();
+        }
+        return start;
+    }
+
     @Override
     public synchronized void dispose() {
         setFileInput(null);
@@ -135,7 +154,7 @@
      */
     protected ITmfContext seek(RandomAccessFile fileInput, ITmfLocation location, final TmfContext context) throws IOException {
         if (location == null) {
-            fileInput.seek(0);
+            fileInput.seek(fFileStart);
             long lineStartOffset = fileInput.getFilePointer();
             String line = fileInput.readLine();
             if (line == null) {
@@ -184,7 +203,7 @@
     protected ITmfEvent parseEvent(RandomAccessFile fileInput, TmfLongLocation tmfLongLocation, long rank) {
         Long locationInfo = tmfLongLocation.getLocationInfo();
         if (tmfLongLocation.equals(NULL_LOCATION)) {
-            locationInfo = 0L;
+            locationInfo = fFileStart;
         }
         if (locationInfo != null) {
             try {
diff --git a/tracetypes/org.eclipse.tracecompass.incubator.ftrace.core/src/org/eclipse/tracecompass/incubator/internal/ftrace/core/trace/TextFtraceTrace.java b/tracetypes/org.eclipse.tracecompass.incubator.ftrace.core/src/org/eclipse/tracecompass/incubator/internal/ftrace/core/trace/TextFtraceTrace.java
new file mode 100644
index 0000000..0f88fe2
--- /dev/null
+++ b/tracetypes/org.eclipse.tracecompass.incubator.ftrace.core/src/org/eclipse/tracecompass/incubator/internal/ftrace/core/trace/TextFtraceTrace.java
@@ -0,0 +1,21 @@
+/*******************************************************************************
+ * Copyright (c) 2021 Ericsson
+ *
+ * All rights reserved. This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0 which
+ * accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *******************************************************************************/
+
+package org.eclipse.tracecompass.incubator.internal.ftrace.core.trace;
+
+/**
+ * Textual Ftrace trace.
+ *
+ * @author Matthew Khouzam
+ */
+public class TextFtraceTrace extends FtraceTrace {
+
+}
diff --git a/tracetypes/org.eclipse.tracecompass.incubator.ftrace.core/src/org/eclipse/tracecompass/incubator/internal/ftrace/core/trace/TrimmedFtraceTrace.java b/tracetypes/org.eclipse.tracecompass.incubator.ftrace.core/src/org/eclipse/tracecompass/incubator/internal/ftrace/core/trace/TrimmedFtraceTrace.java
new file mode 100644
index 0000000..d5c2e35
--- /dev/null
+++ b/tracetypes/org.eclipse.tracecompass.incubator.ftrace.core/src/org/eclipse/tracecompass/incubator/internal/ftrace/core/trace/TrimmedFtraceTrace.java
@@ -0,0 +1,54 @@
+/*******************************************************************************
+ * Copyright (c) 2021 Ericsson
+ *
+ * All rights reserved. This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License 2.0 which
+ * accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *******************************************************************************/
+
+package org.eclipse.tracecompass.incubator.internal.ftrace.core.trace;
+
+import java.io.IOException;
+import java.io.RandomAccessFile;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.tracecompass.tmf.core.io.BufferedRandomAccessFile;
+import org.eclipse.tracecompass.tmf.core.trace.TraceValidationStatus;
+
+/**
+ * Trimmed Ftrace trace.
+ *
+ * @author Matthew Khouzam
+ */
+public class TrimmedFtraceTrace extends FtraceTrace {
+
+    @Override
+    public IStatus validate(IProject project, String path) {
+        IStatus status = super.validate(project, path);
+        if (status instanceof TraceValidationStatus) {
+            TraceValidationStatus traceValidationStatus = (TraceValidationStatus) status;
+            status = new TraceValidationStatus(traceValidationStatus.getConfidence() - 1, traceValidationStatus.getPlugin());
+        }
+        return status;
+    }
+
+    @Override
+    protected long getFileStart() throws IOException {
+        long start = 0;
+        try (RandomAccessFile fileInput = new BufferedRandomAccessFile(getFile(), "r")) { //$NON-NLS-1$
+            fileInput.readLine();
+            String line = fileInput.readLine();
+            while (line != null) {
+                if (line.trim().startsWith("#")) { //$NON-NLS-1$
+                    start = fileInput.getFilePointer();
+                }
+                line = fileInput.readLine();
+            }
+        }
+        return start;
+    }
+}