X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=org.eclipse.linuxtools.tmf.core%2Fsrc%2Forg%2Feclipse%2Flinuxtools%2Finternal%2Ftmf%2Fcore%2Fstatesystem%2FTransientState.java;h=c86b90641a68fd0f29162c1fd51f2f2436fb541f;hb=2e21b6d8848a9a5a2ca4cc4093d6663712afde87;hp=26f163cc901d3e6966f47fccc144c54612dd76a0;hpb=2e75ef6e4e31f4372f98e841de6cefef064e0340;p=deliverable%2Ftracecompass.git diff --git a/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/statesystem/TransientState.java b/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/statesystem/TransientState.java index 26f163cc90..c86b90641a 100644 --- a/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/statesystem/TransientState.java +++ b/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/statesystem/TransientState.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2012 Ericsson + * Copyright (c) 2012, 2013 Ericsson * Copyright (c) 2010, 2011 École Polytechnique de Montréal * Copyright (c) 2010, 2011 Alexandre Montplaisir * @@ -16,108 +16,156 @@ import java.io.PrintWriter; import java.util.ArrayList; import java.util.List; +import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.linuxtools.internal.tmf.core.statesystem.backends.IStateHistoryBackend; import org.eclipse.linuxtools.tmf.core.exceptions.AttributeNotFoundException; import org.eclipse.linuxtools.tmf.core.exceptions.StateValueTypeException; import org.eclipse.linuxtools.tmf.core.exceptions.TimeRangeException; import org.eclipse.linuxtools.tmf.core.interval.ITmfStateInterval; import org.eclipse.linuxtools.tmf.core.interval.TmfStateInterval; import org.eclipse.linuxtools.tmf.core.statevalue.ITmfStateValue; +import org.eclipse.linuxtools.tmf.core.statevalue.ITmfStateValue.Type; import org.eclipse.linuxtools.tmf.core.statevalue.TmfStateValue; /** - * The Transient State is used to build intervals from punctual state changes. It - * contains a "state info" vector similar to the "current state", except here we - * also record the start time of every state stored in it. + * The Transient State is used to build intervals from punctual state changes. + * It contains a "state info" vector similar to the "current state", except here + * we also record the start time of every state stored in it. * - * We can then build StateInterval's, to be inserted in the State History when - * we detect state changes : the "start time" of the interval will be the - * recorded time we have here, and the "end time" will be the timestamp of the - * new state-changing event we just read. - * - * @author alexmont + * We can then build {@link ITmfStateInterval}'s, to be inserted in a + * {@link IStateHistoryBackend} when we detect state changes : the "start time" + * of the interval will be the recorded time we have here, and the "end time" + * will be the timestamp of the new state-changing event we just read. * + * @author Alexandre Montplaisir */ -class TransientState { +public class TransientState { /* Indicates where to insert state changes that we generate */ - private final IStateHistoryBackend backend; + @NonNull private final IStateHistoryBackend backend; private boolean isActive; private long latestTime; - private ArrayList ongoingStateInfo; - private final ArrayList ongoingStateStartTimes; - private final ArrayList stateValueTypes; + private List ongoingStateInfo; + private List ongoingStateStartTimes; + private List stateValueTypes; - TransientState(IStateHistoryBackend backend) { + /** + * Constructor + * + * @param backend + * The back-end in which to insert the generated state intervals + */ + public TransientState(@NonNull IStateHistoryBackend backend) { this.backend = backend; isActive = true; - ongoingStateInfo = new ArrayList(); - ongoingStateStartTimes = new ArrayList(); - stateValueTypes = new ArrayList(); - - if (backend != null) { - latestTime = backend.getStartTime(); - } else { - latestTime = 0; - } + ongoingStateInfo = new ArrayList<>(); + ongoingStateStartTimes = new ArrayList<>(); + stateValueTypes = new ArrayList<>(); + + latestTime = backend.getStartTime(); } - long getLatestTime() { + /** + * Get the latest time we have seen so far. + * + * @return The latest time seen in the transient state + */ + public long getLatestTime() { return latestTime; } - ITmfStateValue getOngoingStateValue(int index) - throws AttributeNotFoundException { - - checkValidAttribute(index); - return ongoingStateInfo.get(index); + /** + * Retrieve the ongoing state value for a given index (attribute quark). + * + * @param quark + * The quark of the attribute to look for + * @return The corresponding state value + * @throws AttributeNotFoundException + * If the quark is invalid + */ + public ITmfStateValue getOngoingStateValue(int quark) throws AttributeNotFoundException { + checkValidAttribute(quark); + return ongoingStateInfo.get(quark); } - void changeOngoingStateValue(int index, ITmfStateValue newValue) - throws AttributeNotFoundException { - - checkValidAttribute(index); - ongoingStateInfo.set(index, newValue); + /** + * Retrieve the start time of the state in which the given attribute is in. + * + * @param quark + * The quark of the attribute to look for + * @return The start time of the current state for this attribute + * @throws AttributeNotFoundException + * If the quark is invalid + */ + public long getOngoingStartTime(int quark) throws AttributeNotFoundException { + checkValidAttribute(quark); + return ongoingStateStartTimes.get(quark); } /** - * Return the "ongoing" value for a given attribute as a dummy interval - * whose end time = -1 (since we don't know its real end time yet). + * Modify the current state for a given attribute. This will not update the + * "ongoing state start time" in any way, so be careful when using this. * * @param quark + * The quark of the attribute to modify + * @param newValue + * The state value the attribute should have * @throws AttributeNotFoundException + * If the quark is invalid */ - ITmfStateInterval getOngoingInterval(int quark) + public void changeOngoingStateValue(int quark, ITmfStateValue newValue) throws AttributeNotFoundException { - checkValidAttribute(quark); - return new TmfStateInterval(ongoingStateStartTimes.get(quark), -1, quark, - ongoingStateInfo.get(quark)); + ongoingStateInfo.set(quark, newValue); } - private void checkValidAttribute(int quark) - throws AttributeNotFoundException { + /** + * Convenience method to return the "ongoing" value for a given attribute as + * a dummy interval whose end time = the current latest time. + * + * @param quark + * The quark of the attribute + * @return An interval representing the current state (but whose end time is + * the current one, and probably not the "final" one) + * @throws AttributeNotFoundException + * If the quark is invalid + */ + public ITmfStateInterval getOngoingInterval(int quark) throws AttributeNotFoundException { + checkValidAttribute(quark); + return new TmfStateInterval(ongoingStateStartTimes.get(quark), latestTime, + quark, ongoingStateInfo.get(quark)); + } + private void checkValidAttribute(int quark) throws AttributeNotFoundException { if (quark > ongoingStateInfo.size() - 1 || quark < 0) { throw new AttributeNotFoundException(); } } /** - * Batch method of changeOngoingStateValue(), updates the complete - * ongoingStateInfo in one go. BE VERY CAREFUL WITH THIS! Especially with - * the sizes of both arrays. + * More advanced version of {@link #changeOngoingStateValue}. Replaces the + * complete ongoingStateInfo in one go, and updates the + * ongoingStateStartTimes and #stateValuesTypes accordingly. BE VERY CAREFUL + * WITH THIS! * - * Note that the new ongoingStateInfo will be a shallow copy of - * newStateInfo, so that last one must be already instantiated and all. - * - * @param newStateInfo - * The List of StateValues to replace the old ongoingStateInfo - * one. + * @param newStateIntervals + * The List of intervals that will represent the new + * "ongoing state". Their end times don't matter, we will only + * check their value and start times. */ - void changeOngoingStateInfo(ArrayList newStateInfo) { - this.ongoingStateInfo = newStateInfo; + public synchronized void replaceOngoingState(List newStateIntervals) { + int size = newStateIntervals.size(); + ongoingStateInfo = new ArrayList<>(size); + ongoingStateStartTimes = new ArrayList<>(size); + stateValueTypes = new ArrayList<>(size); + + for (ITmfStateInterval interval : newStateIntervals) { + ongoingStateInfo.add(interval.getStateValue()); + ongoingStateStartTimes.add(interval.getStartTime()); + stateValueTypes.add(interval.getStateValue().getType()); + } } /** @@ -125,7 +173,7 @@ class TransientState { * Ongoing... tables can stay in sync with the number of attributes in the * attribute tree, namely when we add sub-path attributes. */ - synchronized void addEmptyEntry() { + public synchronized void addEmptyEntry() { /* * Since this is a new attribute, we suppose it was in the "null state" * since the beginning (so we can have intervals covering for all @@ -133,13 +181,9 @@ class TransientState { * change. */ ongoingStateInfo.add(TmfStateValue.nullValue()); - stateValueTypes.add((byte) -1); + stateValueTypes.add(Type.NULL); - if (backend == null) { - ongoingStateStartTimes.add(0L); - } else { - ongoingStateStartTimes.add(backend.getStartTime()); - } + ongoingStateStartTimes.add(backend.getStartTime()); } /** @@ -157,43 +201,46 @@ class TransientState { * @return True if the value is present in the Transient State at this * moment in time, false if it's not */ - boolean hasInfoAboutStateOf(long time, int quark) { + public boolean hasInfoAboutStateOf(long time, int quark) { return (this.isActive() && time >= ongoingStateStartTimes.get(quark)); } /** - * This is the lower-level method that will be called by the - * StateHistorySystem (with already-built StateValues and timestamps) + * Process a state change to be inserted in the history. * - * @param index - * The index in the vectors (== the quark of the attribute) - * @param value - * The new StateValue associated to this attribute * @param eventTime * The timestamp associated with this state change + * @param value + * The new StateValue associated to this attribute + * @param quark + * The quark of the attribute that is being modified * @throws TimeRangeException + * If 'eventTime' is invalid * @throws AttributeNotFoundException + * IF 'quark' does not represent an existing attribute * @throws StateValueTypeException + * If the state value to be inserted is of a different type of + * what was inserted so far for this attribute. */ - synchronized void processStateChange(long eventTime, - ITmfStateValue value, int index) throws TimeRangeException, + public synchronized void processStateChange(long eventTime, + ITmfStateValue value, int quark) throws TimeRangeException, AttributeNotFoundException, StateValueTypeException { assert (this.isActive); - byte expectedSvType = stateValueTypes.get(index); - checkValidAttribute(index); + Type expectedSvType = stateValueTypes.get(quark); + checkValidAttribute(quark); /* * Make sure the state value type we're inserting is the same as the * one registered for this attribute. */ - if (expectedSvType == -1) { + if (expectedSvType == Type.NULL) { /* * The value hasn't been used yet, set it to the value * we're currently inserting (which might be null/-1 again). */ - stateValueTypes.set(index, value.getType()); - } else if ((value.getType() != -1) && (value.getType() != expectedSvType)) { + stateValueTypes.set(quark, value.getType()); + } else if ((value.getType() != Type.NULL) && (value.getType() != expectedSvType)) { /* * We authorize inserting null values in any type of attribute, * but for every other types, it needs to match our expectations! @@ -206,7 +253,7 @@ class TransientState { latestTime = eventTime; } - if (ongoingStateInfo.get(index).equals(value)) { + if (ongoingStateInfo.get(quark).equals(value)) { /* * This is the case where the new value and the one already present * in the Builder are the same. We do not need to create an @@ -215,19 +262,19 @@ class TransientState { return; } - if (backend != null && ongoingStateStartTimes.get(index) < eventTime) { + if (ongoingStateStartTimes.get(quark) < eventTime) { /* * These two conditions are necessary to create an interval and * update ongoingStateInfo. */ - backend.insertPastState(ongoingStateStartTimes.get(index), + backend.insertPastState(ongoingStateStartTimes.get(quark), eventTime - 1, /* End Time */ - index, /* attribute quark */ - ongoingStateInfo.get(index)); /* StateValue */ + quark, /* attribute quark */ + ongoingStateInfo.get(quark)); /* StateValue */ - ongoingStateStartTimes.set(index, eventTime); + ongoingStateStartTimes.set(quark, eventTime); } - ongoingStateInfo.set(index, value); + ongoingStateInfo.set(quark, value); return; } @@ -240,7 +287,7 @@ class TransientState { * @param t * The requested timestamp */ - void doQuery(List stateInfo, long t) { + public void doQuery(List stateInfo, long t) { ITmfStateInterval interval; if (!this.isActive) { @@ -262,11 +309,16 @@ class TransientState { } /** - * Close off the Transient State, used for example when we are done reading a - * static trace file. All the information currently contained in it will be - * converted to intervals and "flushed" to the State History. + * Close off the Transient State, used for example when we are done reading + * a static trace file. All the information currently contained in it will + * be converted to intervals and "flushed" to the state history. + * + * @param endTime + * The timestamp to use as end time for the state history (since + * it may be different than the timestamp of the last state + * change) */ - void closeTransientState(long endTime) { + public void closeTransientState(long endTime) { assert (this.isActive); for (int i = 0; i < ongoingStateInfo.size(); i++) { @@ -288,7 +340,7 @@ class TransientState { * This shouldn't happen, since we control where the interval's * start time comes from */ - e.printStackTrace(); + throw new IllegalStateException(e); } } @@ -301,22 +353,26 @@ class TransientState { /** * Simply returns if this Transient State is currently being used or not * - * @return + * @return True if this transient state is active */ - boolean isActive() { + public boolean isActive() { return this.isActive; } - void setInactive() { + /** + * Mark this transient state as inactive + */ + public void setInactive() { isActive = false; } /** - * Debugging method that prints the contents of both 'ongoing...' vectors + * Debugging method that prints the contents of the transient state * * @param writer + * The writer to which the output should be written */ - void debugPrint(PrintWriter writer) { + public void debugPrint(PrintWriter writer) { /* Only used for debugging, shouldn't be externalized */ writer.println("------------------------------"); //$NON-NLS-1$ writer.println("Info stored in the Builder:"); //$NON-NLS-1$