From c53cebea8f576ee49bc07de8c4d7fa90ef408028 Mon Sep 17 00:00:00 2001 From: Patrick Tasse Date: Thu, 5 Nov 2015 12:50:26 -0500 Subject: [PATCH] tmf: Add Lost Events marker event source and factory A marker event source factory for Lost Events is enabled for all traces. The marker event source can reuse a previously returned marker list if the requested parameters are identical to the previous request. The event types statistics state system is updated to add a new attribute which is used to compute the time ranges that are covered by at least one lost event time range. Change-Id: I2479afc3f07deb363f5847f4816940010bae3e9e Signed-off-by: Patrick Tasse Reviewed-on: https://git.eclipse.org/r/59389 Reviewed-by: Hudson CI Reviewed-by: Marc-Andre Laperle Tested-by: Marc-Andre Laperle --- .../core/statistics/TmfStateStatistics.java | 8 +- .../TmfStatisticsEventTypesModule.java | 40 ++++-- .../META-INF/MANIFEST.MF | 1 + .../internal/tmf/ui/Activator.java | 8 ++ .../internal/tmf/ui/Messages.java | 1 + .../markers/LostEventsMarkerEventSource.java | 136 ++++++++++++++++++ .../LostEventsMarkerEventSourceFactory.java | 39 +++++ .../internal/tmf/ui/messages.properties | 1 + 8 files changed, 221 insertions(+), 13 deletions(-) create mode 100644 tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/markers/LostEventsMarkerEventSource.java create mode 100644 tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/markers/LostEventsMarkerEventSourceFactory.java diff --git a/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/statistics/TmfStateStatistics.java b/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/statistics/TmfStateStatistics.java index db4c38f28b..9f0825d917 100644 --- a/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/statistics/TmfStateStatistics.java +++ b/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/statistics/TmfStateStatistics.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2012, 2014 Ericsson + * Copyright (c) 2012, 2015 Ericsson * * All rights reserved. This program and the accompanying materials are * made available under the terms of the Eclipse Public License v1.0 which @@ -314,6 +314,10 @@ public class TmfStateStatistics implements ITmfStatistics { public static final String TOTAL = "total"; //$NON-NLS-1$ /** event_types */ - public static final String EVENT_TYPES = "event_types"; //$NON-NLS-1$< + public static final String EVENT_TYPES = "event_types"; //$NON-NLS-1$ + + /** lost_events + * @since 2.0*/ + public static final String LOST_EVENTS = "lost_events"; //$NON-NLS-1$ } } diff --git a/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/statistics/TmfStatisticsEventTypesModule.java b/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/statistics/TmfStatisticsEventTypesModule.java index 0ad0c8b652..b141784907 100644 --- a/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/statistics/TmfStatisticsEventTypesModule.java +++ b/tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/statistics/TmfStatisticsEventTypesModule.java @@ -8,6 +8,7 @@ * * Contributors: * Alexandre Montplaisir - Initial API and implementation + * Patrick Tasse - Added lost events attribute ******************************************************************************/ package org.eclipse.tracecompass.tmf.core.statistics; @@ -19,6 +20,7 @@ import org.eclipse.tracecompass.statesystem.core.ITmfStateSystemBuilder; import org.eclipse.tracecompass.statesystem.core.exceptions.AttributeNotFoundException; import org.eclipse.tracecompass.statesystem.core.exceptions.StateValueTypeException; import org.eclipse.tracecompass.statesystem.core.exceptions.TimeRangeException; +import org.eclipse.tracecompass.statesystem.core.statevalue.ITmfStateValue; import org.eclipse.tracecompass.statesystem.core.statevalue.TmfStateValue; import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; import org.eclipse.tracecompass.tmf.core.event.ITmfLostEvent; @@ -70,21 +72,27 @@ public class TmfStatisticsEventTypesModule extends TmfStateSystemAnalysisModule * The state provider for traces statistics that use TmfStateStatistics. It * should work with any trace type for which we can use the state system. * - * It will store number of events seen, per event types. The resulting attribute - * tree will look like this: + * It will store number of events seen, per event types. The resulting + * attribute tree will look like this: * *
      * (root)
-     *   \-- event_types
-     *        |-- (event name 1)
-     *        |-- (event name 2)
-     *        |-- (event name 3)
-     *       ...
+     *   |-- event_types
+     *   |    |-- (event name 1)
+     *   |    |-- (event name 2)
+     *   |    |-- (event name 3)
+     *   |   ...
+     *   \-- lost_events
      * 
* - * And each (event name)'s value will be an integer, representing how many times + * Each (event name)'s value will be an integer, representing how many times * this particular event type has been seen in the trace so far. * + * The value of the lost_events attribute will be a long, representing the + * latest end time of any current or previous lost event time range, in + * nanoseconds. If the value at a specific time 't' is greater than 't', + * then there is at least one lost event time range that overlaps time 't'. + * * @author Alexandre Montplaisir * @version 1.0 */ @@ -94,7 +102,7 @@ public class TmfStatisticsEventTypesModule extends TmfStateSystemAnalysisModule * Version number of this input handler. Please bump this if you modify the * contents of the generated state history in some way. */ - private static final int VERSION = 2; + private static final int VERSION = 3; /** * Constructor @@ -138,8 +146,18 @@ public class TmfStatisticsEventTypesModule extends TmfStateSystemAnalysisModule curVal = 0; } - TmfStateValue value = TmfStateValue.newValueInt((int) (curVal + le.getNbLostEvents())); - ss.modifyAttribute(ts, value, quark); + ITmfStateValue value1 = TmfStateValue.newValueInt((int) (curVal + le.getNbLostEvents())); + ss.modifyAttribute(ts, value1, quark); + + long lostEventsStartTime = le.getTimeRange().getStartTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(); + long lostEventsEndTime = le.getTimeRange().getEndTime().normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue(); + int lostEventsQuark = ss.getQuarkAbsoluteAndAdd(Attributes.LOST_EVENTS); + ITmfStateValue currentLostEventsEndTime = ss.queryOngoingState(lostEventsQuark); + if (currentLostEventsEndTime.isNull() || currentLostEventsEndTime.unboxLong() < lostEventsStartTime) { + ss.modifyAttribute(lostEventsStartTime, TmfStateValue.newValueLong(lostEventsEndTime), lostEventsQuark); + } else if (currentLostEventsEndTime.unboxLong() < lostEventsEndTime) { + ss.updateOngoingState(TmfStateValue.newValueLong(lostEventsEndTime), lostEventsQuark); + } return; } diff --git a/tmf/org.eclipse.tracecompass.tmf.ui/META-INF/MANIFEST.MF b/tmf/org.eclipse.tracecompass.tmf.ui/META-INF/MANIFEST.MF index 4fd10699bb..a8f2294758 100644 --- a/tmf/org.eclipse.tracecompass.tmf.ui/META-INF/MANIFEST.MF +++ b/tmf/org.eclipse.tracecompass.tmf.ui/META-INF/MANIFEST.MF @@ -30,6 +30,7 @@ Export-Package: org.eclipse.tracecompass.internal.tmf.ui;x-friends:="org.eclipse org.eclipse.tracecompass.internal.tmf.ui.dialogs;x-internal:=true, org.eclipse.tracecompass.internal.tmf.ui.editors;x-internal:=true, org.eclipse.tracecompass.internal.tmf.ui.editors.handlers;x-internal:=true, + org.eclipse.tracecompass.internal.tmf.ui.markers;x-internal:=true, org.eclipse.tracecompass.internal.tmf.ui.parsers;x-internal:=true, org.eclipse.tracecompass.internal.tmf.ui.parsers.wizards;x-friends:="org.eclipse.tracecompass.tmf.ui.tests", org.eclipse.tracecompass.internal.tmf.ui.preferences;x-internal:=true, diff --git a/tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/Activator.java b/tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/Activator.java index 10d1dfc28f..d577b0ca8d 100644 --- a/tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/Activator.java +++ b/tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/Activator.java @@ -20,7 +20,10 @@ import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.jface.resource.ImageDescriptor; import org.eclipse.jface.resource.ImageRegistry; import org.eclipse.swt.graphics.Image; +import org.eclipse.tracecompass.internal.tmf.ui.markers.LostEventsMarkerEventSourceFactory; import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; +import org.eclipse.tracecompass.tmf.core.trace.TmfTraceAdapterManager; import org.eclipse.tracecompass.tmf.ui.TmfUiRefreshHandler; import org.eclipse.tracecompass.tmf.ui.project.model.TmfExperimentElement; import org.eclipse.tracecompass.tmf.ui.project.model.TmfTraceElement; @@ -53,6 +56,7 @@ public class Activator extends AbstractUIPlugin { private static Activator plugin; private TmfEventAdapterFactory fTmfEventAdapterFactory; + private LostEventsMarkerEventSourceFactory fLostEventMarkerEventSourceFactory; private IPreferenceStore fCorePreferenceStore; // ------------------------------------------------------------------------ @@ -93,6 +97,8 @@ public class Activator extends AbstractUIPlugin { fTmfEventAdapterFactory = new TmfEventAdapterFactory(); Platform.getAdapterManager().registerAdapters(fTmfEventAdapterFactory, ITmfEvent.class); + fLostEventMarkerEventSourceFactory = new LostEventsMarkerEventSourceFactory(); + TmfTraceAdapterManager.registerFactory(fLostEventMarkerEventSourceFactory, ITmfTrace.class); } @Override @@ -102,6 +108,8 @@ public class Activator extends AbstractUIPlugin { plugin = null; Platform.getAdapterManager().unregisterAdapters(fTmfEventAdapterFactory); + TmfTraceAdapterManager.unregisterFactory(fLostEventMarkerEventSourceFactory); + fLostEventMarkerEventSourceFactory.dispose(); super.stop(context); } diff --git a/tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/Messages.java b/tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/Messages.java index a405a1c462..d22c763090 100644 --- a/tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/Messages.java +++ b/tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/Messages.java @@ -39,6 +39,7 @@ public class Messages extends NLS { public static String ManageCustomParsersDialog_TextButtonLabel; public static String MarkerEvent_Bookmarks; + public static String MarkerEvent_LostEvents; public static String TmfEventsTable_AddBookmarkActionText; public static String TmfEventsTable_ApplyPresetFilterMenuName; diff --git a/tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/markers/LostEventsMarkerEventSource.java b/tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/markers/LostEventsMarkerEventSource.java new file mode 100644 index 0000000000..ae9488295c --- /dev/null +++ b/tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/markers/LostEventsMarkerEventSource.java @@ -0,0 +1,136 @@ +/******************************************************************************* + * Copyright (c) 2015 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: + * Patrick Tasse - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.ui.markers; + +import static org.eclipse.tracecompass.common.core.NonNullUtils.checkNotNull; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.jdt.annotation.NonNull; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.graphics.RGBA; +import org.eclipse.swt.widgets.Display; +import org.eclipse.tracecompass.internal.tmf.ui.Messages; +import org.eclipse.tracecompass.statesystem.core.ITmfStateSystem; +import org.eclipse.tracecompass.statesystem.core.StateSystemUtils; +import org.eclipse.tracecompass.statesystem.core.exceptions.AttributeNotFoundException; +import org.eclipse.tracecompass.statesystem.core.exceptions.StateSystemDisposedException; +import org.eclipse.tracecompass.statesystem.core.interval.ITmfStateInterval; +import org.eclipse.tracecompass.tmf.core.statistics.TmfStateStatistics.Attributes; +import org.eclipse.tracecompass.tmf.core.statistics.TmfStatisticsEventTypesModule; +import org.eclipse.tracecompass.tmf.core.statistics.TmfStatisticsModule; +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; +import org.eclipse.tracecompass.tmf.core.trace.TmfTraceUtils; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.IMarkerEvent; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.IMarkerEventSource; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.MarkerEvent; + +/** + * Marker event source for lost events. + */ +public class LostEventsMarkerEventSource implements IMarkerEventSource { + + private static final String LOST_EVENTS = Messages.MarkerEvent_LostEvents; + + private static final Color COLOR = new Color(Display.getDefault(), new RGBA(255, 0, 0, 50)); + + private final @NonNull ITmfTrace fTrace; + private long[] fLastRequest; + private @NonNull List fLastMarkers = Collections.emptyList(); + + /** + * Constructor. + * + * @param trace + * the trace + */ + public LostEventsMarkerEventSource(@NonNull ITmfTrace trace) { + fTrace = trace; + } + + @Override + public List getMarkerCategories() { + return Arrays.asList(LOST_EVENTS); + } + + @Override + public synchronized List getMarkerList(String category, long startTime, long endTime, long resolution, IProgressMonitor monitor) { + if (!category.equals(LOST_EVENTS)) { + return Collections.emptyList(); + } + ITmfStateSystem ss = getStateSystem(); + if (ss == null) { + return Collections.emptyList(); + } + int lostEventsQuark = getLostEventsQuark(ss); + if (lostEventsQuark == -1) { + return Collections.emptyList(); + } + long[] request = new long[] { startTime, endTime, resolution, ss.getCurrentEndTime() }; + if (Arrays.equals(request, fLastRequest)) { + return fLastMarkers; + } + List markers = new ArrayList<>(); + try { + long start = Math.max(startTime, ss.getStartTime()); + long end = Math.min(endTime, ss.getCurrentEndTime()); + if (start <= end) { + /* Update start to ensure that the previous marker is included. */ + start = Math.max(start - 1, ss.getStartTime()); + /* Update end to ensure that the next marker is included. */ + long nextStartTime = ss.querySingleState(end, lostEventsQuark).getEndTime() + 1; + end = Math.min(nextStartTime, ss.getCurrentEndTime()); + List intervals = StateSystemUtils.queryHistoryRange(ss, lostEventsQuark, start, end, resolution, monitor); + for (ITmfStateInterval interval : intervals) { + if (interval.getStateValue().isNull()) { + continue; + } + long lostEventsStartTime = interval.getStartTime(); + /* + * The end time of the lost events range is the value of the + * attribute, not the end time of the interval. + */ + long lostEventsEndTime = interval.getStateValue().unboxLong(); + long duration = lostEventsEndTime - lostEventsStartTime; + IMarkerEvent marker = new MarkerEvent(null, lostEventsStartTime, duration, LOST_EVENTS, COLOR, null, false); + markers.add(marker); + } + } + } catch (AttributeNotFoundException | StateSystemDisposedException e) { + /* ignored */ + } + fLastRequest = request; + fLastMarkers = Collections.unmodifiableList(markers); + return fLastMarkers; + } + + private ITmfStateSystem getStateSystem() { + TmfStatisticsModule module = TmfTraceUtils.getAnalysisModuleOfClass(fTrace, TmfStatisticsModule.class, TmfStatisticsModule.ID); + if (module == null) { + return null; + } + return module.getStateSystem(checkNotNull(TmfStatisticsEventTypesModule.ID)); + } + + private static int getLostEventsQuark(ITmfStateSystem ss) { + try { + return ss.getQuarkAbsolute(Attributes.LOST_EVENTS); + } catch (AttributeNotFoundException e) { + return -1; + } + } +} diff --git a/tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/markers/LostEventsMarkerEventSourceFactory.java b/tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/markers/LostEventsMarkerEventSourceFactory.java new file mode 100644 index 0000000000..20c25fb176 --- /dev/null +++ b/tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/markers/LostEventsMarkerEventSourceFactory.java @@ -0,0 +1,39 @@ +/******************************************************************************* + * Copyright (c) 2015 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: + * Patrick Tasse - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.tracecompass.internal.tmf.ui.markers; + +import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; +import org.eclipse.tracecompass.tmf.core.trace.AbstractTmfTraceAdapterFactory; +import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.IMarkerEventSource; + +/** + * Marker event source factory for lost events. + */ +public class LostEventsMarkerEventSourceFactory extends AbstractTmfTraceAdapterFactory { + + @Override + protected T getTraceAdapter(ITmfTrace trace, Class adapterType) { + if (IMarkerEventSource.class.equals(adapterType)) { + IMarkerEventSource adapter = new LostEventsMarkerEventSource(trace); + return adapterType.cast(adapter); + } + return null; + } + + @Override + public Class[] getAdapterList() { + return new Class[] { + IMarkerEventSource.class + }; + } +} diff --git a/tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/messages.properties b/tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/messages.properties index 92170e71d3..243194e6bd 100644 --- a/tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/messages.properties +++ b/tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/messages.properties @@ -86,6 +86,7 @@ TmfTimeFilterDialog_UNCHECK_SUBTREE=Uncheck subtree # org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model MarkerEvent_Bookmarks=Bookmarks +MarkerEvent_LostEvents=Lost Events # org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets TmfTimeTipHandler_DURATION=Duration -- 2.34.1