blob: 9fe996c9708437705030bebcbedd7c25cc1d7588 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2017, 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.analysis.profiling.core.base;
import java.util.ArrayList;
import java.util.Collection;
import org.eclipse.jdt.annotation.Nullable;
/**
* A basic callstack element implementing the methods of the interface.
*
* @author Geneviève Bastien
* @since 1.1
*/
public class ProfilingElement implements IProfilingElement {
/**
* The default key to use for symbol resolution if none is available
*/
public static final int DEFAULT_SYMBOL_KEY = -1;
private final String fName;
private final IProfilingGroupDescriptor fDescriptor;
private final @Nullable IProfilingGroupDescriptor fNextDescriptor;
private final Collection<IProfilingElement> fChildren = new ArrayList<>();
private final @Nullable IProfilingElement fParent;
private @Nullable IProfilingElement fSymbolKeyElement = null;
/**
* Constructor
*
* @param name
* The name of this element
* @param descriptor
* The corresponding group descriptor
*/
public ProfilingElement(String name, IProfilingGroupDescriptor descriptor) {
this(name, descriptor, null, null);
}
/**
* Constructor
*
* @param name
* The name of this element
* @param descriptor
* The corresponding group descriptor
* @param nextGroup
* The next group descriptor
* @param parent
* The parent element
*/
public ProfilingElement(String name, IProfilingGroupDescriptor descriptor, @Nullable IProfilingGroupDescriptor nextGroup, @Nullable IProfilingElement parent) {
fName = name;
fDescriptor = descriptor;
fParent = parent;
fNextDescriptor = nextGroup;
if (parent instanceof ProfilingElement) {
fSymbolKeyElement = ((ProfilingElement) parent).fSymbolKeyElement;
}
}
@Override
public Collection<IProfilingElement> getChildren() {
return fChildren;
}
@Override
public void addChild(IProfilingElement node) {
fChildren.add(node);
}
@Override
public IProfilingGroupDescriptor getGroup() {
return fDescriptor;
}
@Override
public String getName() {
return fName;
}
@Override
public boolean isLeaf() {
return fNextDescriptor == null;
}
@Override
public @Nullable IProfilingGroupDescriptor getNextGroup() {
return fNextDescriptor;
}
@Override
public void setSymbolKeyElement(IProfilingElement element) {
fSymbolKeyElement = element;
}
@Override
public boolean isSymbolKeyElement() {
return fSymbolKeyElement == this;
}
@Override
public final int getSymbolKeyAt(long startTime) {
int processId = DEFAULT_SYMBOL_KEY;
if (isSymbolKeyElement()) {
return retrieveSymbolKeyAt(startTime);
}
IProfilingElement symbolKeyElement = fSymbolKeyElement;
// if there is no symbol key element, return the default value
if (symbolKeyElement == null) {
return processId;
}
return symbolKeyElement.getSymbolKeyAt(startTime);
}
/**
* Retrieve the symbol key for this element. This method is called by
* {@link #getSymbolKeyAt(long)} when the current element is the symbol key. So
* this method should assume the current is the symbol key provider and use its
* own values to retrieve what the key to resolve symbols should be at the time
* of the query.
*
* @param time
* The time at which to resolve the symbol
* @return The symbol key at the requested time
*/
protected int retrieveSymbolKeyAt(long time) {
return DEFAULT_SYMBOL_KEY;
}
@Override
public @Nullable IProfilingElement getParentElement() {
return fParent;
}
@Override
public String toString() {
return "Element: " + getName() + '[' + fDescriptor + ']'; //$NON-NLS-1$
}
}