Skip to content

Commit

Permalink
callstack: Bring incubated ICallGraphProvider in
Browse files Browse the repository at this point in the history
Add ICallGraphProvider from Incubator in turn, as well as its necessary
dependencies.

Skip ICalledFunction thus reuse the sibling profiling.core one, which
only differs in contract; Incubator's has no default implementation that
may differ. Do so until more contract becomes required if ever. (Likely,
though.)

Change-Id: If6f29c696283355b83b061a9ce0f45a57b230f0d
Signed-off-by: Marco Miller <marco.miller@ericsson.com>
Reviewed-on: https://git.eclipse.org/r/c/tracecompass/org.eclipse.tracecompass/+/197779
Tested-by: Trace Compass Bot <tracecompass-bot@eclipse.org>
Tested-by: Bernd Hufmann <bernd.hufmann@ericsson.com>
Reviewed-by: Bernd Hufmann <bernd.hufmann@ericsson.com>
  • Loading branch information
marco-miller committed Mar 31, 2023
1 parent 72a48a5 commit fbf1eaa
Show file tree
Hide file tree
Showing 8 changed files with 520 additions and 3 deletions.
Expand Up @@ -11,8 +11,10 @@ Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Automatic-Module-Name: org.eclipse.tracecompass.analysis.callstack.core
Require-Bundle: org.eclipse.core.runtime,
org.eclipse.jdt.annotation;bundle-version="[2.0.0,3.0.0)";resolution:=optional,
org.eclipse.tracecompass.analysis.profiling.core,
org.eclipse.tracecompass.analysis.timing.core,
org.eclipse.tracecompass.common.core,
org.eclipse.tracecompass.segmentstore.core,
org.eclipse.tracecompass.tmf.core
Export-Package: org.eclipse.tracecompass.internal.analysis.callstack.core;x-friends:="org.eclipse.tracecompass.analysis.callstack.core.tests"
Import-Package: com.google.common.annotations,
Expand Down
@@ -0,0 +1,117 @@
/*******************************************************************************
* Copyright (c) 2018 École Polytechnique de Montréal
*
* 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.internal.analysis.callstack.core;

import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.tracecompass.internal.analysis.callstack.core.tree.IDataPalette;
import org.eclipse.tracecompass.internal.analysis.profiling.core.callgraph.ICalledFunction;
import org.eclipse.tracecompass.tmf.core.dataprovider.X11ColorUtils;
import org.eclipse.tracecompass.tmf.core.model.OutputElementStyle;
import org.eclipse.tracecompass.tmf.core.model.StyleProperties;
import org.eclipse.tracecompass.tmf.core.model.timegraph.TimeGraphState;
import org.eclipse.tracecompass.tmf.core.presentation.IPaletteProvider;
import org.eclipse.tracecompass.tmf.core.presentation.RGBAColor;
import org.eclipse.tracecompass.tmf.core.presentation.RotatingPaletteProvider;

import com.google.common.collect.ImmutableMap;

/**
* Class to manage the colors of the flame chart and flame graph views
*
* @author Geneviève Bastien
*/
public final class FlameDefaultPalette implements IDataPalette {

/**
* The state index for the multiple state
*/
private static final int NUM_COLORS = 360;
private static final String DEFAULT_STYLE = "0"; //$NON-NLS-1$

private static final Map<String, OutputElementStyle> STYLES;
// Map of styles with the parent
private static final Map<String, OutputElementStyle> STYLE_MAP = Collections.synchronizedMap(new HashMap<>());

static {
IPaletteProvider palette = new RotatingPaletteProvider.Builder().setNbColors(NUM_COLORS).build();
int i = 0;
ImmutableMap.Builder<String, OutputElementStyle> builder = new ImmutableMap.Builder<>();
for (RGBAColor color : palette.get()) {
builder.put(String.valueOf(i), new OutputElementStyle(null, ImmutableMap.of(
StyleProperties.STYLE_NAME, String.valueOf(i),
StyleProperties.BACKGROUND_COLOR, X11ColorUtils.toHexColor(color.getRed(), color.getGreen(), color.getBlue()),
StyleProperties.OPACITY, (float) color.getAlpha() / 255)));
i++;
}
STYLES = builder.build();
}

private static @Nullable FlameDefaultPalette fInstance = null;

private FlameDefaultPalette() {
// Do nothing
}

/**
* Get the instance of this palette
*
* @return The instance of the palette
*/
public static FlameDefaultPalette getInstance() {
FlameDefaultPalette instance = fInstance;
if (instance == null) {
instance = new FlameDefaultPalette();
fInstance = instance;
}
return instance;
}

/**
* Get the map of styles for this palette
*
* @return The styles
*/
@Override
public Map<String, OutputElementStyle> getStyles() {
return STYLES;
}

/**
* Get the style element for a given value
*
* @param callsite
* The value to get an element for
* @return The output style
*/
@Override
public OutputElementStyle getStyleFor(Object callsite) {
if (callsite instanceof AggregatedCallSite) {
ICallStackSymbol value = ((AggregatedCallSite) callsite).getObject();
int hashCode = value.hashCode();
return STYLE_MAP.computeIfAbsent(String.valueOf(Math.floorMod(hashCode, NUM_COLORS)), style -> new OutputElementStyle(style));
}
if (callsite instanceof ICalledFunction) {
Object value = ((ICalledFunction) callsite).getSymbol();
int hashCode = value.hashCode();
return STYLE_MAP.computeIfAbsent(String.valueOf(Math.floorMod(hashCode, NUM_COLORS)), style -> new OutputElementStyle(style));
}
if (callsite instanceof TimeGraphState) {
OutputElementStyle elStyle = ((TimeGraphState) callsite).getStyle();
return elStyle == null ? STYLE_MAP.computeIfAbsent(DEFAULT_STYLE, style -> new OutputElementStyle(style)) : elStyle;
}
return STYLE_MAP.computeIfAbsent(DEFAULT_STYLE, style -> new OutputElementStyle(style));
}
}
@@ -0,0 +1,100 @@
/*******************************************************************************
* Copyright (c) 2017 École Polytechnique de Montréal
*
* 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.internal.analysis.callstack.core;

import java.util.Collection;

import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.tracecompass.internal.analysis.callstack.core.tree.IDataPalette;
import org.eclipse.tracecompass.internal.analysis.callstack.core.tree.IWeightedTreeGroupDescriptor;
import org.eclipse.tracecompass.internal.analysis.callstack.core.tree.IWeightedTreeProvider;
import org.eclipse.tracecompass.internal.analysis.callstack.core.tree.IWeightedTreeSet;
import org.eclipse.tracecompass.internal.analysis.callstack.core.tree.WeightedTreeGroupBy;
import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp;

/**
* Interface that analyses who provide callgraph
*
* @author Geneviève Bastien
*/
public interface ICallGraphProvider extends IWeightedTreeProvider<@NonNull ICallStackSymbol, ICallStackElement, AggregatedCallSite> {

/**
* Get the group descriptors that describe how the elements are grouped in
* this call graph hierarchy. This method will return the root group
* descriptor. Children groups can be retrieved by the parent group. For
* call graph providers who have only one series, this will be a singleton.
*
* @return The collection of group descriptors for this call graph
*/
Collection<IWeightedTreeGroupDescriptor> getGroupDescriptors();

@Override
default @Nullable IWeightedTreeGroupDescriptor getGroupDescriptor() {
// Return the first group descriptor
Collection<IWeightedTreeGroupDescriptor> groupDescriptors = getGroupDescriptors();
if (groupDescriptors.isEmpty()) {
return null;
}
return groupDescriptors.iterator().next();
}

/**
* Get the call graph for a given time range. This callgraph is for all the
* elements. The caller can then group the result by calling
* {@link WeightedTreeGroupBy#groupWeightedTreeBy(IWeightedTreeGroupDescriptor, IWeightedTreeSet, IWeightedTreeProvider)}
* method
*
* @param start
* The start of the range
* @param end
* The end of the range
* @return The call graph object containing the CCTs for each element in the
* range.
*/
CallGraph getCallGraph(ITmfTimestamp start, ITmfTimestamp end);

/**
* Get the call graph for the full range of the trace. This callgraph is for
* all the elements. The caller can then group the result by calling
* {@link WeightedTreeGroupBy#groupWeightedTreeBy(IWeightedTreeGroupDescriptor, IWeightedTreeSet, IWeightedTreeProvider)}
*
* @return The call graph object containing the CCTs for each element in the
* range.
*/
CallGraph getCallGraph();

@Override
default @Nullable IWeightedTreeSet<@NonNull ICallStackSymbol, ICallStackElement, AggregatedCallSite> getSelection(ITmfTimestamp start, ITmfTimestamp end) {
return getCallGraph(start, end);
}

@Override
default IWeightedTreeSet<@NonNull ICallStackSymbol, ICallStackElement, AggregatedCallSite> getTreeSet() {
return getCallGraph();
}

/**
* Factory method to create an aggregated callsite for a symbol
*
* @param object
* The symbol
* @return A new aggregated callsite
*/
AggregatedCallSite createCallSite(Object object);

@Override
default IDataPalette getPalette() {
return FlameDefaultPalette.getInstance();
}
}
@@ -0,0 +1,48 @@
/*******************************************************************************
* Copyright (c) 2019 École Polytechnique de Montréal
*
* 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.internal.analysis.callstack.core.tree;

import org.eclipse.jdt.annotation.Nullable;

/**
* Group descriptor to represent all elements grouped together
*
* @author Geneviève Bastien
*/
public final class AllGroupDescriptor implements IWeightedTreeGroupDescriptor {

private static final String ALL_NAME = "all"; //$NON-NLS-1$

private static final IWeightedTreeGroupDescriptor INSTANCE = new AllGroupDescriptor();

/**
* Get the instance of the all group descriptor
*
* @return The instance of this group.
*/
public static IWeightedTreeGroupDescriptor getInstance() {
return INSTANCE;
}

private AllGroupDescriptor() {
}

@Override
public @Nullable IWeightedTreeGroupDescriptor getNextGroup() {
return null;
}

@Override
public String getName() {
return ALL_NAME;
}
}

0 comments on commit fbf1eaa

Please sign in to comment.