flame chart: Add a getEnd() method to IFlameChartProvider

This should return the end time of the analysis/state system underneath
and it will be used in the data provider to avoid having to wait for the
whole trace to be indexed before returning entries in case the trace
doesn't have a fast way to end time (like trace-event trace).

[Added] A IFlameChartProvider#getEnd method to return end time of the analysis

Change-Id: If3686a7b3fbf2b101b8aac2338fbf05a72980d32
Signed-off-by: Geneviève Bastien <gbastien+lttng@versatic.net>
Reviewed-on: https://git.eclipse.org/r/156015
Tested-by: Trace Compass Bot <tracecompass-bot@eclipse.org>
Reviewed-by: Matthew Khouzam <matthew.khouzam@ericsson.com>
Tested-by: Matthew Khouzam <matthew.khouzam@ericsson.com>
diff --git a/callstack/org.eclipse.tracecompass.incubator.callstack.core/src/org/eclipse/tracecompass/incubator/callstack/core/instrumented/IFlameChartProvider.java b/callstack/org.eclipse.tracecompass.incubator.callstack.core/src/org/eclipse/tracecompass/incubator/callstack/core/instrumented/IFlameChartProvider.java
index 179bca3..6d7766e 100644
--- a/callstack/org.eclipse.tracecompass.incubator.callstack.core/src/org/eclipse/tracecompass/incubator/callstack/core/instrumented/IFlameChartProvider.java
+++ b/callstack/org.eclipse.tracecompass.incubator.callstack.core/src/org/eclipse/tracecompass/incubator/callstack/core/instrumented/IFlameChartProvider.java
@@ -55,6 +55,20 @@
     boolean isComplete();
 
     /**
+     * Return the current end time of this flame chart. The return value of this
+     * method may change as long as the {@link #isComplete()} method returns
+     * <code>false</code>. When the flame chart is complete, then this value
+     * should stay the same.
+     *
+     * If the value is not known, impossible to compute or not available, the
+     * return value should be {@link Integer#MIN_VALUE}.
+     *
+     * @return The end time of the flame chart, in nanoseconds, or
+     *         {@link Integer#MIN_VALUE} if end time is not available.
+     */
+    long getEnd();
+
+    /**
      * Query the requested callstacks and return the segments for the sampled times.
      * The returned segments will be simply {@link ISegment} when there is no
      * function at a given depth, or {@link ICalledFunction} when there is an actual
diff --git a/callstack/org.eclipse.tracecompass.incubator.callstack.core/src/org/eclipse/tracecompass/incubator/callstack/core/instrumented/statesystem/InstrumentedCallStackAnalysis.java b/callstack/org.eclipse.tracecompass.incubator.callstack.core/src/org/eclipse/tracecompass/incubator/callstack/core/instrumented/statesystem/InstrumentedCallStackAnalysis.java
index 891546c..c2be79e 100644
--- a/callstack/org.eclipse.tracecompass.incubator.callstack.core/src/org/eclipse/tracecompass/incubator/callstack/core/instrumented/statesystem/InstrumentedCallStackAnalysis.java
+++ b/callstack/org.eclipse.tracecompass.incubator.callstack.core/src/org/eclipse/tracecompass/incubator/callstack/core/instrumented/statesystem/InstrumentedCallStackAnalysis.java
@@ -347,6 +347,19 @@
     }
 
     @Override
+    public long getEnd() {
+        // Initialization error, but the analysis is completed
+        if (!waitForInitialization()) {
+            return Integer.MIN_VALUE;
+        }
+        ITmfStateSystem stateSystem = getStateSystem();
+        if (stateSystem == null) {
+            throw new IllegalStateException("The initialiation is complete, so the state system must not be null"); //$NON-NLS-1$
+        }
+        return stateSystem.getCurrentEndTime();
+    }
+
+    @Override
     public @NonNull List<@NonNull String> getExtraDataSets() {
         return fCallGraph.getExtraDataSets();
     }
diff --git a/callstack/org.eclipse.tracecompass.incubator.callstack.core/src/org/eclipse/tracecompass/incubator/internal/callstack/core/instrumented/provider/FlameChartDataProvider.java b/callstack/org.eclipse.tracecompass.incubator.callstack.core/src/org/eclipse/tracecompass/incubator/internal/callstack/core/instrumented/provider/FlameChartDataProvider.java
index 70e23b7..639c410 100644
--- a/callstack/org.eclipse.tracecompass.incubator.callstack.core/src/org/eclipse/tracecompass/incubator/internal/callstack/core/instrumented/provider/FlameChartDataProvider.java
+++ b/callstack/org.eclipse.tracecompass.incubator.callstack.core/src/org/eclipse/tracecompass/incubator/internal/callstack/core/instrumented/provider/FlameChartDataProvider.java
@@ -416,7 +416,7 @@
                 return new TmfModelResponse<>(null, ITmfResponse.Status.FAILED, CommonStatusMessage.ANALYSIS_INITIALIZATION_FAILED);
             }
             long start = getTrace().getStartTime().getValue();
-            long end = getTrace().readEnd().getValue();
+            long end = Math.max(start, fcProvider.getEnd());
 
             // Initialize the first element of the tree
             ImmutableList.Builder<FlameChartEntryModel> builder = ImmutableList.builder();
diff --git a/callstack/org.eclipse.tracecompass.incubator.callstack.core/src/org/eclipse/tracecompass/incubator/internal/callstack/core/xml/callstack/CallstackXmlAnalysis.java b/callstack/org.eclipse.tracecompass.incubator.callstack.core/src/org/eclipse/tracecompass/incubator/internal/callstack/core/xml/callstack/CallstackXmlAnalysis.java
index 6a6582b..c95583f 100644
--- a/callstack/org.eclipse.tracecompass.incubator.callstack.core/src/org/eclipse/tracecompass/incubator/internal/callstack/core/xml/callstack/CallstackXmlAnalysis.java
+++ b/callstack/org.eclipse.tracecompass.incubator.callstack.core/src/org/eclipse/tracecompass/incubator/internal/callstack/core/xml/callstack/CallstackXmlAnalysis.java
@@ -386,6 +386,19 @@
     }
 
     @Override
+    public long getEnd() {
+        // Initialization error, but the analysis is completed
+        if (!waitForInitialization()) {
+            return Integer.MIN_VALUE;
+        }
+        Iterator<ITmfStateSystem> iterator = getStateSystems().iterator();
+        if (!iterator.hasNext()) {
+            throw new IllegalStateException("The initialization is complete, so the state system must not be null"); //$NON-NLS-1$
+        }
+        return iterator.next().getCurrentEndTime();
+    }
+
+    @Override
     public List<String> getExtraDataSets() {
         return fCallGraph.getExtraDataSets();
     }