timing: Fix duration of flamegraph view
[deliverable/tracecompass.git] / analysis / org.eclipse.tracecompass.analysis.timing.ui / src / org / eclipse / tracecompass / internal / analysis / timing / ui / flamegraph / FlameGraphContentProvider.java
index f38a28c71a92aceab4b840abcb040e8b0ddf8ecc..02a6c70ca7c38c5413ddec98609438d01f8233fe 100644 (file)
@@ -9,14 +9,17 @@
 
 package org.eclipse.tracecompass.internal.analysis.timing.ui.flamegraph;
 
+import static org.eclipse.tracecompass.common.core.NonNullUtils.checkNotNull;
+
 import java.util.ArrayDeque;
 import java.util.ArrayList;
 import java.util.Comparator;
 import java.util.Deque;
 import java.util.List;
 
+import org.eclipse.jdt.annotation.NonNull;
 import org.eclipse.jface.viewers.Viewer;
-import org.eclipse.tracecompass.common.core.NonNullUtils;
+
 import org.eclipse.tracecompass.internal.analysis.timing.core.callgraph.AggregatedCalledFunction;
 import org.eclipse.tracecompass.internal.analysis.timing.core.callgraph.ThreadNode;
 import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
@@ -25,8 +28,6 @@ import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.ITimeGraphContentProvid
 import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.ITimeGraphEntry;
 import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.TimeGraphEntry;
 
-import com.google.common.collect.Lists;
-
 /**
  * Content provider for the flame graph view
  *
@@ -35,9 +36,11 @@ import com.google.common.collect.Lists;
  */
 public class FlameGraphContentProvider implements ITimeGraphContentProvider {
 
-    private List<FlamegraphDepthEntry> fFlameGraphEntries = new ArrayList<>();
-    private long fThreadDuration;
+    private final List<FlamegraphDepthEntry> fFlameGraphEntries = new ArrayList<>();
     private ITmfTrace fActiveTrace;
+    private SortOption fSortOption = SortOption.BY_NAME;
+    private @NonNull Comparator<FlamegraphDepthEntry> fThreadComparator = new ThreadNameComparator();
+
 
     /**
      * Parse the aggregated tree created by the callGraphAnalysis and creates
@@ -51,16 +54,19 @@ public class FlameGraphContentProvider implements ITimeGraphContentProvider {
      *            A stack used to save the functions timeStamps
      */
     private void setData(AggregatedCalledFunction firstNode, List<FlamegraphDepthEntry> childrenEntries, Deque<Long> timestampStack) {
+        long lastEnd = timestampStack.peek();
         for (int i = 0; i < firstNode.getMaxDepth(); i++) {
             if (i >= childrenEntries.size()) {
-                FlamegraphDepthEntry entry = new FlamegraphDepthEntry(String.valueOf(i), 0, fActiveTrace.getEndTime().toNanos() - fActiveTrace.getStartTime().toNanos(), i, i);
+                FlamegraphDepthEntry entry = new FlamegraphDepthEntry(String.valueOf(i), 0, firstNode.getDuration(), i, i);
                 childrenEntries.add(entry);
             }
+            childrenEntries.get(i).updateEndTime(lastEnd + firstNode.getDuration());
         }
-        FlamegraphDepthEntry firstEntry = NonNullUtils.checkNotNull(childrenEntries.get(0));
-        firstEntry.addEvent(new FlamegraphEvent(firstEntry, timestampStack.peek(), firstNode));
+        FlamegraphDepthEntry firstEntry = checkNotNull(childrenEntries.get(0));
+        firstEntry.addEvent(new FlamegraphEvent(firstEntry, lastEnd, firstNode));
         // Build the event list for next entries (next depth)
         addEvent(firstNode, childrenEntries, timestampStack);
+        timestampStack.pop();
     }
 
     /**
@@ -88,7 +94,7 @@ public class FlameGraphContentProvider implements ITimeGraphContentProvider {
                 timestampStack.pop();
             });
         }
-        FlamegraphDepthEntry entry = NonNullUtils.checkNotNull(childrenEntries.get(node.getDepth()));
+        FlamegraphDepthEntry entry = checkNotNull(childrenEntries.get(node.getDepth()));
         // Create the event corresponding to the function using the caller's
         // timestamp
         entry.addEvent(new FlamegraphEvent(entry, timestampStack.peek(), node));
@@ -117,8 +123,8 @@ public class FlameGraphContentProvider implements ITimeGraphContentProvider {
                 }
             }
         }
-        // Reverse the order of threads
-        fFlameGraphEntries = Lists.reverse(fFlameGraphEntries);
+        // Sort the threads
+        fFlameGraphEntries.sort(fThreadComparator);
         return fFlameGraphEntries.toArray(new ITimeGraphEntry[fFlameGraphEntries.size()]);
     }
 
@@ -129,24 +135,24 @@ public class FlameGraphContentProvider implements ITimeGraphContentProvider {
      *            The node of the aggregation tree
      */
     private void buildChildrenEntries(ThreadNode threadNode) {
-        FlamegraphDepthEntry threadEntry = new FlamegraphDepthEntry("", 0, fActiveTrace.getEndTime().toNanos() - fActiveTrace.getStartTime().toNanos(), fFlameGraphEntries.size(), threadNode.getId()); //$NON-NLS-1$
+        FlamegraphDepthEntry threadEntry = new FlamegraphDepthEntry("", 0, 0, fFlameGraphEntries.size(), threadNode.getId()); //$NON-NLS-1$
         List<FlamegraphDepthEntry> childrenEntries = new ArrayList<>();
-        fThreadDuration = 0L;
+        Deque<Long> timestampStack = new ArrayDeque<>();
+        timestampStack.push(0L);
         // Sort children by duration
         threadNode.getChildren().stream()
                 .sorted(Comparator.comparingLong(AggregatedCalledFunction::getDuration))
                 .forEach(rootFunction -> {
-                    Deque<Long> timestampStack = new ArrayDeque<>();
-                    timestampStack.push(fThreadDuration);
                     setData(rootFunction, childrenEntries, timestampStack);
-                    fThreadDuration += rootFunction.getDuration();
-                    timestampStack.pop();
+                    long currentThreadDuration = timestampStack.pop() + rootFunction.getDuration();
+                    timestampStack.push(currentThreadDuration);
                 });
         childrenEntries.forEach(child -> {
             if (child != null) {
                 threadEntry.addChild(child);
             }
         });
+        threadEntry.updateEndTime(timestampStack.pop());
         threadEntry.setName(threadNode.getSymbol().toString());
         fFlameGraphEntries.add(threadEntry);
     }
@@ -172,4 +178,40 @@ public class FlameGraphContentProvider implements ITimeGraphContentProvider {
         // Do nothing
     }
 
+
+    /**
+     * Get the sort option
+     *
+     * @return the sort option.
+     */
+    public SortOption getSortOption() {
+        return fSortOption;
+    }
+
+    /**
+     * Set the sort option for sorting the thread entries
+     *
+     * @param sortOption
+     *              the sort option to set
+     *
+     */
+    public void setSortOption(SortOption sortOption) {
+        fSortOption = sortOption;
+        switch (sortOption) {
+        case BY_NAME:
+            fThreadComparator = new ThreadNameComparator();
+            break;
+        case BY_NAME_REV:
+            fThreadComparator = checkNotNull(new ThreadNameComparator().reversed());
+            break;
+        case BY_ID:
+            fThreadComparator = new ThreadIdComparator();
+            break;
+        case BY_ID_REV:
+            fThreadComparator = checkNotNull(new ThreadIdComparator().reversed());
+            break;
+        default:
+            break;
+        }
+    }
 }
This page took 0.02628 seconds and 5 git commands to generate.