tmf: Add Lost Events marker event source and factory
authorPatrick Tasse <patrick.tasse@gmail.com>
Thu, 5 Nov 2015 17:50:26 +0000 (12:50 -0500)
committerPatrick Tasse <patrick.tasse@gmail.com>
Mon, 9 Nov 2015 20:00:58 +0000 (15:00 -0500)
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 <patrick.tasse@gmail.com>
Reviewed-on: https://git.eclipse.org/r/59389
Reviewed-by: Hudson CI
Reviewed-by: Marc-Andre Laperle <marc-andre.laperle@ericsson.com>
Tested-by: Marc-Andre Laperle <marc-andre.laperle@ericsson.com>
tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/statistics/TmfStateStatistics.java
tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/statistics/TmfStatisticsEventTypesModule.java
tmf/org.eclipse.tracecompass.tmf.ui/META-INF/MANIFEST.MF
tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/Activator.java
tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/Messages.java
tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/markers/LostEventsMarkerEventSource.java [new file with mode: 0644]
tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/markers/LostEventsMarkerEventSourceFactory.java [new file with mode: 0644]
tmf/org.eclipse.tracecompass.tmf.ui/src/org/eclipse/tracecompass/internal/tmf/ui/messages.properties

index db4c38f28b6c17e746f4ff517969a97c32ca2689..9f0825d9172b118e9db19e484afdedf384e14c31 100644 (file)
@@ -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$
     }
 }
index 0ad0c8b652593e5f2b6f790db194b56876f71740..b141784907aafa519902fa01b567d00a75c55d43 100644 (file)
@@ -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:
      *
      * <pre>
      * (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
      * </pre>
      *
-     * 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;
                 }
 
index 4fd10699bbeeeeae74b61b691932074f66de2ea5..a8f229475897ff1296fc06761cf2bc555e469752 100644 (file)
@@ -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,
index 10d1dfc28f8daa8133ce7e53036b74029f24c608..d577b0ca8d703cb90851ec6760b7238912737bc2 100644 (file)
@@ -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);
     }
 
index a405a1c462c56e1b36e7a04d33bad5f5c3e9ffd2..d22c763090ba4c7f573562243aacdb9048e2f61d 100644 (file)
@@ -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 (file)
index 0000000..ae94882
--- /dev/null
@@ -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<IMarkerEvent> fLastMarkers = Collections.emptyList();
+
+    /**
+     * Constructor.
+     *
+     * @param trace
+     *            the trace
+     */
+    public LostEventsMarkerEventSource(@NonNull ITmfTrace trace) {
+        fTrace = trace;
+    }
+
+    @Override
+    public List<String> getMarkerCategories() {
+        return Arrays.asList(LOST_EVENTS);
+    }
+
+    @Override
+    public synchronized List<IMarkerEvent> 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<IMarkerEvent> 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<ITmfStateInterval> 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 (file)
index 0000000..20c25fb
--- /dev/null
@@ -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> T getTraceAdapter(ITmfTrace trace, Class<T> 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
+        };
+    }
+}
index 92170e71d3580db9d40eb4d8726211a3a3f3c04a..243194e6bd1c13031ced9cc14b079b0b6a66c8e0 100644 (file)
@@ -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
This page took 0.038201 seconds and 5 git commands to generate.