Fix for bug 385419: Streaming issues with legacy LTTng traces.
[deliverable/tracecompass.git] / org.eclipse.linuxtools.tmf.core / src / org / eclipse / linuxtools / tmf / core / trace / TmfExperiment.java
index fa06bd49fa8f1683a54bd8f1cbb5794d082c924a..5c13ebf55a27e743e1374bc91348fdffe147d0ca 100644 (file)
@@ -88,7 +88,7 @@ public class TmfExperiment<T extends ITmfEvent> extends TmfTrace<T> implements I
      * @param type
      * @param id
      * @param traces
-     * @throws TmfTraceException 
+     * @throws TmfTraceException
      */
     public TmfExperiment(final Class<T> type, final String id, final ITmfTrace<T>[] traces) {
         this(type, id, traces, DEFAULT_INDEX_PAGE_SIZE);
@@ -99,7 +99,7 @@ public class TmfExperiment<T extends ITmfEvent> extends TmfTrace<T> implements I
      * @param id
      * @param traces
      * @param indexPageSize
-     * @throws TmfTraceException 
+     * @throws TmfTraceException
      */
     @SuppressWarnings({ "unchecked", "rawtypes" })
     public TmfExperiment(final Class<T> type, final String path, final ITmfTrace<T>[] traces, final int indexPageSize) {
@@ -137,8 +137,9 @@ public class TmfExperiment<T extends ITmfEvent> extends TmfTrace<T> implements I
         }
 
         if (fTraces != null) {
-            for (final ITmfTrace trace : fTraces)
+            for (final ITmfTrace trace : fTraces) {
                 trace.dispose();
+            }
             fTraces = null;
         }
         super.dispose();
@@ -149,18 +150,18 @@ public class TmfExperiment<T extends ITmfEvent> extends TmfTrace<T> implements I
     // ------------------------------------------------------------------------
 
     /* (non-Javadoc)
-     * @see org.eclipse.linuxtools.tmf.core.trace.ITmfTrace#validate(org.eclipse.core.resources.IProject, java.lang.String)
+     * @see org.eclipse.linuxtools.tmf.core.trace.TmfTrace#initTrace(org.eclipse.core.resources.IResource, java.lang.String, java.lang.Class)
      */
     @Override
-    public boolean validate(final IProject project, final String path) {
-        return true;
+    public void initTrace(final IResource resource, final String path, final Class<T> type) {
     }
 
     /* (non-Javadoc)
-     * @see org.eclipse.linuxtools.tmf.core.trace.TmfTrace#initTrace(org.eclipse.core.resources.IResource, java.lang.String, java.lang.Class)
+     * @see org.eclipse.linuxtools.tmf.core.trace.ITmfTrace#validate(org.eclipse.core.resources.IProject, java.lang.String)
      */
     @Override
-    public void initTrace(final IResource resource, final String path, final Class<T> type) {
+    public boolean validate(final IProject project, final String path) {
+        return true;
     }
 
     // ------------------------------------------------------------------------
@@ -169,7 +170,7 @@ public class TmfExperiment<T extends ITmfEvent> extends TmfTrace<T> implements I
 
     /**
      * Selects the current, framework-wide, experiment
-     * 
+     *
      * @param experiment das experiment
      */
     public static void setCurrentExperiment(final TmfExperiment<?> experiment) {
@@ -188,7 +189,7 @@ public class TmfExperiment<T extends ITmfEvent> extends TmfTrace<T> implements I
 
     /**
      * Get the list of traces. Handle with care...
-     * 
+     *
      * @return the experiment traces
      */
     public ITmfTrace<T>[] getTraces() {
@@ -198,7 +199,7 @@ public class TmfExperiment<T extends ITmfEvent> extends TmfTrace<T> implements I
     /**
      * Returns the timestamp of the event at the requested index. If none,
      * returns null.
-     * 
+     *
      * @param index the event index (rank)
      * @return the corresponding event timestamp
      */
@@ -210,7 +211,7 @@ public class TmfExperiment<T extends ITmfEvent> extends TmfTrace<T> implements I
 
     /**
      * Set the file to be used for bookmarks on this experiment
-     * 
+     *
      * @param file the bookmarks file
      */
     public void setBookmarksFile(final IFile file) {
@@ -219,7 +220,7 @@ public class TmfExperiment<T extends ITmfEvent> extends TmfTrace<T> implements I
 
     /**
      * Get the file used for bookmarks on this experiment
-     * 
+     *
      * @return the bookmarks file or null if none is set
      */
     public IFile getBookmarksFile() {
@@ -230,8 +231,17 @@ public class TmfExperiment<T extends ITmfEvent> extends TmfTrace<T> implements I
     // Request management
     // ------------------------------------------------------------------------
 
+    /* (non-Javadoc)
+     * @see org.eclipse.linuxtools.tmf.core.trace.TmfTrace#armRequest(org.eclipse.linuxtools.tmf.core.request.ITmfDataRequest)
+     */
     @Override
-    protected ITmfContext armRequest(final ITmfDataRequest<T> request) {
+    protected synchronized ITmfContext armRequest(final ITmfDataRequest<T> request) {
+
+        // Make sure we have something to read from
+        if (fTraces == null) {
+            return null;
+        }
+
         if (request instanceof ITmfEventRequest<?>
             && !TmfTimestamp.BIG_BANG.equals(((ITmfEventRequest<T>) request).getRange().getStartTime())
             && request.getIndex() == 0)
@@ -256,9 +266,9 @@ public class TmfExperiment<T extends ITmfEvent> extends TmfTrace<T> implements I
 
     /* (non-Javadoc)
      *
-     * Returns a brand new context based on the location provided and 
+     * Returns a brand new context based on the location provided and
      * initializes the event queues
-     * 
+     *
      * @see org.eclipse.linuxtools.tmf.core.trace.ITmfTrace#seekEvent(org.eclipse.linuxtools.tmf.core.trace.ITmfLocation)
      */
     @Override
@@ -274,7 +284,7 @@ public class TmfExperiment<T extends ITmfEvent> extends TmfTrace<T> implements I
 
         // Instantiate the location
         final TmfExperimentLocation expLocation = (location == null)
-                ? new TmfExperimentLocation(new TmfLocationArray(new ITmfLocation<?>[fTraces.length])) 
+                ? new TmfExperimentLocation(new TmfLocationArray(new ITmfLocation<?>[fTraces.length]))
                 : (TmfExperimentLocation) location.clone();
 
         // Create and populate the context's traces contexts
@@ -282,8 +292,8 @@ public class TmfExperiment<T extends ITmfEvent> extends TmfTrace<T> implements I
 
         for (int i = 0; i < fTraces.length; i++) {
             // Get the relevant trace attributes
-            final ITmfLocation<?> traceLocation = expLocation.getLocation().getLocations()[i];
-            context.getContexts()[i] = fTraces[i].seekEvent(traceLocation);
+            final ITmfLocation<?> trcLocation = expLocation.getLocation().getLocations()[i];
+            context.getContexts()[i] = fTraces[i].seekEvent(trcLocation);
             expLocation.getLocation().getLocations()[i] = context.getContexts()[i].getLocation().clone();
             context.getEvents()[i] = fTraces[i].getNext(context.getContexts()[i]);
         }
@@ -291,13 +301,16 @@ public class TmfExperiment<T extends ITmfEvent> extends TmfTrace<T> implements I
         // Finalize context
         context.setLocation(expLocation);
         context.setLastTrace(TmfExperimentContext.NO_TRACE);
-        context.setRank(ITmfContext.UNKNOWN_RANK);
+        context.setRank((location == null) ? 0 : ITmfContext.UNKNOWN_RANK);
 
         fExperimentContext = context;
-
-        return (ITmfContext) context;
+        return context;
     }
 
+    // ------------------------------------------------------------------------
+    // ITmfTrace - SeekEvent operations (returning a trace context)
+    // ------------------------------------------------------------------------
+
     /* (non-Javadoc)
      * @see org.eclipse.linuxtools.tmf.core.trace.ITmfTrace#seekEvent(double)
      */
@@ -335,40 +348,32 @@ public class TmfExperiment<T extends ITmfEvent> extends TmfTrace<T> implements I
     // ------------------------------------------------------------------------
 
     /* (non-Javadoc)
-     * @see org.eclipse.linuxtools.tmf.core.trace.TmfTrace#getNext(org.eclipse.linuxtools.tmf.core.trace.ITmfContext)
+     * @see org.eclipse.linuxtools.tmf.core.trace.ITmfEventParser#parseEvent(org.eclipse.linuxtools.tmf.core.trace.ITmfContext)
      */
     @Override
-    public synchronized T getNext(final ITmfContext context) {
-        final ITmfContext previousContext = context.clone();
-        final T event = parseEvent(context);
-        if (event != null) {
-            updateAttributes(previousContext, event.getTimestamp());
-
-            fExperimentContext = (TmfExperimentContext) context;
-            int trace = fExperimentContext.getLastTrace();
-            if (trace != TmfExperimentContext.NO_TRACE) {
-                TmfExperimentLocation location = (TmfExperimentLocation) fExperimentContext.getLocation();
-                location.getLocation().getLocations()[trace] = fExperimentContext.getContexts()[trace].getLocation();
-            }
-            
-            context.increaseRank();
-            processEvent(event);
-        }
+    public synchronized T parseEvent(final ITmfContext context) {
+        final ITmfContext savedContext = context.clone();
+        final T event = getNext(savedContext);
         return event;
     }
 
     /* (non-Javadoc)
-     * @see org.eclipse.linuxtools.tmf.core.trace.ITmfEventParser#parseEvent(org.eclipse.linuxtools.tmf.core.trace.ITmfContext)
+     * @see org.eclipse.linuxtools.tmf.core.trace.TmfTrace#getNext(org.eclipse.linuxtools.tmf.core.trace.ITmfContext)
      */
-    @SuppressWarnings("unchecked")
     @Override
-    public T parseEvent(ITmfContext context) {
+    @SuppressWarnings("unchecked")
+    public synchronized T getNext(ITmfContext context) {
 
         // Validate the context
         if (!(context instanceof TmfExperimentContext)) {
             return null; // Throw an exception?
         }
 
+        // Make sure that we have something to read from
+        if (fTraces == null) {
+            return null;
+        }
+
         TmfExperimentContext expContext = (TmfExperimentContext) context;
 
         // If an event was consumed previously, first get the next one from that trace
@@ -396,9 +401,22 @@ public class TmfExperiment<T extends ITmfEvent> extends TmfTrace<T> implements I
         T event = null;
         if (trace != TmfExperimentContext.NO_TRACE) {
             event = (T) expContext.getEvents()[trace];
+            if (event != null) {
+                updateAttributes(expContext, event.getTimestamp());
+                expContext.increaseRank();
+                expContext.setLastTrace(trace);
+                final ITmfContext traceContext = expContext.getContexts()[trace];
+
+                TmfExperimentLocation location = (TmfExperimentLocation) expContext.getLocation();
+                if (location != null) {
+                    location.getLocation().getLocations()[trace] = traceContext.getLocation().clone();
+                }
+
+                fExperimentContext = expContext.clone();
+                processEvent(event);
+            }
         }
 
-        expContext.setLastTrace(trace);
         return event;
     }
 
@@ -407,7 +425,7 @@ public class TmfExperiment<T extends ITmfEvent> extends TmfTrace<T> implements I
      */
     @Override
     @SuppressWarnings("nls")
-    public String toString() {
+    public synchronized String toString() {
         return "[TmfExperiment (" + getName() + ")]";
     }
 
@@ -425,8 +443,9 @@ public class TmfExperiment<T extends ITmfEvent> extends TmfTrace<T> implements I
         if (getStreamingInterval() == 0) {
             final ITmfContext context = seekEvent(0);
             final ITmfEvent event = getNext(context);
-            if (event == null)
+            if (event == null) {
                 return;
+            }
             final TmfTimeRange timeRange = new TmfTimeRange(event.getTimestamp().clone(), TmfTimestamp.BIG_CRUNCH);
             final TmfExperimentRangeUpdatedSignal signal = new TmfExperimentRangeUpdatedSignal(this, this, timeRange);
 
@@ -442,6 +461,7 @@ public class TmfExperiment<T extends ITmfEvent> extends TmfTrace<T> implements I
 
         final Thread thread = new Thread("Streaming Monitor for experiment " + getName()) { //$NON-NLS-1$
             private ITmfTimestamp safeTimestamp = null;
+            private ITmfTimestamp lastSafeTimestamp = null;
             private TmfTimeRange timeRange = null;
 
             @Override
@@ -451,15 +471,19 @@ public class TmfExperiment<T extends ITmfEvent> extends TmfTrace<T> implements I
                         ITmfTimestamp startTimestamp = TmfTimestamp.BIG_CRUNCH;
                         ITmfTimestamp endTimestamp = TmfTimestamp.BIG_BANG;
                         for (final ITmfTrace<T> trace : fTraces) {
-                            if (trace.getStartTime().compareTo(startTimestamp) < 0)
+                            if (trace.getStartTime().compareTo(startTimestamp) < 0) {
                                 startTimestamp = trace.getStartTime();
-                            if (trace.getStreamingInterval() != 0 && trace.getEndTime().compareTo(endTimestamp) > 0)
+                            }
+                            if (trace.getStreamingInterval() != 0 && trace.getEndTime().compareTo(endTimestamp) > 0) {
                                 endTimestamp = trace.getEndTime();
+                            }
                         }
-                        if (safeTimestamp != null && safeTimestamp.compareTo(getTimeRange().getEndTime(), false) > 0)
+                        if (safeTimestamp != null && (lastSafeTimestamp == null || safeTimestamp.compareTo(lastSafeTimestamp, false) > 0)) {
                             timeRange = new TmfTimeRange(startTimestamp, safeTimestamp);
-                        else
+                            lastSafeTimestamp = safeTimestamp;
+                        } else {
                             timeRange = null;
+                        }
                         safeTimestamp = endTimestamp;
                         if (timeRange != null) {
                             final TmfExperimentRangeUpdatedSignal signal =
@@ -484,8 +508,9 @@ public class TmfExperiment<T extends ITmfEvent> extends TmfTrace<T> implements I
     @Override
     public long getStreamingInterval() {
         long interval = 0;
-        for (final ITmfTrace<T> trace : fTraces)
+        for (final ITmfTrace<T> trace : fTraces) {
             interval = Math.max(interval, trace.getStreamingInterval());
+        }
         return interval;
     }
 
@@ -497,7 +522,7 @@ public class TmfExperiment<T extends ITmfEvent> extends TmfTrace<T> implements I
 
     /**
      * Signal handler for the TmfExperimentSelectedSignal signal
-     * 
+     *
      * @param signal
      */
     @TmfSignalHandler
@@ -511,7 +536,7 @@ public class TmfExperiment<T extends ITmfEvent> extends TmfTrace<T> implements I
 
     /**
      * Signal handler for the TmfEndSynchSignal signal
-     * 
+     *
      * @param signal
      */
     @TmfSignalHandler
@@ -524,7 +549,7 @@ public class TmfExperiment<T extends ITmfEvent> extends TmfTrace<T> implements I
 
     /**
      * Signal handler for the TmfTraceUpdatedSignal signal
-     * 
+     *
      * @param signal
      */
     @TmfSignalHandler
@@ -536,7 +561,7 @@ public class TmfExperiment<T extends ITmfEvent> extends TmfTrace<T> implements I
 
     /**
      * Signal handler for the TmfExperimentRangeUpdatedSignal signal
-     * 
+     *
      * @param signal
      */
     @TmfSignalHandler
This page took 0.029316 seconds and 5 git commands to generate.