| /******************************************************************************* |
| * Copyright (c) 2015 É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 |
| * |
| * Contributors: |
| * Francis Giraldeau - Initial implementation and API |
| * Geneviève Bastien - Initial implementation and API |
| *******************************************************************************/ |
| |
| package org.eclipse.tracecompass.analysis.graph.core.base; |
| |
| import java.util.Map; |
| |
| import org.eclipse.jdt.annotation.Nullable; |
| import org.eclipse.tracecompass.internal.analysis.graph.core.base.Messages; |
| import org.eclipse.tracecompass.tmf.core.dataprovider.X11ColorUtils; |
| import org.eclipse.tracecompass.tmf.core.model.StyleProperties; |
| |
| import com.google.common.collect.ImmutableMap; |
| |
| /** |
| * Edge of a TmfGraph |
| * |
| * @author Francis Giraldeau |
| * @author Geneviève Bastien |
| */ |
| public class TmfEdge { |
| |
| /** |
| * Enumeration of the different types of edges |
| * |
| * FIXME: this sounds very specific to kernel traces, maybe it shouldn't be |
| * here |
| * |
| * Comment by gbastien: I think the edge itself should be either a green |
| * light or a red light and there could be a context specific qualifier to |
| * go along |
| * |
| * How about something like this: |
| * |
| * <pre> |
| * public enum EdgeState { |
| * PASS, |
| * STOP |
| * [,EPS] (for "fake" edge to allow 2 vertices at the same timestamp to many vertical edges) |
| * } |
| * |
| * public ISomeInterface { |
| * } |
| * |
| * public enum KernelEdgeType implements ISomeInterface { |
| * RUNNING, BLOCKED, INTERRUPTED, ... |
| * } |
| * |
| * public class EdgeType { |
| * private EdgeState fState; |
| * private ISomeInterface fQualifier; |
| * } |
| * </pre> |
| */ |
| public enum EdgeType { |
| |
| /** |
| * Special edge, so it is possible to have two vertices at the same |
| * timestamp |
| */ |
| EPS(String.valueOf(Messages.TmfEdge_Unknown), 0x40, 0x3b, 0x33, 255, 1.0f, String.valueOf(Messages.TmfEdge_GroupBlocked)), |
| /** Unknown edge */ |
| UNKNOWN(String.valueOf(Messages.TmfEdge_Unknown), 0x40, 0x3b, 0x33, 255, 1.0f, String.valueOf(Messages.TmfEdge_GroupBlocked)), |
| /** Default type for an edge */ |
| DEFAULT(String.valueOf(Messages.TmfEdge_Unknown), 0x40, 0x3b, 0x33, 255, 1.0f, String.valueOf(Messages.TmfEdge_GroupBlocked)), |
| /** Worker is running */ |
| RUNNING(String.valueOf(Messages.TmfEdge_Running), 0x33, 0x99, 0x00, 255, 1.0f, String.valueOf(Messages.TmfEdge_GroupRunning)), |
| /** Worker is blocked */ |
| BLOCKED(String.valueOf(Messages.TmfEdge_Blocked), 220, 20, 60, 255, 1.0f, String.valueOf(Messages.TmfEdge_GroupBlocked)), |
| /** Worker is in an interrupt state */ |
| INTERRUPTED(String.valueOf(Messages.TmfEdge_Interrupted), 0xff, 0xdc, 0x00, 255, 1.0f, String.valueOf(Messages.TmfEdge_GroupBlocked)), |
| /** Worker is preempted */ |
| PREEMPTED(String.valueOf(Messages.TmfEdge_Preempted), 0xc8, 0x64, 0x00, 255, 1.0f, String.valueOf(Messages.TmfEdge_GroupBlocked)), |
| /** In a timer */ |
| TIMER(String.valueOf(Messages.TmfEdge_Timer), 0x33, 0x66, 0x99, 255, 1.0f, String.valueOf(Messages.TmfEdge_GroupBlocked)), |
| /** Edge represents a network communication */ |
| NETWORK(String.valueOf(Messages.TmfEdge_Network), 0xff, 0x9b, 0xff, 255, 1.0f, String.valueOf(Messages.TmfEdge_GroupBlocked)), |
| /** Worker is waiting for user input */ |
| USER_INPUT(String.valueOf(Messages.TmfEdge_UserInput), 0x5a, 0x01, 0x01, 255, 1.0f, String.valueOf(Messages.TmfEdge_GroupBlocked)), |
| /** Block device */ |
| BLOCK_DEVICE(String.valueOf(Messages.TmfEdge_BlockDevice), 0x66, 0x00, 0xcc, 255, 1.0f, String.valueOf(Messages.TmfEdge_GroupBlocked)), |
| /** inter-processor interrupt */ |
| IPI(String.valueOf(Messages.TmfEdge_IPI), 0x66, 0x66, 0xcc, 255, 1.0f, String.valueOf(Messages.TmfEdge_GroupBlocked)); |
| |
| private final Map<String, Object> fMap; |
| |
| /** |
| * A Linux style |
| * |
| * @param label |
| * the label of the style |
| * @param red |
| * red value, must be between 0 and 255 |
| * @param green |
| * green value, must be between 0 and 255 |
| * @param blue |
| * blue value, must be between 0 and 255 |
| * @param alpha |
| * value, must be between 0 and 255 |
| * @param heightFactor |
| * the hint of the height, between 0 and 1.0 |
| * @param group |
| * the group string this style belongs to |
| */ |
| private EdgeType(String label, int red, int green, int blue, int alpha, float heightFactor, String group) { |
| if (red > 255 || red < 0) { |
| throw new IllegalArgumentException("Red needs to be between 0 and 255"); //$NON-NLS-1$ |
| } |
| if (green > 255 || green < 0) { |
| throw new IllegalArgumentException("Green needs to be between 0 and 255"); //$NON-NLS-1$ |
| } |
| if (blue > 255 || blue < 0) { |
| throw new IllegalArgumentException("Blue needs to be between 0 and 255"); //$NON-NLS-1$ |
| } |
| if (alpha > 255 || alpha < 0) { |
| throw new IllegalArgumentException("alpha needs to be between 0 and 255"); //$NON-NLS-1$ |
| } |
| if (heightFactor > 1.0 || heightFactor < 0) { |
| throw new IllegalArgumentException("Height factor needs to be between 0 and 1.0, given hint : " + heightFactor); //$NON-NLS-1$ |
| } |
| fMap = ImmutableMap.of(StyleProperties.STYLE_NAME, label, |
| StyleProperties.BACKGROUND_COLOR, X11ColorUtils.toHexColor(red, green, blue), |
| StyleProperties.HEIGHT, heightFactor, |
| StyleProperties.OPACITY, (float) alpha / 255, |
| StyleProperties.STYLE_GROUP, group); |
| } |
| |
| /** |
| * Get a map of the values corresponding to the fields in |
| * {@link StyleProperties} |
| * |
| * @return the map corresponding to the api defined in |
| * {@link StyleProperties} |
| * @since 2.1 |
| */ |
| public Map<String, Object> toMap() { |
| return fMap; |
| } |
| } |
| |
| private final TmfVertex fVertexFrom; |
| private final TmfVertex fVertexTo; |
| private EdgeType fType; |
| private @Nullable String fQualifier = null; |
| |
| /** |
| * Constructor |
| * |
| * @param from |
| * The vertex this edge leaves from |
| * @param to |
| * The vertex the edge leads to |
| */ |
| public TmfEdge(TmfVertex from, TmfVertex to) { |
| fVertexFrom = from; |
| fVertexTo = to; |
| fType = EdgeType.DEFAULT; |
| } |
| |
| /* |
| * Getters |
| */ |
| |
| /** |
| * Get the origin vertex of this edge |
| * |
| * @return The origin vertex |
| */ |
| public TmfVertex getVertexFrom() { |
| return fVertexFrom; |
| } |
| |
| /** |
| * Get the destination vertex of this edge |
| * |
| * @return The destination vertex |
| */ |
| public TmfVertex getVertexTo() { |
| return fVertexTo; |
| } |
| |
| /** |
| * Get the edge type |
| * |
| * @return The type of the edge |
| */ |
| public EdgeType getType() { |
| return fType; |
| } |
| |
| /** |
| * Sets the edge type |
| * |
| * @param type |
| * The edge type |
| */ |
| public void setType(final EdgeType type) { |
| fType = type; |
| } |
| |
| /** |
| * Sets the edge type |
| * |
| * @param type |
| * The edge type |
| * @param linkQualifier |
| * A string to qualify this link |
| * @since 2.1 |
| */ |
| public void setType(EdgeType type, @Nullable String linkQualifier) { |
| fType = type; |
| fQualifier = linkQualifier; |
| } |
| |
| /** |
| * Get the link qualifier, ie a descriptor for the link. This has no effect on |
| * the graph or critical path |
| * |
| * @return The link qualifier |
| * @since 2.1 |
| */ |
| public @Nullable String getLinkQualifier() { |
| return fQualifier; |
| } |
| |
| /** |
| * Returns the duration of the edge |
| * |
| * @return The duration (in nanoseconds) |
| */ |
| public long getDuration() { |
| return fVertexTo.getTs() - fVertexFrom.getTs(); |
| } |
| |
| @Override |
| public String toString() { |
| return "[" + fVertexFrom + "--" + fType + "->" + fVertexTo + "]"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ |
| } |
| |
| } |