diff --git a/statesystem/org.eclipse.tracecompass.statesystem.core/META-INF/MANIFEST.MF b/statesystem/org.eclipse.tracecompass.statesystem.core/META-INF/MANIFEST.MF index 73026a9768..a9e7a498f0 100644 --- a/statesystem/org.eclipse.tracecompass.statesystem.core/META-INF/MANIFEST.MF +++ b/statesystem/org.eclipse.tracecompass.statesystem.core/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %Bundle-Name Bundle-Vendor: %Bundle-Vendor -Bundle-Version: 5.3.1.qualifier +Bundle-Version: 5.4.0.qualifier Bundle-Localization: plugin Bundle-SymbolicName: org.eclipse.tracecompass.statesystem.core;singleton:=true Bundle-Activator: org.eclipse.tracecompass.internal.statesystem.core.Activator diff --git a/statesystem/org.eclipse.tracecompass.statesystem.core/src/org/eclipse/tracecompass/internal/statesystem/core/StateSystem.java b/statesystem/org.eclipse.tracecompass.statesystem.core/src/org/eclipse/tracecompass/internal/statesystem/core/StateSystem.java index 950592017b..745ae8710d 100644 --- a/statesystem/org.eclipse.tracecompass.statesystem.core/src/org/eclipse/tracecompass/internal/statesystem/core/StateSystem.java +++ b/statesystem/org.eclipse.tracecompass.statesystem.core/src/org/eclipse/tracecompass/internal/statesystem/core/StateSystem.java @@ -681,4 +681,19 @@ static void logMissingInterval(int attribute, long timestamp) { attribute + " at time " + timestamp + //$NON-NLS-1$ ", returning dummy interval"); //$NON-NLS-1$ } + + /** + * @param t + * @param value + * @param attributeQuark + * @param spanQuark + * @throws TimeRangeException + * @throws StateValueTypeException + */ + @Override + public void modifySpanAttribute(long t, Object value, int attributeQuark, int spanQuark) + throws TimeRangeException, StateValueTypeException { + transState.processSpanStateChange(t, value, attributeQuark,spanQuark); + } + } diff --git a/statesystem/org.eclipse.tracecompass.statesystem.core/src/org/eclipse/tracecompass/internal/statesystem/core/TransientState.java b/statesystem/org.eclipse.tracecompass.statesystem.core/src/org/eclipse/tracecompass/internal/statesystem/core/TransientState.java index f543e600b3..eac0f278a6 100644 --- a/statesystem/org.eclipse.tracecompass.statesystem.core/src/org/eclipse/tracecompass/internal/statesystem/core/TransientState.java +++ b/statesystem/org.eclipse.tracecompass.statesystem.core/src/org/eclipse/tracecompass/internal/statesystem/core/TransientState.java @@ -511,4 +511,95 @@ public void debugPrint(PrintWriter writer) { } writer.println('\n'); } + /** + * Process a state change to be inserted in the history. + * + * @param eventTime + * The timestamp associated with this state change + * @param value + * The new StateValue associated to this attribute + * @param quark + * The transient state quark of the attribute that is being modified + * @param callStackQuark + * The callstack quark of the attribute that is being modified + * @throws TimeRangeException + * If 'eventTime' is invalid + * @throws IndexOutOfBoundsException + * If the quark is out of range + * @throws StateValueTypeException + * If the state value to be inserted is of a different type of + * what was inserted so far for this attribute. + */ + public void processSpanStateChange(long eventTime, @Nullable Object value, int quark, int callStackQuark) + throws TimeRangeException, StateValueTypeException { + if (!this.fIsActive) { + return; + } + + fRWLock.writeLock().lock(); + try { + if (value!=null) { + addEmptyEntry(); + } + Class expectedSvType = fStateValueTypes.get(quark); + + /* + * Make sure the state value type we're inserting is the same as the + * one registered for this attribute. + */ + if (expectedSvType == null) { + /* + * The value hasn't been used yet, set it to the value we're + * currently inserting (which might be null/-1 again). + */ + fStateValueTypes.set(quark, value != null ? value.getClass() : null); + } else if ((value != null) && (value.getClass() != expectedSvType)) { + /* + * We authorize inserting null values in any type of attribute, + * but for every other types, it needs to match our + * expectations! + */ + throw new StateValueTypeException(fBackend.getSSID() + " Quark:" + quark + ", Type:" + value.getClass() + ", Expected:" + expectedSvType); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + } + + if (Objects.equals(fOngoingStateInfo.get(quark), value) && !fBackend.canInsertBackwards()) { + /* + * 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 interval, we'll just keep the current one going. + */ + return; + } + + if (fOngoingStateStartTimes.get(quark) < eventTime) { + /* + * These two conditions are necessary to create an interval and + * update ongoingStateInfo. + */ + fBackend.insertPastState(fOngoingStateStartTimes.get(quark), + eventTime - 1, /* End Time */ + callStackQuark, /* attribute quark */ + fOngoingStateInfo.get(quark)); /* StateValue */ + + fOngoingStateStartTimes.set(quark, eventTime); + fOngoingStateInfo.set(quark, value); + } else if (fOngoingStateStartTimes.get(quark) == eventTime || !fBackend.canInsertBackwards()) { + fOngoingStateInfo.set(quark, value); + } else { + fBackend.insertPastState(fOngoingStateStartTimes.get(quark), + eventTime - 1, /* End Time */ + callStackQuark, /* attribute quark */ + value); /* StateValue */ + fOngoingStateStartTimes.set(quark, eventTime); + } + + /* Update the Transient State's lastestTime, if needed */ + if (fLatestTime < eventTime) { + fLatestTime = eventTime; + } + + } finally { + fRWLock.writeLock().unlock(); + } + } } diff --git a/statesystem/org.eclipse.tracecompass.statesystem.core/src/org/eclipse/tracecompass/statesystem/core/ITmfStateSystem.java b/statesystem/org.eclipse.tracecompass.statesystem.core/src/org/eclipse/tracecompass/statesystem/core/ITmfStateSystem.java index 01831a022b..8986d0b321 100644 --- a/statesystem/org.eclipse.tracecompass.statesystem.core/src/org/eclipse/tracecompass/statesystem/core/ITmfStateSystem.java +++ b/statesystem/org.eclipse.tracecompass.statesystem.core/src/org/eclipse/tracecompass/statesystem/core/ITmfStateSystem.java @@ -21,6 +21,7 @@ import org.eclipse.jdt.annotation.Nullable; import org.eclipse.tracecompass.statesystem.core.exceptions.AttributeNotFoundException; import org.eclipse.tracecompass.statesystem.core.exceptions.StateSystemDisposedException; +import org.eclipse.tracecompass.statesystem.core.exceptions.StateValueTypeException; import org.eclipse.tracecompass.statesystem.core.exceptions.TimeRangeException; import org.eclipse.tracecompass.statesystem.core.interval.ITmfStateInterval; import org.eclipse.tracecompass.statesystem.core.statevalue.ITmfStateValue; @@ -540,4 +541,15 @@ int getQuarkRelative(int startingNodeQuark, String... subPath) */ Iterable<@NonNull ITmfStateInterval> query2D(@NonNull Collection quarks, long start, long end) throws StateSystemDisposedException, IndexOutOfBoundsException, TimeRangeException; + + /** + * @param t + * @param value + * @param attributeQuark + * @param spanQuark + * @throws TimeRangeException + * @throws StateValueTypeException + * @since 5.4 + */ + void modifySpanAttribute(long t, Object value, int attributeQuark, int spanQuark) throws TimeRangeException, StateValueTypeException; } \ No newline at end of file