/******************************************************************************* * Copyright (c) 2009, 2014 Ericsson * * All rights reserved. This program and the accompanying materials are * made available under the terms of the Eclipse Public License v1.0 which * accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Francois Chouinard - Initial API and implementation * Francois Chouinard - Put in shape for 1.0 * Patrick Tasse - Updated for removal of context clone *******************************************************************************/ package org.eclipse.tracecompass.internal.tmf.core.trace.experiment; import java.util.ArrayList; import java.util.List; import org.eclipse.jdt.annotation.Nullable; import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; import org.eclipse.tracecompass.tmf.core.trace.ITmfContext; import org.eclipse.tracecompass.tmf.core.trace.TmfContext; /** * The experiment context in TMF. * <p> * The experiment keeps track of the next event from each of its traces so it * can pick the next one in chronological order. * <p> * This implies that the "next" event from each trace has already been * read and that we at least know its timestamp. * <p> * The last trace refers to the trace from which the last event was "consumed" * at the experiment level. */ public final class TmfExperimentContext extends TmfContext { // ------------------------------------------------------------------------ // Constants // ------------------------------------------------------------------------ /** * No last trace read indicator */ public static final int NO_TRACE = -1; // ------------------------------------------------------------------------ // Attributes // ------------------------------------------------------------------------ private final List<ITmfContext> fContexts; private final List<ITmfEvent> fEvents; private int fLastTraceRead; // ------------------------------------------------------------------------ // Constructors // ------------------------------------------------------------------------ /** * Standard constructor * * @param nbTraces * The number of traces in the experiment */ public TmfExperimentContext(final int nbTraces) { super(); fLastTraceRead = NO_TRACE; fContexts = new ArrayList<>(nbTraces); fEvents = new ArrayList<>(nbTraces); /* Initialize the arrays to the requested size */ for (int i = 0; i < nbTraces; i++) { fContexts.add(null); fEvents.add(null); } } @Override public void dispose() { for (ITmfContext context : fContexts) { context.dispose(); } super.dispose(); } // ------------------------------------------------------------------------ // Accessors // ------------------------------------------------------------------------ /** * Return how many traces this experiment context tracks the contexts of * (a.k.a., the number of traces in the experiment). * * @return The number of traces in the experiment */ public int getNbTraces() { return fContexts.size(); } /** * Get the current context of a specific trace * * @param traceIndex * The index of the trace in the experiment * @return The matching context object for that trace */ @Nullable public ITmfContext getContext(int traceIndex) { return fContexts.get(traceIndex); } /** * Set the context of a trace * * @param traceIndex * The index of the trace in the experiment * @param ctx * The new context object for that trace */ public void setContext(int traceIndex, ITmfContext ctx) { fContexts.set(traceIndex, ctx); } /** * Get the current event for a specific trace in the experiment. * * @param traceIndex * The index of the trace in the experiment * @return The event matching the trace/context * */ @Nullable public ITmfEvent getEvent(int traceIndex) { return fEvents.get(traceIndex); } /** * Set the context's event for a specific trace * * @param traceIndex * The index of the trace in the experiment * @param event * The event at the context in the trace */ public void setEvent(int traceIndex, ITmfEvent event) { fEvents.set(traceIndex, event); } /** * Get the index of the trace that was last read (so the trace whose * current context will match this experiment's). * * @return The index of the trace */ public int getLastTrace() { return fLastTraceRead; } /** * Set the last trace read index * * @param newIndex * The new value to assign */ public void setLastTrace(final int newIndex) { fLastTraceRead = newIndex; } // ------------------------------------------------------------------------ // Object // ------------------------------------------------------------------------ @Override public int hashCode() { int result = 17; for (int i = 0; i < fContexts.size(); i++) { result = 37 * result + fContexts.get(i).hashCode(); } return result; } @Override public boolean equals(final Object other) { if (this == other) { return true; } if (!super.equals(other)) { return false; } if (!(other instanceof TmfExperimentContext)) { return false; } final TmfExperimentContext o = (TmfExperimentContext) other; boolean isEqual = true; int i = 0; while (isEqual && (i < fContexts.size())) { isEqual &= fContexts.get(i).equals(o.fContexts.get(i)); i++; } return isEqual; } @Override @SuppressWarnings("nls") public String toString() { StringBuilder sb = new StringBuilder("TmfExperimentContext [\n"); sb.append("\tfLocation=" + getLocation() + ", fRank=" + getRank() + "\n"); sb.append("\tfContexts=["); for (int i = 0; i < fContexts.size(); i++) { sb.append("(" + fContexts.get(i).getLocation() + "," + fContexts.get(i).getRank() + ((i < fContexts.size() - 1) ? ")," : ")]\n")); } sb.append("\tfEvents=["); for (int i = 0; i < fEvents.size(); i++) { ITmfEvent event = fEvents.get(i); sb.append(((event != null) ? fEvents.get(i).getTimestamp() : "(null)") + ((i < fEvents.size() - 1) ? "," : "]\n")); } sb.append("\tfLastTraceRead=" + fLastTraceRead + "\n"); sb.append("]"); return sb.toString(); } }