blob: 0dd3cf6252640a02b3bad19da523fc6bcc1acbfe [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2016 Ericsson
*
* 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.incubator.internal.callstack.ui.flamegraph;
import java.text.Format;
import java.util.Map;
import java.util.Map.Entry;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.tracecompass.analysis.timing.core.statistics.IStatistics;
import org.eclipse.tracecompass.incubator.analysis.core.concepts.AggregatedCallSite;
import org.eclipse.tracecompass.incubator.analysis.core.concepts.ICallStackSymbol;
import org.eclipse.tracecompass.incubator.analysis.core.model.IHostModel;
import org.eclipse.tracecompass.incubator.callstack.core.instrumented.ICalledFunction;
import org.eclipse.tracecompass.incubator.internal.callstack.core.instrumented.callgraph.AggregatedCalledFunction;
import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.ITimeGraphEntry;
import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.TimeEvent;
import com.google.common.collect.ImmutableMap;
/**
* Time Event implementation specific to the FlameGraph View (it represents a
* function in a certain depth)
*
* @author Sonia Farrah
*/
public class FlamegraphEvent extends TimeEvent {
private final ICallStackSymbol fSymbol;
private final AggregatedCallSite fCallSite;
/**
* Constructor
*
* @param source
* The Entry
* @param beginTime
* The event's begin time
* @param aggregatedFunction
* The function the event's presenting
*/
public FlamegraphEvent(ITimeGraphEntry source, long beginTime, AggregatedCallSite aggregatedFunction) {
super(source, beginTime, aggregatedFunction.getWeight(), aggregatedFunction.getObject().hashCode());
fSymbol = aggregatedFunction.getObject();
fCallSite = aggregatedFunction;
}
/**
* The event's name or address
*
* @return The event's name or address
*/
public Object getSymbol() {
return fSymbol;
}
/**
* Return a map containing tooltip key, value strings for this event
*
* @param formatter
* The number formatter to use
* @return A map of key, value tooltip pairs
*/
public Map<String, String> getTooltip(Format formatter) {
ImmutableMap.Builder<String, String> builder = new ImmutableMap.Builder<>();
for (Entry<String, IStatistics<?>> entry : fCallSite.getStatistics().entrySet()) {
String statType = String.valueOf(entry.getKey());
IStatistics<?> stats = entry.getValue();
if (stats.getMax() != IHostModel.TIME_UNKNOWN) {
builder.put(statType, ""); //$NON-NLS-1$
String lowerType = statType.toLowerCase();
builder.put("\t" + Messages.FlameGraph_Total + ' ' + lowerType, formatter.format(stats.getTotal())); //$NON-NLS-1$
builder.put("\t" + Messages.FlameGraph_Average + ' ' + lowerType, formatter.format(stats.getMean())); //$NON-NLS-1$
builder.put("\t" + Messages.FlameGraph_Max + ' ' + lowerType, formatter.format(stats.getMax())); //$NON-NLS-1$
builder.put("\t" + Messages.FlameGraph_Min + ' ' + lowerType, formatter.format(stats.getMin())); //$NON-NLS-1$
builder.put("\t" + Messages.FlameGraph_Deviation + ' ' + lowerType, formatter.format(stats.getStdDev())); //$NON-NLS-1$
}
}
return builder.build();
}
/**
* Get the number of calls for this flamegraph event's callsite. If the callsite
* was instrumented, the result will be the exact number of calls of this call
* site, otherwise, it will be the number of samples.
*
* @return The number of calls of the call site
*/
public long getNumberOfCalls() {
AggregatedCallSite callSite = fCallSite;
// Return the number of calls if this is an instrumented function, otherwise,
// the length will be the number of samples
if (callSite instanceof AggregatedCalledFunction) {
return ((AggregatedCalledFunction) callSite).getNbCalls();
}
return callSite.getWeight();
}
/**
* Get the object with minimal duration in this aggregated call site.
*
* @return The minimal duration object, or <code>null</code> if no such object
* exists
*/
public @Nullable ICalledFunction getMinObject() {
AggregatedCallSite callSite = fCallSite;
// Return the number of calls if this is an instrumented function, otherwise,
// the length will be the number of samples
if (callSite instanceof AggregatedCalledFunction) {
return ((AggregatedCalledFunction) callSite).getFunctionStatistics().getDurationStatistics().getMinObject();
}
return null;
}
/**
* Get the object with maximum duration in this aggregated call site.
*
* @return The maximum duration object, or <code>null</code> if no such object
* exists
*/
public @Nullable ICalledFunction getMaxObject() {
AggregatedCallSite callSite = fCallSite;
// Return the number of calls if this is an instrumented function, otherwise,
// the length will be the number of samples
if (callSite instanceof AggregatedCalledFunction) {
return ((AggregatedCalledFunction) callSite).getFunctionStatistics().getDurationStatistics().getMaxObject();
}
return null;
}
}