diff --git a/callstack/org.eclipse.tracecompass.incubator.callstack.core/src/org/eclipse/tracecompass/incubator/internal/callstack/core/instrumented/callgraph/AbstractCalledFunction.java b/callstack/org.eclipse.tracecompass.incubator.callstack.core/src/org/eclipse/tracecompass/incubator/internal/callstack/core/instrumented/callgraph/AbstractCalledFunction.java index 35850e692..8708d3d0c 100644 --- a/callstack/org.eclipse.tracecompass.incubator.callstack.core/src/org/eclipse/tracecompass/incubator/internal/callstack/core/instrumented/callgraph/AbstractCalledFunction.java +++ b/callstack/org.eclipse.tracecompass.incubator.callstack.core/src/org/eclipse/tracecompass/incubator/internal/callstack/core/instrumented/callgraph/AbstractCalledFunction.java @@ -181,5 +181,16 @@ public boolean equals(@Nullable Object obj) { Objects.equals(fParent, other.getParent()) && Objects.equals(getSymbol(), other.getSymbol())); } + + private long getChildIntersection(TmfTimeRange chlInt) { + long intersection = 0; + for (TmfTimeRange childInterval:fChildrenIntervals ) { + TmfTimeRange intersect = chlInt.getIntersection(childInterval); + if (intersect!=null) { + intersection += (intersect.getEndTime().getValue())-(intersect.getStartTime().getValue()); + } + } + return intersection; + } +} -} \ No newline at end of file diff --git a/tracetypes/org.eclipse.tracecompass.incubator.opentracing.core/src/org/eclipse/tracecompass/incubator/opentracing/core/analysis/callstack/AsincCallStackStateProvider.java b/tracetypes/org.eclipse.tracecompass.incubator.opentracing.core/src/org/eclipse/tracecompass/incubator/opentracing/core/analysis/callstack/AsincCallStackStateProvider.java new file mode 100644 index 000000000..7d000f340 --- /dev/null +++ b/tracetypes/org.eclipse.tracecompass.incubator.opentracing.core/src/org/eclipse/tracecompass/incubator/opentracing/core/analysis/callstack/AsincCallStackStateProvider.java @@ -0,0 +1,209 @@ +package org.eclipse.tracecompass.incubator.opentracing.core.analysis.callstack; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.TreeMap; + +import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.jdt.annotation.Nullable; +import org.eclipse.tracecompass.incubator.callstack.core.instrumented.statesystem.InstrumentedCallStackAnalysis; +import org.eclipse.tracecompass.incubator.internal.opentracing.core.event.IOpenTracingConstants; +import org.eclipse.tracecompass.statesystem.core.ITmfStateSystemBuilder; +import org.eclipse.tracecompass.statesystem.core.statevalue.TmfStateValue; +import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; +import org.eclipse.tracecompass.tmf.core.event.ITmfEventField; +import org.eclipse.tracecompass.tmf.core.statesystem.AbstractTmfStateProvider; +import org.eclipse.tracecompass.tmf.core.statesystem.ITmfStateProvider; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; +import org.eclipse.tracecompass.tmf.core.trace.TmfTraceUtils; + +/** + * Span Callstack state provider + * + * @author Fateme Faraji Daneshgar + * + */ +public class AsincCallStackStateProvider extends AbstractTmfStateProvider { + + /** + * Thread attribute + * + * @since 2.0 + */ + public static final String PROCESSES = "Processes"; //$NON-NLS-1$ + + /** + * Unknown process ID + * + * @since 2.0 + */ + public static final int UNKNOWN_PID = -1; + + /** + * Unknown name + * + * @since 2.0 + */ + public static final String UNKNOWN = "UNKNOWN"; //$NON-NLS-1$ + + + private static final int MAX_STACK_DEPTH = 100000; + + private final Map fStackDepthMap; + private TreeMap> fPrevEvent; + private int fStateQuark = 3; + + /** + * Constructor + * + * @param trace + * the trace to follow + */ + public AsincCallStackStateProvider(@NonNull ITmfTrace trace) { + super(trace, OpenTracingCallstackAnalysis.ID); + // fSpanMap = new HashMap<>(); + fStackDepthMap = new HashMap<>(); + fPrevEvent = new TreeMap<>(); + } + + @Override + public int getVersion() { + return 3; + } + + @Override + public @NonNull ITmfStateProvider getNewInstance() { + return new AsincCallStackStateProvider(getTrace()); + } + + @Override + protected void eventHandle(@NonNull ITmfEvent event) { + ITmfStateSystemBuilder ss = getStateSystemBuilder(); + if (ss == null) { + return; + } + handleSpan(event,ss); + } + + private void handleSpan(ITmfEvent event, ITmfStateSystemBuilder ss) { + long timestamp = event.getTimestamp().toNanos(); + if (timestamp == getTrace().getStartTime().toNanos()) { + timestamp++; + } + Long duration = event.getContent().getFieldValue(Long.class, IOpenTracingConstants.DURATION); + if (duration == null) { + return; + } + while (!(fPrevEvent.isEmpty()) && (fPrevEvent.firstKey() < timestamp)) { + long prevTime = fPrevEvent.firstKey(); + List quarks = Objects.requireNonNull(fPrevEvent.get(fPrevEvent.firstKey())); + ss.modifySpanAttribute(prevTime, (Object) null, quarks.get(0), quarks.get(1)); + fPrevEvent.remove(fPrevEvent.firstKey()); + } + + String processName = event.getContent().getFieldValue(String.class, IOpenTracingConstants.TRACE_ID); + + int processId = getProcessId(event); + if (processName == null) { + processName = (processId == UNKNOWN_PID) ? UNKNOWN : Integer.toString(processId); + } + + int pq = ss.getQuarkAbsoluteAndAdd(PROCESSES, processName); + ss.updateOngoingState(TmfStateValue.newValueInt(processId), 1); + + String Opname = String.valueOf(TmfTraceUtils.resolveAspectOfNameForEvent(event.getTrace(), "Name", event)); //$NON-NLS-1$ + String spanId = event.getContent().getFieldValue(String.class, IOpenTracingConstants.SPAN_ID); + String parentId = event.getContent().getFieldValue(String.class, IOpenTracingConstants.REFERENCES + "/CHILD_OF"); //$NON-NLS-1$ + + int callStackQuark = ss.getQuarkRelativeAndAdd(pq, InstrumentedCallStackAnalysis.CALL_STACK); + int stackDepth = getStackDepth(parentId); + + Object functionEntryName = functionEntry(spanId, parentId, Opname); + stackDepth++; + + int spanQuark = ss.getQuarkRelativeAndAdd(callStackQuark, String.valueOf(stackDepth)); + + ss.modifySpanAttribute(timestamp, functionEntryName, fStateQuark, spanQuark); + + fStackDepthMap.put(spanId, stackDepth); + + List quarksList = Arrays.asList(fStateQuark, spanQuark); + fPrevEvent.put(timestamp + duration, quarksList); + fStateQuark++; + + } + + protected @Nullable String getProcessName(ITmfEvent event) { + + Long fieldValue = event.getContent().getFieldValue(Long.class, "trace_id"); + if (fieldValue == null) { + fieldValue = event.getContent().getFieldValue(Long.class, "trace_id_low"); + } + + return fieldValue == null ? "eduroam" : Long.toHexString(fieldValue); + } + + protected int getProcessId(ITmfEvent event) { + Long resolve = event.getContent().getFieldValue(Long.class, "trace_id"); + return resolve == null ? -1 : resolve.intValue(); + } + + private int getStackDepth(String parentId) { + Integer stackDepth = fStackDepthMap.get(parentId); + if (stackDepth == null) { + stackDepth = 0; + } + if (stackDepth >= MAX_STACK_DEPTH) { + /* + * Limit stackDepth to 100000, to avoid having Attribute Trees grow + * out of control due to buggy insertions + */ + String message = " Stack limit reached, not pushing"; //$NON-NLS-1$ + throw new IllegalStateException(" Quark:" + parentId + message); //$NON-NLS-1$ + } + return stackDepth; + + } + + protected @Nullable Object functionEntry(String spanId, String parentId, String name) { + return new SpanCustomValue(spanId, (parentId == null) ? "0" : parentId, name); + + } + + protected Map MessageHashMapExtractor(ITmfEventField value) { + // split the string to creat key-value pairs + Map map = new HashMap<>(); + // iterate over the pairs + for (ITmfEventField field : value.getFields()) { + Objects.requireNonNull(field); + map.put(field.getName(), field.getValue().toString().trim()); + } + if (map.isEmpty()) { + String valueString = (String) Objects.requireNonNull(value.getValue()); + String[] values = valueString.split(","); + for (String tuple : values) { + String[] parts = tuple.split("="); + map.put(parts[0], parts[1].trim()); + } + } + return map; + } + + @Override + public void done() { + ITmfStateSystemBuilder ss = getStateSystemBuilder(); + if (ss == null) { + return; + } + while (!(fPrevEvent.isEmpty())) { + long prevTime = fPrevEvent.firstKey(); + List quarks = Objects.requireNonNull(fPrevEvent.get(fPrevEvent.firstKey())); + ss.modifySpanAttribute(prevTime, (Object) null, quarks.get(0), quarks.get(1)); + fPrevEvent.remove(fPrevEvent.firstKey()); + } + } + +} diff --git a/tracetypes/org.eclipse.tracecompass.incubator.opentracing.core/src/org/eclipse/tracecompass/incubator/opentracing/core/analysis/callstack/OpenTracingCallstackAnalysis.java b/tracetypes/org.eclipse.tracecompass.incubator.opentracing.core/src/org/eclipse/tracecompass/incubator/opentracing/core/analysis/callstack/OpenTracingCallstackAnalysis.java new file mode 100644 index 000000000..d68f9e837 --- /dev/null +++ b/tracetypes/org.eclipse.tracecompass.incubator.opentracing.core/src/org/eclipse/tracecompass/incubator/opentracing/core/analysis/callstack/OpenTracingCallstackAnalysis.java @@ -0,0 +1,33 @@ +package org.eclipse.tracecompass.incubator.opentracing.core.analysis.callstack; + +import java.util.Collections; +import java.util.Objects; + +import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.tracecompass.tmf.core.analysis.requirements.TmfAbstractAnalysisRequirement; +import org.eclipse.tracecompass.tmf.core.statesystem.ITmfStateProvider; + +/** + * + */ +public class OpenTracingCallstackAnalysis extends SpanCallStackAnalysis { + /** + * ID + */ + public static final @NonNull String ID = "org.eclipse.tracecompass.incubator.opentracing.analysis.callstack"; //$NON-NLS-1$ + + + @Override + protected ITmfStateProvider createStateProvider() { + return new AsincCallStackStateProvider(Objects.requireNonNull(getTrace())); + } + + + @Override + public @NonNull Iterable<@NonNull TmfAbstractAnalysisRequirement> getAnalysisRequirements() { + return Collections.emptyList(); + } + + + + } diff --git a/tracetypes/org.eclipse.tracecompass.incubator.opentracing.core/src/org/eclipse/tracecompass/incubator/opentracing/core/analysis/callstack/SpanCallGraphAnalysis.java b/tracetypes/org.eclipse.tracecompass.incubator.opentracing.core/src/org/eclipse/tracecompass/incubator/opentracing/core/analysis/callstack/SpanCallGraphAnalysis.java new file mode 100644 index 000000000..07d6d648e --- /dev/null +++ b/tracetypes/org.eclipse.tracecompass.incubator.opentracing.core/src/org/eclipse/tracecompass/incubator/opentracing/core/analysis/callstack/SpanCallGraphAnalysis.java @@ -0,0 +1,178 @@ +package org.eclipse.tracecompass.incubator.opentracing.core.analysis.callstack; + +import java.util.Collection; +import java.util.Collections; +import java.util.List; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.tracecompass.incubator.analysis.core.concepts.ICallStackSymbol; +import org.eclipse.tracecompass.incubator.analysis.core.concepts.ProcessStatusInterval; +import org.eclipse.tracecompass.incubator.analysis.core.model.IHostModel; +import org.eclipse.tracecompass.incubator.callstack.core.base.ICallStackElement; +import org.eclipse.tracecompass.incubator.callstack.core.callgraph.CallGraph; +import org.eclipse.tracecompass.incubator.callstack.core.flamechart.CallStack; +import org.eclipse.tracecompass.incubator.callstack.core.instrumented.ICalledFunction; +import org.eclipse.tracecompass.incubator.callstack.core.instrumented.IFlameChartProvider; +import org.eclipse.tracecompass.incubator.callstack.core.instrumented.statesystem.CallStackSeries; +import org.eclipse.tracecompass.incubator.callstack.core.symbol.CallStackSymbolFactory; +import org.eclipse.tracecompass.incubator.internal.callstack.core.instrumented.InstrumentedCallStackElement; +import org.eclipse.tracecompass.incubator.internal.callstack.core.instrumented.callgraph.AbstractCalledFunction; +import org.eclipse.tracecompass.incubator.internal.callstack.core.instrumented.callgraph.AggregatedCalledFunction; +import org.eclipse.tracecompass.incubator.internal.callstack.core.instrumented.callgraph.CallGraphAnalysis; +import org.eclipse.tracecompass.tmf.core.signal.TmfSignalManager; + +/** + * Call Graph Analysis for concurrent traces + * @author Fateme Faraji Daneshgar + * + */ +public class SpanCallGraphAnalysis extends CallGraphAnalysis { + private boolean fHasKernelStatuses = false; + public static final String Span = "span:"; + public static final String parentSpan = "parentSpan:"; + public static final String func = "opName:"; + + + + /** + * @param csProvider + */ + public SpanCallGraphAnalysis(IFlameChartProvider csProvider) { + super(csProvider); + // TODO Auto-generated constructor stub + } + + @Override + protected boolean iterateOverCallstackSerie(CallStackSeries callstackSerie, IHostModel model, CallGraph callgraph, long start, long end, IProgressMonitor monitor) { + // The root elements are the same as the one from the callstack series + Collection rootElements = callstackSerie.getRootElements(); + for (ICallStackElement element : rootElements) { + if (monitor.isCanceled()) { + return false; + } + iterateOverElement(element, model, callgraph, start, end, monitor); + } + return true; + } + + private void iterateOverElement(ICallStackElement element, IHostModel model, CallGraph callgraph, long start, long end, IProgressMonitor monitor) { + // Iterator over the children of the element until we reach the leaves + if (element.isLeaf()) { + iterateOverLeafElement(element, model, callgraph, start, end, monitor); + return; + } + for (ICallStackElement child : element.getChildrenElements()) { + iterateOverElement(child, model, callgraph, start, end, monitor); + } + } + + private void iterateOverLeafElement(ICallStackElement element, IHostModel model, CallGraph callgraph, long start, long end, IProgressMonitor monitor) { + if (!(element instanceof InstrumentedCallStackElement)) { + throw new IllegalStateException("Call Graph Analysis: The element does not have the right type"); //$NON-NLS-1$ + } + InstrumentedCallStackElement insElement = (InstrumentedCallStackElement) element; + + CallStack callStack = insElement.getCallStack(); + + // If there is no children for this callstack, just return + if (callStack.getMaxDepth() == 0) { + return; + } + fHasKernelStatuses |= callStack.hasKernelStatuses(); + // Start with the first function + AbstractCalledFunction nextFunction = (AbstractCalledFunction) callStack.getNextFunction(callStack.getStartTime(), 1, null, model, start, end); + while (nextFunction != null) { + AggregatedCalledFunction aggregatedChild = createSpanCallSite(CallStackSymbolFactory.createSymbol(getFuncName(nextFunction.getSymbol()), element, nextFunction.getStart())); + iterateOverCallstack(element, callStack, nextFunction, 2, aggregatedChild, model, start, end, monitor); + aggregatedChild.addFunctionCall(nextFunction); + Iterable kernelStatuses = callStack.getKernelStatuses(nextFunction, Collections.emptyList()); + for (ProcessStatusInterval status : kernelStatuses) { + aggregatedChild.addKernelStatus(status); + } + callgraph.addAggregatedCallSite(element, aggregatedChild); + nextFunction = (AbstractCalledFunction) callStack.getNextFunction(nextFunction.getEnd(), 1, null, model, start, end); + } + } + + private void iterateOverCallstack(ICallStackElement element, CallStack callstack, ICalledFunction function, int nextLevel, AggregatedCalledFunction aggregatedCall, IHostModel model, long start, long end, IProgressMonitor monitor) { + if (nextLevel > callstack.getMaxDepth()) { + return; + } + AbstractCalledFunction nextFunction = (AbstractCalledFunction) callstack.getNextFunction(function.getStart(), nextLevel, function, model, Math.max(function.getStart(), start), Math.min(function.getEnd(), end)); + int level = nextLevel; + String funcSpanId = getSpanId(function.getSymbol()); + while (nextFunction !=null) { + String nextFuncParentId = getParentId(nextFunction.getSymbol()); + if (!funcSpanId.equals(nextFuncParentId)) { + nextFunction = (AbstractCalledFunction) callstack.getNextFunction(nextFunction.getEnd()+1, level, function, model, Math.max(function.getStart(), start), Math.min(function.getEnd(), end)); + continue; + } + + if (nextFunction !=null) { + ((AbstractCalledFunction) function).addChild(nextFunction); + AggregatedCalledFunction aggregatedChild = createSpanCallSite(CallStackSymbolFactory.createSymbol(getFuncName(nextFunction.getSymbol()), element, nextFunction.getStart())); + iterateOverCallstack(element, callstack, nextFunction, level+1, aggregatedChild, model, start, end, monitor); + aggregatedCall.addChild( nextFunction, aggregatedChild); + + nextFunction = (AbstractCalledFunction) callstack.getNextFunction(nextFunction.getEnd()+1, level, function, model, Math.max(function.getStart(), start), Math.min(function.getEnd(), end)); + + } + } + + } + private static String getParentId(@NonNull Object object) { + String symbol = String.valueOf(object); + int indx = symbol.indexOf(parentSpan); + int lastIndx = symbol.indexOf(",o"); + if (indx ==-1) { + return null; + } + return symbol.substring(indx+parentSpan.length(),lastIndx); + } + + private static String getSpanId(@NonNull Object object) { + String symbol = String.valueOf(object); + int indx = symbol.indexOf(Span); + int lastIndx = symbol.indexOf(","); + if (indx ==-1) { + return null; + } + return symbol.substring(indx+Span.length(),lastIndx); + + } + + private static String getFuncName(@NonNull Object object) { + String symbol = String.valueOf(object); + int indx = symbol.indexOf(func); + int lastIndx = symbol.indexOf("]"); + if (indx ==-1) { + return null; + } + return symbol.substring(indx+func.length(),lastIndx); + + } + + @Override + public List getExtraDataSets() { + if (fHasKernelStatuses) { + return Collections.singletonList(String.valueOf(org.eclipse.tracecompass.incubator.internal.callstack.core.instrumented.provider.Messages.FlameChartDataProvider_KernelStatusTitle)); + } + //return ICallGraphProvider.super.getExtraDataSets(); + return Collections.emptyList(); + } + + + public AggregatedCalledFunction createSpanCallSite(Object symbol) { + return new AggregatedCalledFunction((ICallStackSymbol) symbol); + } + + @Override + public void dispose() { + super.dispose(); + TmfSignalManager.deregister(this); + + } + + +} \ No newline at end of file diff --git a/tracetypes/org.eclipse.tracecompass.incubator.opentracing.core/src/org/eclipse/tracecompass/incubator/opentracing/core/analysis/callstack/SpanCallStackAnalysis.java b/tracetypes/org.eclipse.tracecompass.incubator.opentracing.core/src/org/eclipse/tracecompass/incubator/opentracing/core/analysis/callstack/SpanCallStackAnalysis.java new file mode 100644 index 000000000..cd1801b8e --- /dev/null +++ b/tracetypes/org.eclipse.tracecompass.incubator.opentracing.core/src/org/eclipse/tracecompass/incubator/opentracing/core/analysis/callstack/SpanCallStackAnalysis.java @@ -0,0 +1,181 @@ +package org.eclipse.tracecompass.incubator.opentracing.core.analysis.callstack; + +import java.util.Collection; +import java.util.Collections; +import java.util.List; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.jdt.annotation.Nullable; +import org.eclipse.tracecompass.incubator.analysis.core.concepts.AggregatedCallSite; +import org.eclipse.tracecompass.incubator.analysis.core.weighted.tree.IDataPalette; +import org.eclipse.tracecompass.incubator.analysis.core.weighted.tree.IWeightedTreeGroupDescriptor; +import org.eclipse.tracecompass.incubator.callstack.core.callgraph.CallGraph; +import org.eclipse.tracecompass.incubator.callstack.core.callgraph.SymbolAspect; +import org.eclipse.tracecompass.incubator.callstack.core.instrumented.statesystem.CallStackSeries; +import org.eclipse.tracecompass.incubator.callstack.core.instrumented.statesystem.CallStackStateProvider; +import org.eclipse.tracecompass.incubator.callstack.core.instrumented.statesystem.InstrumentedCallStackAnalysis; +import org.eclipse.tracecompass.segmentstore.core.ISegment; +import org.eclipse.tracecompass.segmentstore.core.ISegmentStore; +import org.eclipse.tracecompass.statesystem.core.ITmfStateSystem; +import org.eclipse.tracecompass.tmf.core.exceptions.TmfAnalysisException; +import org.eclipse.tracecompass.tmf.core.segment.ISegmentAspect; +import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; + +import com.google.common.collect.ImmutableList; + +/** + * + */ +public abstract class SpanCallStackAnalysis extends InstrumentedCallStackAnalysis { + + private static final String[] DEFAULT_PROCESSES_PATTERN = new String[] { CallStackStateProvider.PROCESSES, "*" }; //$NON-NLS-1$ + + private static final List PATTERNS = ImmutableList.of(DEFAULT_PROCESSES_PATTERN); + + private @Nullable CallStackSeries fCallStacks; + + private final SpanCallGraphAnalysis fCallGraph; + + private boolean fAutomaticCallgraph=true; + + + protected SpanCallStackAnalysis() { + super(); + fCallGraph = new SpanCallGraphAnalysis(this); + } + @Override + public boolean setTrace(@NonNull ITmfTrace trace) throws TmfAnalysisException { + if (!super.setTrace(trace)) { + return false; + } + return fCallGraph.setTrace(trace); + } + + @Override + public void setName(String name) { + super.setName(name); + fCallGraph.setName(name); + } + + @Override + public synchronized @Nullable CallStackSeries getCallStackSeries() { + CallStackSeries callstacks = fCallStacks; + if (callstacks == null) { + ITmfStateSystem ss = getStateSystem(); + ITmfTrace trace = getTrace(); + if (ss == null || trace == null) { + return null; + } + callstacks = new CallStackSeries(ss, getPatterns(), 0, "", getCallStackHostResolver(trace), null); //$NON-NLS-1$ + fCallStacks = callstacks; + } + return callstacks; + } + + + /** + * Get the patterns for the process, threads and callstack levels in the + * state system + * + * @return The patterns for the different levels in the state system + */ + @Override + protected List getPatterns() { + return PATTERNS; + } + @Override + protected boolean executeAnalysis(@Nullable IProgressMonitor monitor) { + fCallGraph.setId(getId()); + boolean ret = super.executeAnalysis(monitor); + if (!ret) { + return ret; + } + ISegmentStore segmentStore = getSegmentStore(); + if (segmentStore != null) { + sendUpdate(segmentStore); + } + if (fAutomaticCallgraph) { + fCallGraph.schedule(); + } + return true; + } + + @Override + public void dispose() { + fCallGraph.dispose(); + super.dispose(); + } + + @Override + public CallGraph getCallGraph(ITmfTimestamp start, ITmfTimestamp end) { + fCallGraph.schedule(); + fCallGraph.waitForCompletion(); + return fCallGraph.getCallGraph(start, end); + } + + @Override + public CallGraph getCallGraph() { + fCallGraph.schedule(); + fCallGraph.waitForCompletion(); + return fCallGraph.getCallGraph(); + } + + @Override + public Collection getGroupDescriptors() { + fCallGraph.schedule(); + fCallGraph.waitForCompletion(); + return fCallGraph.getGroupDescriptors(); + } + + @Override + public String getTitle() { + return fCallGraph.getTitle(); + } + + @Override + public AggregatedCallSite createCallSite(Object symbol) { + return fCallGraph.createCallSite(symbol); + } + @Override + public @NonNull List<@NonNull String> getExtraDataSets() { + return fCallGraph.getExtraDataSets(); + } + + @Override + public MetricType getWeightType() { + return fCallGraph.getWeightType(); + } + + @Override + public List getAdditionalMetrics() { + return fCallGraph.getAdditionalMetrics(); + } + + @Override + public String toDisplayString(AggregatedCallSite object) { + return fCallGraph.toDisplayString(object); + } + + @Override + public Object getAdditionalMetric(AggregatedCallSite object, int metricIndex) { + return fCallGraph.getAdditionalMetric(object, metricIndex); + } + + @Override + public IDataPalette getPalette() { + // Schedule the analysis (it will likely be needed) but don't wait for + // completion as this should be a fast return. + fCallGraph.schedule(); + return fCallGraph.getPalette(); + } + + + @Override + + public Iterable getSegmentAspects() { + + return Collections.singletonList(SymbolAspect.SYMBOL_ASPECT); + } +} \ No newline at end of file diff --git a/tracetypes/org.eclipse.tracecompass.incubator.opentracing.core/src/org/eclipse/tracecompass/incubator/opentracing/core/analysis/callstack/SpanCustomValue.java b/tracetypes/org.eclipse.tracecompass.incubator.opentracing.core/src/org/eclipse/tracecompass/incubator/opentracing/core/analysis/callstack/SpanCustomValue.java new file mode 100644 index 000000000..f911dcf0e --- /dev/null +++ b/tracetypes/org.eclipse.tracecompass.incubator.opentracing.core/src/org/eclipse/tracecompass/incubator/opentracing/core/analysis/callstack/SpanCustomValue.java @@ -0,0 +1,117 @@ +package org.eclipse.tracecompass.incubator.opentracing.core.analysis.callstack; + + + +import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.jdt.annotation.Nullable; +import org.eclipse.tracecompass.datastore.core.serialization.ISafeByteBufferWriter; +import org.eclipse.tracecompass.datastore.core.serialization.SafeByteBufferFactory; +import org.eclipse.tracecompass.internal.provisional.statesystem.core.statevalue.CustomStateValue; +import org.eclipse.tracecompass.statesystem.core.exceptions.StateValueTypeException; +import org.eclipse.tracecompass.statesystem.core.statevalue.ITmfStateValue; + +/** + * The states in concurrent state system is composed of spanId and parent spanId since there might be + * different spans with the same name and the combination of spanId and parent spanId is unique. + * The funcName also in included in the class to represent in UI. + * + * @author fateme faraji daneshgar + * + */ +@SuppressWarnings("restriction") +public class SpanCustomValue extends CustomStateValue { + + public static final CustomStateValueFactory FACTORY = (b) -> { + String spanStri = b.getString(); + String parentStr = b.getString(); + String func = b.getString(); + return new SpanCustomValue(spanStri, parentStr, func); + }; + + /** Custom type ID */ + public static final byte CUSTOM_TYPE_ID = 115; + + private final String spanId; + private final String parentSpanId; + private final String funcName; + + public SpanCustomValue(String span, String parentSpan, String func) { + spanId = span; + parentSpanId = parentSpan; + funcName = func; + } + + @Override + public int compareTo(@Nullable ITmfStateValue o) { + if (o == null) { + throw new IllegalArgumentException(); + } + if (!(o instanceof SpanCustomValue)) { + throw new StateValueTypeException("Need a TestCustomStateValue object to compare to"); //$NON-NLS-1$ + } + SpanCustomValue other = (SpanCustomValue) o; + if (spanId.equals(other.spanId)) { + if (parentSpanId.equals(other.parentSpanId)) { + if (funcName.equals(other.funcName)) { + return 1; + } + } + } + return 0; + } + + @Override + public boolean equals(@Nullable Object arg0) { + if (!(arg0 instanceof SpanCustomValue)) { + return false; + } + SpanCustomValue tcsv = (SpanCustomValue) arg0; + return (spanId.equals(tcsv.spanId)) && (parentSpanId.equals(tcsv.parentSpanId) && (funcName.equals(tcsv.funcName))); + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + spanId.hashCode(); + result = prime * result + parentSpanId.hashCode(); + result = prime * result + funcName.hashCode(); + + return result; + } + + @Override + public String toString() { + return "[span:" + spanId + ",parentSpan:" + parentSpanId + ",opName:" + funcName + "]"; + } + + @Override + protected void serializeValue(@NonNull ISafeByteBufferWriter buffer) { + buffer.putString(spanId); + buffer.putString(parentSpanId); + buffer.putString(funcName); + } + + @Override + protected int getSerializedValueSize() { + return SafeByteBufferFactory.getStringSizeInBuffer(spanId) + SafeByteBufferFactory.getStringSizeInBuffer(parentSpanId) + SafeByteBufferFactory.getStringSizeInBuffer(funcName); + } + + @Override + protected @NonNull Byte getCustomTypeId() { + return CUSTOM_TYPE_ID; + } + + public String getSpanId() { + return this.spanId; + } + + public String getParentId() { + return this.parentSpanId; + } + + public String getFunction() { + return this.funcName; + } + +} diff --git a/tracetypes/org.eclipse.tracecompass.incubator.opentracing.core/src/org/eclipse/tracecompass/incubator/opentracing/core/analysis/callstack/package-info.java b/tracetypes/org.eclipse.tracecompass.incubator.opentracing.core/src/org/eclipse/tracecompass/incubator/opentracing/core/analysis/callstack/package-info.java new file mode 100644 index 000000000..5afc24f48 --- /dev/null +++ b/tracetypes/org.eclipse.tracecompass.incubator.opentracing.core/src/org/eclipse/tracecompass/incubator/opentracing/core/analysis/callstack/package-info.java @@ -0,0 +1 @@ +package org.eclipse.tracecompass.incubator.opentracing.core.analysis.callstack; \ No newline at end of file