tmf: Cache CallStackEvent names
authorAlexandre Montplaisir <alexmonthy@efficios.com>
Thu, 30 Jun 2016 20:55:31 +0000 (16:55 -0400)
committerAlexandre Montplaisir <alexmonthy@efficios.com>
Thu, 14 Jul 2016 16:30:47 +0000 (12:30 -0400)
This will avoid calling the symbol provider repeatedly, which
equates to a state system query + calling an external process
for LTTng-UST traces, for examples.

Change-Id: I798c0d253b2ba83529c98b99b70481430ea1a613
Signed-off-by: Alexandre Montplaisir <alexmonthy@efficios.com>
Reviewed-on: https://git.eclipse.org/r/76400
Reviewed-by: Hudson CI
tmf/org.eclipse.tracecompass.tmf.ui/META-INF/MANIFEST.MF
tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/callstack/CallStackEvent.java
tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/callstack/CallStackPresentationProvider.java
tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/views/callstack/CallStackView.java
tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/tmf/ui/widgets/timegraph/model/TimeEvent.java

index e3ffcebb4c441ec740f4bca3c4b0031fc39e4ecb..77609d5973ab82184b3cdfaa09890ab4043c6b28 100644 (file)
@@ -108,6 +108,7 @@ Export-Package: org.eclipse.tracecompass.internal.tmf.ui;x-friends:="org.eclipse
  org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets,
  org.eclipse.tracecompass.tmf.ui.widgets.virtualtable
 Import-Package: com.google.common.base,
+ com.google.common.cache,
  com.google.common.collect,
  org.eclipse.emf.common.util,
  org.eclipse.emf.ecore
index e56959052eaf2872533997e1669544ce3e770494..c2782e29e1634af49267072a4d0d3a7d5b0af559 100644 (file)
@@ -36,4 +36,14 @@ public class CallStackEvent extends TimeEvent {
     public CallStackEvent(CallStackEntry entry, long time, long duration, int value) {
         super(entry, time, duration, value);
     }
+
+    /**
+     * @since 2.1
+     */
+    @Override
+    public CallStackEntry getEntry() {
+        /* Type enforced at constructor */
+        return (CallStackEntry) fEntry;
+    }
+
 }
index 2631bc72f0300b72c3391ef971d15a12fa08cb81..b6478f028afb0a3c7823b7e89b9b55bf5875dba3 100644 (file)
@@ -12,6 +12,8 @@
 
 package org.eclipse.tracecompass.tmf.ui.views.callstack;
 
+import java.util.Optional;
+
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.graphics.GC;
 import org.eclipse.swt.graphics.RGB;
@@ -29,6 +31,10 @@ import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.ITimeGraphEntry;
 import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.NullTimeEvent;
 import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.Utils;
 
+import com.google.common.cache.CacheBuilder;
+import com.google.common.cache.CacheLoader;
+import com.google.common.cache.LoadingCache;
+
 /**
  * Presentation provider for the Call Stack view, based on the generic TMF
  * presentation provider.
@@ -44,6 +50,28 @@ public class CallStackPresentationProvider extends TimeGraphPresentationProvider
 
     private Integer fAverageCharWidth;
 
+    private final LoadingCache<CallStackEvent, Optional<String>> fTimeEventNames = CacheBuilder.newBuilder()
+            .maximumSize(1000)
+            .build(new CacheLoader<CallStackEvent, Optional<String>>() {
+                @Override
+                public Optional<String> load(CallStackEvent event) {
+                    CallStackEntry entry = event.getEntry();
+                    ITmfStateSystem ss = entry.getStateSystem();
+                    try {
+                        ITmfStateValue value = ss.querySingleState(event.getTime(), entry.getQuark()).getStateValue();
+                        if (!value.isNull()) {
+                            String name = fView.getFunctionName(entry.getTrace(), entry.getProcessId(), event.getTime(), value);
+                            return Optional.ofNullable(name);
+                        }
+                    } catch (TimeRangeException e) {
+                        Activator.getDefault().logError("Error querying state system", e); //$NON-NLS-1$
+                    } catch (StateSystemDisposedException e) {
+                        /* Ignored */
+                    }
+                    return Optional.empty();
+                }
+            });
+
     private enum State {
         MULTIPLE (new RGB(100, 100, 100)),
         EXEC     (new RGB(0, 200, 0));
@@ -106,19 +134,7 @@ public class CallStackPresentationProvider extends TimeGraphPresentationProvider
     @Override
     public String getEventName(ITimeEvent event) {
         if (event instanceof CallStackEvent) {
-            CallStackEntry entry = (CallStackEntry) event.getEntry();
-            ITmfStateSystem ss = entry.getStateSystem();
-            try {
-                ITmfStateValue value = ss.querySingleState(event.getTime(), entry.getQuark()).getStateValue();
-                if (!value.isNull()) {
-                    return fView.getFunctionName(entry.getTrace(), entry.getProcessId(), event.getTime(), value);
-                }
-            } catch (TimeRangeException e) {
-                Activator.getDefault().logError("Error querying state system", e); //$NON-NLS-1$
-            } catch (StateSystemDisposedException e) {
-                /* Ignored */
-            }
-            return null;
+            return fTimeEventNames.getUnchecked((CallStackEvent) event).orElse(null);
         }
         return State.MULTIPLE.toString();
     }
@@ -134,20 +150,17 @@ public class CallStackPresentationProvider extends TimeGraphPresentationProvider
         if (!(event instanceof CallStackEvent)) {
             return;
         }
-        CallStackEntry entry = (CallStackEntry) event.getEntry();
-        ITmfStateSystem ss = entry.getStateSystem();
-        try {
-            ITmfStateValue value = ss.querySingleState(event.getTime(), entry.getQuark()).getStateValue();
-            if (!value.isNull()) {
-                String name = fView.getFunctionName(entry.getTrace(), entry.getProcessId(), event.getTime(), value);
-                gc.setForeground(gc.getDevice().getSystemColor(SWT.COLOR_WHITE));
-                Utils.drawText(gc, name, bounds.x, bounds.y, bounds.width, bounds.height, true, true);
-            }
-        } catch (TimeRangeException e) {
-            Activator.getDefault().logError("Error querying state system", e); //$NON-NLS-1$
-        } catch (StateSystemDisposedException e) {
-            /* Ignored */
-        }
+        String name = fTimeEventNames.getUnchecked((CallStackEvent) event).orElse(null);
+        gc.setForeground(gc.getDevice().getSystemColor(SWT.COLOR_WHITE));
+        Utils.drawText(gc, name, bounds.x, bounds.y, bounds.width, bounds.height, true, true);
+    }
+
+    /**
+     * Indicate that the provider of function names has changed, so any cached
+     * values must be reset.
+     */
+    void resetFunctionNames() {
+        fTimeEventNames.invalidateAll();
     }
 
 }
index 5f4524cc179d3c4b1dc422df7382b70638b65a53..749bc3ce672d821b99e8daa35811dd63025a8018 100644 (file)
@@ -361,7 +361,7 @@ public class CallStackView extends AbstractTimeGraphView {
      */
     public CallStackView() {
         super(ID, new CallStackPresentationProvider());
-        ((CallStackPresentationProvider) getPresentationProvider()).setCallStackView(this);
+        getPresentationProvider().setCallStackView(this);
         setTreeColumns(COLUMN_NAMES);
         setTreeLabelProvider(new CallStackTreeLabelProvider());
         setEntryComparator(new CallStackComparator());
@@ -501,6 +501,15 @@ public class CallStackView extends AbstractTimeGraphView {
     // Internal
     // ------------------------------------------------------------------------
 
+    /**
+     * @since 2.1
+     */
+    @Override
+    protected CallStackPresentationProvider getPresentationProvider() {
+        /* Set to this type by the constructor */
+        return (CallStackPresentationProvider) super.getPresentationProvider();
+    }
+
     @Override
     @TmfSignalHandler
     public void traceClosed(TmfTraceClosedSignal signal) {
@@ -1220,6 +1229,7 @@ public class CallStackView extends AbstractTimeGraphView {
             public void run() {
                 SymbolProviderConfigDialog dialog = new SymbolProviderConfigDialog(getSite().getShell(), getProviderPages());
                 if (dialog.open() == IDialogConstants.OK_ID) {
+                    getPresentationProvider().resetFunctionNames();
                     refresh();
                 }
             }
index 189b8bafc38fb07860eee62a217e7c7a2bb42ca5..c66ea4d8f15f4d0fd19d424c0121a0562e9edaa2 100644 (file)
@@ -13,6 +13,8 @@
 
 package org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model;
 
+import java.util.Objects;
+
 /**
  * Generic TimeEvent implementation
  *
@@ -120,6 +122,29 @@ public class TimeEvent implements ITimeEvent {
                 null);
     }
 
+    @Override
+    public int hashCode() {
+        return Objects.hash(fEntry, fTime, fDuration, fValue);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj == null) {
+            return false;
+        }
+        if (getClass() != obj.getClass()) {
+            return false;
+        }
+        TimeEvent other = (TimeEvent) obj;
+        return Objects.equals(fEntry, other.fEntry) &&
+                Objects.equals(fTime, other.fTime) &&
+                Objects.equals(fDuration, other.fDuration) &&
+                Objects.equals(fValue, other.fValue);
+    }
+
     @Override
     public String toString() {
         return getClass().getSimpleName() + " start=" + fTime + " end=" + (fTime + fDuration) + " duration=" + fDuration + (hasValue() ? (" value=" + fValue) : ""); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
This page took 0.02824 seconds and 5 git commands to generate.