Skip to content

Commit

Permalink
execution comparison:
Browse files Browse the repository at this point in the history
Differential flame graph view is updated to
be able to show and hide Query part by demand.

grouping are added to hamburger menu

Dependencies to incubator for callstack and weighted tree packages are reslved

changing in time ranges or in query reflect in graphical treeview and density charts

Adding the reset Button to select entire trace (back to initial state)

TODO

* Add progress bar
* instrument code(pretty good)
* add test
* make a registry for traceTYpe->callstack ID

Signed-off-by: fariba <[email protected]>
  • Loading branch information
farajidaneshgar committed Apr 28, 2024
1 parent c3b4c1c commit 8cf63a9
Show file tree
Hide file tree
Showing 11 changed files with 652 additions and 439 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,19 +13,20 @@

import java.util.Collection;

import org.eclipse.tracecompass.analysis.profiling.core.base.ICallStackElement;
import org.eclipse.tracecompass.analysis.profiling.core.base.ICallStackSymbol;
import org.eclipse.tracecompass.analysis.profiling.core.base.IDataPalette;
import org.eclipse.tracecompass.analysis.profiling.core.callgraph.AggregatedCallSite;
import org.eclipse.tracecompass.analysis.profiling.core.callgraph.ICallGraphProvider2;
import org.eclipse.tracecompass.analysis.profiling.core.base.ICallStackSymbol;
import org.eclipse.tracecompass.analysis.profiling.core.base.IDataPalette;
import org.eclipse.tracecompass.analysis.profiling.core.tree.IWeightedTreeProvider;
import org.eclipse.tracecompass.analysis.profiling.core.tree.WeightedTree;
import org.eclipse.tracecompass.analysis.profiling.core.base.ICallStackElement;
import org.eclipse.tracecompass.incubator.analysis.core.weighted.tree.diff.DifferentialWeightedTree;
import org.eclipse.tracecompass.incubator.analysis.core.weighted.tree.diff.DifferentialWeightedTreeProvider;
import org.eclipse.tracecompass.incubator.analysis.core.weighted.tree.diff.DifferentialWeightedTreeSet;

/**
*
* DifferentialCallGraphProvider which provide a callgraphProvider. Inherited from DifferentialWeightedTreeProvider
* to edit naming and color ICallGraphProviderpalette to provide a differential flame graph
* @author Fateme Faraji Daneshgar
*/
public class DifferentialCallGraphProvider extends DifferentialWeightedTreeProvider<ICallStackSymbol> {
Expand Down Expand Up @@ -86,4 +87,4 @@ public String toDisplayString(DifferentialWeightedTree<ICallStackSymbol> tree) {

}

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ private static String generateBlue(int i) {
StyleProperties.BACKGROUND_COLOR, WHITE_COLOR,
StyleProperties.OPACITY, 1,
StyleProperties.BORDER_STYLE, StyleProperties.BorderStyle.SOLID)));
// Add Blue tenses for Shorter duration
// Add Blue color palette for Shorter duration
for (i = MIN_HUE; i <= MAX_HUE; i++) {
j = (i-50)>0 ? i-50:0;
String blueKey = generateBlue(i);
Expand All @@ -96,7 +96,7 @@ private static String generateBlue(int i) {
StyleProperties.OPACITY, 1,
StyleProperties.BORDER_STYLE, StyleProperties.BorderStyle.SOLID)));
}
// Add Red tenses for Longer duration
// Add Red color palette for Longer duration
for (i = MIN_HUE; i <= MAX_HUE; i++) {
String redKey = generateRed(i);
builder.put(redKey, new OutputElementStyle(null, ImmutableMap.of(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ public DifferentialSeqCallGraphAnalysis() {
super();
// TODO: Make a way to register tracetype->callstack IDs.
fcallStackAnalysisMap.put("org.eclipse.tracecompass.incubator.traceevent.core.trace", "org.eclipse.tracecompass.incubator.traceevent.analysis.callstack"); //$NON-NLS-1$ //$NON-NLS-2$
fcallStackAnalysisMap.put("org.eclipse.linuxtools.lttng2.ust.tracetype", "org.eclipse.tracecompass.incubator.callstack.core.lttng.ust"); //$NON-NLS-1$ //$NON-NLS-2$
fcallStackAnalysisMap.put("org.eclipse.linuxtools.lttng2.ust.tracetype", "org.eclipse.tracecompass.lttng2.ust.core.analysis.callstack"); //$NON-NLS-1$ //$NON-NLS-2$
}

/**
Expand All @@ -119,7 +119,7 @@ public void refreshDiffCG(@Nullable IProgressMonitor monitor) {
}

Collection<DifferentialWeightedTree<ICallStackSymbol>> trees;
trees = ParametricWeightedTreeUtils.diffTrees(originalTree, diffTree, fStatistic);
trees = ParametricWeightedTreeUtils.diffTrees(originalTree, diffTree, fStatistic);

IWeightedTreeProvider<ICallStackSymbol, ICallStackElement, AggregatedCallSite> instrumentedCallStackAnalysis = Iterables.get(fTraceCallGraphRegistry.values(), 0);
setDifferentialCallGraphProvider(new DifferentialCallGraphProvider(instrumentedCallStackAnalysis, trees));
Expand Down Expand Up @@ -147,7 +147,18 @@ public WeightedTreeSet<ICallStackSymbol, Object> mergeCallGraph(ITmfTimestamp st
for (String traceName : traceList) {
ICallGraphProvider2 instrumentedCallStackAnalysis = fTraceCallGraphRegistry.get(traceName);
if (instrumentedCallStackAnalysis != null) {
cGList.add(instrumentedCallStackAnalysis.getCallGraph(start, end));
ITmfTrace trace = getTrace(traceName);
ITmfTimestamp traceStart = start;
ITmfTimestamp traceEnd = end;

if (traceStart.getValue()< trace.getStartTime().getValue()) {
traceStart = trace.getStartTime();
}
if (traceEnd.getValue()> trace.getEndTime().getValue()) {
traceEnd = trace.getEndTime();
}
cGList.add(instrumentedCallStackAnalysis.getCallGraph(traceStart, traceEnd));

}
}

Expand Down Expand Up @@ -314,7 +325,7 @@ public void selectionRangeUpdated(TmfComparisonFilteringUpdatedSignal signal) {
try (ScopeLog sl = new ScopeLog(LOGGER, Level.FINE, "MakeDiffCallGraph")) { //$NON-NLS-1$
synchronized (this) {
if (fDiffJob != null) {
fDiffJob.join();
fDiffJob.cancel();
}
fDiffJob = new Job("Make differential Callgraph") { //$NON-NLS-1$
@Override
Expand All @@ -328,11 +339,8 @@ protected IStatus run(@Nullable IProgressMonitor monitor) {
};
fDiffJob.schedule();
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}

}

@Override
Expand Down Expand Up @@ -360,7 +368,16 @@ public void dispose() {
*/
private void setDifferentialCallGraphProvider(DifferentialCallGraphProvider differentialCallGraphProvider) {
fDifferentialCallGraphProvider = Objects.requireNonNull(differentialCallGraphProvider);

}
private static ITmfTrace getTrace(String traceName) {
ITmfTrace trace = TmfTraceManager.getInstance().getActiveTrace();
Collection<ITmfTrace> traceSet = TmfTraceManager.getTraceSet(trace);
for (ITmfTrace traceMember : traceSet) {
if (traceMember.getName().equals(traceName)) {
return traceMember;
}
}
return null;
}

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -235,4 +235,4 @@ private ParametricWeightedTreeUtils() {
return null;
}

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@ Require-Bundle: org.eclipse.ui,
org.eclipse.tracecompass.common.core,
org.eclipse.tracecompass.tmf.core,
org.eclipse.tracecompass.tmf.ui,
org.eclipse.tracecompass.incubator.callstack.ui,
org.eclipse.tracecompass.incubator.callstack.core,
org.eclipse.tracecompass.incubator.analysis.core,
org.eclipse.tracecompass.incubator.executioncomparision.core,
org.eclipse.jdt.annotation;bundle-version="[2.0.0,3.0.0)";resolution:=optional,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

<view
category="org.eclipse.linuxtools.tmf.ui.views.category"
class="org.eclipse.tracecompass.incubator.internal.executioncomparision.ui.MultipleDensityView"
class="org.eclipse.tracecompass.incubator.internal.executioncomparision.ui.ExecutionComparisonView"
id="org.eclipse.tracecompass.incubator.internal.entexecutioncomparison.ui.execComparison"
name="Execution Comparision"
restorable="true">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,7 @@
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.GroupMarker;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.swt.SWT;
Expand All @@ -52,17 +48,14 @@
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.tracecompass.analysis.profiling.core.callgraph.ICallGraphProvider;
import org.eclipse.tracecompass.analysis.profiling.core.callgraph.ICallGraphProvider2;
import org.eclipse.tracecompass.common.core.NonNullUtils;
import org.eclipse.tracecompass.common.core.log.TraceCompassLogUtils.FlowScopeLog;
import org.eclipse.tracecompass.common.core.log.TraceCompassLogUtils.FlowScopeLogBuilder;
import org.eclipse.tracecompass.common.core.log.TraceCompassLogUtils.ScopeLog;
import org.eclipse.tracecompass.incubator.analysis.core.weighted.tree.diff.DifferentialWeightedTreeProvider;
import org.eclipse.tracecompass.incubator.internal.callstack.ui.flamegraph.DataProviderActionUtils;
import org.eclipse.tracecompass.incubator.internal.executioncomparision.core.DifferentialSeqCallGraphAnalysis;
import org.eclipse.tracecompass.internal.analysis.profiling.core.flamegraph.DataProviderUtils;
import org.eclipse.tracecompass.internal.analysis.profiling.core.flamegraph.FlameGraphDataProvider;
import org.eclipse.tracecompass.incubator.internal.executioncomparision.core.DifferentialSeqCallGraphAnalysis;
import org.eclipse.tracecompass.internal.provisional.tmf.core.model.filters.TmfFilterAppliedSignal;
import org.eclipse.tracecompass.internal.provisional.tmf.core.model.filters.TraceCompassFilter;
import org.eclipse.tracecompass.internal.provisional.tmf.ui.widgets.timegraph.BaseDataProviderTimeGraphPresentationProvider;
Expand Down Expand Up @@ -106,7 +99,6 @@
import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.TimeGraphControl;
import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.Utils.TimeFormat;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IWorkbenchActionConstants;
import org.eclipse.ui.IWorkbenchPartSite;
import org.eclipse.ui.progress.IWorkbenchSiteProgressService;

Expand All @@ -116,7 +108,7 @@
import com.google.common.collect.Multimap;

/**
* the flame graph part of the differential flame graph.
* the differential flame graph used in execution comparison view. Its mostly based on FlameGraphView
*
* @author Fateme Faraji Daneshgar
*
Expand All @@ -143,7 +135,6 @@ public class DifferentialFlameGraphView extends TmfView {

private @Nullable ITmfTrace fTrace = null;

private final MenuManager fEventMenuManager = new MenuManager();
/**
* A plain old semaphore is used since different threads will be competing
* for the same resource.
Expand Down Expand Up @@ -210,7 +201,6 @@ public void createPartControl(@Nullable Composite parent) {
}
TmfSignalManager.register(this);
getSite().setSelectionProvider(getTimeGraphViewer().getSelectionProvider());
createTimeEventContextMenu();
getTimeGraphViewer().getTimeGraphControl().addMouseListener(new MouseAdapter() {
@Override
public void mouseDoubleClick(@Nullable MouseEvent e) {
Expand Down Expand Up @@ -319,13 +309,13 @@ public void traceSelected(final TmfTraceSelectedSignal signal) {
*
* @return The call graph provider modules
*/
protected Iterable<ICallGraphProvider> getCallgraphModules() {
protected Iterable<ICallGraphProvider2> getCallgraphModules() {
ITmfTrace trace = fTrace;
if (trace == null) {
return Collections.emptyList();
}
String analysisId = NonNullUtils.nullToEmptyString(getViewSite().getSecondaryId());
Iterable<ICallGraphProvider> modules = TmfTraceUtils.getAnalysisModulesOfClass(trace, ICallGraphProvider.class);
Iterable<ICallGraphProvider2> modules = TmfTraceUtils.getAnalysisModulesOfClass(trace, ICallGraphProvider2.class);
return StreamSupport.stream(modules.spliterator(), false)
.filter(m -> {
if (m instanceof IAnalysisModule) {
Expand Down Expand Up @@ -464,6 +454,9 @@ private void buildEntryList(@Nullable ITmfTrace trace, ITmfTrace parentTrace, Ma
}

if (monitor.isCanceled()) {
if (trace==null) {
return;
}
resetEntries(trace);
return;
}
Expand Down Expand Up @@ -733,7 +726,10 @@ private void zoomEntries(Iterable<TimeGraphEntry> normalEntries, long zoomStartT
List<Long> times = StateSystemUtils.getTimes(start, end, resolution);
Sampling sampling = new Sampling(start, end, resolution);


Multimap<ITimeGraphDataProvider<? extends TimeGraphEntryModel>, Long> providersToModelIds = filterGroupEntries(normalEntries, zoomStartTime, zoomEndTime);
if (providersToModelIds!=null) {

SubMonitor subMonitor = SubMonitor.convert(monitor, getClass().getSimpleName() + "#zoomEntries", providersToModelIds.size()); //$NON-NLS-1$

Entry<ITimeGraphDataProvider<? extends TimeGraphEntryModel>, Collection<Long>> entry = providersToModelIds.asMap().entrySet().iterator().next();
Expand All @@ -746,16 +742,14 @@ private void zoomEntries(Iterable<TimeGraphEntry> normalEntries, long zoomStartT
}
TmfModelResponse<TimeGraphModel> response = dataProvider.fetchRowModel(parameters, monitor);
TimeGraphModel model = response.getModel();
if ((model != null) && (fEntries.get(dataProvider)) != null) {
System.out.println(
"zommEntries: Current Thread Name: "
+ Thread.currentThread().getName());

zoomEntries(fEntries.get(dataProvider), model.getRows(), response.getStatus() == ITmfResponse.Status.COMPLETED, sampling);
Map<Long,TimeGraphEntry> entries = fEntries.get(dataProvider);
if ((model != null) && (entries) != null) {
zoomEntries(entries, model.getRows(), response.getStatus() == ITmfResponse.Status.COMPLETED, sampling);

}
subMonitor.worked(1);
redraw();
}
}

/**
Expand All @@ -767,6 +761,7 @@ private void zoomEntries(Iterable<TimeGraphEntry> normalEntries, long zoomStartT
*
* @return The multimap of regexes by property
*/
@SuppressWarnings("null")
private Multimap<Integer, String> getRegexes() {
Multimap<Integer, String> regexes = HashMultimap.create();

Expand All @@ -784,8 +779,7 @@ private Multimap<Integer, String> getRegexes() {
}

private void zoomEntries(Map<Long, TimeGraphEntry> map, List<ITimeGraphRowModel> model, boolean completed, Sampling sampling) {
boolean isZoomThread = false; // Thread.currentThread() instanceof
// ZoomThread;
boolean isZoomThread = false;
for (ITimeGraphRowModel rowModel : model) {
TimeGraphEntry entry = map.get(rowModel.getEntryID());

Expand Down Expand Up @@ -871,7 +865,7 @@ protected TimeEvent createTimeEvent(TimeGraphEntry entry, ITimeGraphState state)
* the rightmost time bound of the view
* @return A Multimap of data providers to their visible entries' model IDs.
*/
private static Multimap<ITimeGraphDataProvider<? extends TimeGraphEntryModel>, Long> filterGroupEntries(Iterable<TimeGraphEntry> visible,
private static @Nullable Multimap<ITimeGraphDataProvider<? extends TimeGraphEntryModel>, Long> filterGroupEntries(Iterable<TimeGraphEntry> visible,
long zoomStartTime, long zoomEndTime) {
Multimap<ITimeGraphDataProvider<? extends TimeGraphEntryModel>, Long> providersToModelIds = HashMultimap.create();
for (TimeGraphEntry entry : visible) {
Expand Down Expand Up @@ -1169,75 +1163,6 @@ public void traceClosed(final TmfTraceClosedSignal signal) {
public void setFocus() {
getTimeGraphViewer().setFocus();
}

// ------------------------------------------------------------------------
// Helper methods
// ------------------------------------------------------------------------

private void createTimeEventContextMenu() {
fEventMenuManager.setRemoveAllWhenShown(true);
TimeGraphControl timeGraphControl = getTimeGraphViewer().getTimeGraphControl();
final Menu timeEventMenu = fEventMenuManager.createContextMenu(timeGraphControl);

timeGraphControl.addTimeGraphEntryMenuListener(event -> {
/*
* The TimeGraphControl will call the TimeGraphEntryMenuListener
* before the TimeEventMenuListener. We need to clear the menu for
* the case the selection was done on the namespace where the time
* event listener below won't be called afterwards.
*/
timeGraphControl.setMenu(null);
event.doit = false;
});
timeGraphControl.addTimeEventMenuListener(event -> {
Menu menu = timeEventMenu;
if (event.data instanceof TimeEvent && !(event.data instanceof NullTimeEvent)) {
timeGraphControl.setMenu(menu);
return;
}
timeGraphControl.setMenu(null);
event.doit = false;
});

fEventMenuManager.addMenuListener(manager -> {
fillTimeEventContextMenu(fEventMenuManager);
fEventMenuManager.add(new GroupMarker(IWorkbenchActionConstants.MB_ADDITIONS));
});
getSite().registerContextMenu(fEventMenuManager, getTimeGraphViewer().getSelectionProvider());
}

/**
* Fill context menu
*
* @param menuManager
* a menuManager to fill
*/
protected void fillTimeEventContextMenu(IMenuManager menuManager) {
ISelection selection = getSite().getSelectionProvider().getSelection();
if (selection instanceof IStructuredSelection) {
for (Object object : ((IStructuredSelection) selection).toList()) {
if (object instanceof ITimeEvent) {
ITimeEvent event = (ITimeEvent) object;
ITimeGraphDataProvider<? extends TimeGraphEntryModel> provider = getProvider(Objects.requireNonNull(event.getEntry()));
Map<String, String> tooltip = getTooltip(event, event.getTime(), provider, true);
for (Entry<String, String> entry : tooltip.entrySet()) {
String tooltipKey = Objects.requireNonNull((entry.getKey()));
if (tooltipKey.startsWith(DataProviderUtils.ACTION_PREFIX)) {
// It's an action, add it to the menu
menuManager.add(new Action(tooltipKey.substring(DataProviderUtils.ACTION_PREFIX.length())) {
@Override
public void run() {
DataProviderActionUtils.executeAction(entry.getValue());

}
});
}
}
}
}
}
}

// --------------------------------
// Sorting related methods
// --------------------------------
Expand Down Expand Up @@ -1312,4 +1237,4 @@ private ITimeGraphDataProvider<TimeGraphEntryModel> getFdataProviderGroup() {
private void setFdataProviderGroup(@Nullable ITimeGraphDataProvider<TimeGraphEntryModel> fdataProviderGroup) {
this.fdataProviderGroup = fdataProviderGroup;
}
}
}
Loading

0 comments on commit 8cf63a9

Please sign in to comment.