ctf/tmf: allow multiple traces to be open with name clashing events
[deliverable/tracecompass.git] / org.eclipse.linuxtools.tmf.core / src / org / eclipse / linuxtools / tmf / core / ctfadaptor / CtfTmfTrace.java
index f1b6427a27e356611cb8afc730aca4a755bc4364..66d53cd203dcdf925bb415de9a315cd0db73b5f9 100644 (file)
@@ -1,29 +1,48 @@
 /*******************************************************************************
- * Copyright (c) 2012 Ericsson
+ * Copyright (c) 2012, 2014 Ericsson, École Polytechnique de Montréal
  *
  * 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: Matthew Khouzam - Initial API and implementation
+ * Contributors:
+ *   Matthew Khouzam - Initial API and implementation
+ *   Patrick Tasse - Updated for removal of context clone
+ *   Geneviève Bastien - Added the createTimestamp function
  *******************************************************************************/
 
 package org.eclipse.linuxtools.tmf.core.ctfadaptor;
 
+import java.nio.BufferOverflowException;
+import java.nio.ByteBuffer;
+import java.util.Map;
+
 import org.eclipse.core.resources.IProject;
 import org.eclipse.core.resources.IResource;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.linuxtools.ctf.core.event.CTFClock;
+import org.eclipse.linuxtools.ctf.core.event.IEventDeclaration;
 import org.eclipse.linuxtools.ctf.core.trace.CTFReaderException;
 import org.eclipse.linuxtools.ctf.core.trace.CTFTrace;
+import org.eclipse.linuxtools.ctf.core.trace.CTFTraceReader;
+import org.eclipse.linuxtools.internal.tmf.core.Activator;
 import org.eclipse.linuxtools.tmf.core.event.ITmfEvent;
-import org.eclipse.linuxtools.tmf.core.event.ITmfTimestamp;
-import org.eclipse.linuxtools.tmf.core.event.TmfTimestamp;
 import org.eclipse.linuxtools.tmf.core.exceptions.TmfTraceException;
-import org.eclipse.linuxtools.tmf.core.statesystem.ITmfStateSystem;
+import org.eclipse.linuxtools.tmf.core.timestamp.ITmfTimestamp;
+import org.eclipse.linuxtools.tmf.core.timestamp.TmfTimestamp;
 import org.eclipse.linuxtools.tmf.core.trace.ITmfContext;
 import org.eclipse.linuxtools.tmf.core.trace.ITmfEventParser;
-import org.eclipse.linuxtools.tmf.core.trace.ITmfLocation;
+import org.eclipse.linuxtools.tmf.core.trace.ITmfTraceProperties;
 import org.eclipse.linuxtools.tmf.core.trace.TmfTrace;
+import org.eclipse.linuxtools.tmf.core.trace.TraceValidationStatus;
+import org.eclipse.linuxtools.tmf.core.trace.indexer.ITmfPersistentlyIndexable;
+import org.eclipse.linuxtools.tmf.core.trace.indexer.ITmfTraceIndexer;
+import org.eclipse.linuxtools.tmf.core.trace.indexer.TmfBTreeTraceIndexer;
+import org.eclipse.linuxtools.tmf.core.trace.indexer.checkpoint.ITmfCheckpoint;
+import org.eclipse.linuxtools.tmf.core.trace.indexer.checkpoint.TmfCheckpoint;
+import org.eclipse.linuxtools.tmf.core.trace.location.ITmfLocation;
 
 /**
  * The CTf trace handler
@@ -31,32 +50,33 @@ import org.eclipse.linuxtools.tmf.core.trace.TmfTrace;
  * @version 1.0
  * @author Matthew khouzam
  */
-public class CtfTmfTrace extends TmfTrace implements ITmfEventParser {
-
+public class CtfTmfTrace extends TmfTrace
+        implements ITmfEventParser, ITmfTraceProperties, ITmfPersistentlyIndexable {
 
-    //-------------------------------------------
-    //        Constants
-    //-------------------------------------------
+    // -------------------------------------------
+    // Constants
+    // -------------------------------------------
     /**
      * Default cache size for CTF traces
      */
     protected static final int DEFAULT_CACHE_SIZE = 50000;
 
-    //-------------------------------------------
-    //        Fields
-    //-------------------------------------------
+    /*
+     * The Ctf clock unique identifier field
+     */
+    private static final String CLOCK_HOST_PROPERTY = "uuid"; //$NON-NLS-1$
+    private static final int CONFIDENCE = 10;
 
-    /** Reference to the state system assigned to this trace */
-    protected ITmfStateSystem ss = null;
+    // -------------------------------------------
+    // Fields
+    // -------------------------------------------
 
     /* Reference to the CTF Trace */
     private CTFTrace fTrace;
 
-
-
-    //-------------------------------------------
-    //        TmfTrace Overrides
-    //-------------------------------------------
+    // -------------------------------------------
+    // TmfTrace Overrides
+    // -------------------------------------------
     /**
      * Method initTrace.
      *
@@ -67,7 +87,7 @@ public class CtfTmfTrace extends TmfTrace implements ITmfEventParser {
      * @param eventType
      *            The type of events that will be read from this trace
      * @throws TmfTraceException
-     *             If something when wrong while reading the trace
+     *             If something went wrong while reading the trace
      */
     @Override
     public void initTrace(final IResource resource, final String path, final Class<? extends ITmfEvent> eventType)
@@ -78,17 +98,16 @@ public class CtfTmfTrace extends TmfTrace implements ITmfEventParser {
          */
         setCacheSize();
 
-        @SuppressWarnings("unused")
-        CtfTmfEventType type;
+        super.initTrace(resource, path, eventType);
 
         try {
             this.fTrace = new CTFTrace(path);
             CtfIteratorManager.addTrace(this);
-            CtfTmfLightweightContext ctx;
+            CtfTmfContext ctx;
             /* Set the start and (current) end times for this trace */
-            ctx = (CtfTmfLightweightContext) seekEvent(0L);
+            ctx = (CtfTmfContext) seekEvent(0L);
             CtfTmfEvent event = getNext(ctx);
-            if((ctx.getLocation().equals(CtfIterator.NULL_LOCATION)) || (ctx.getCurrentEvent() == null)) {
+            if ((ctx.getLocation().equals(CtfIterator.NULL_LOCATION)) || (ctx.getCurrentEvent() == null)) {
                 /* Handle the case where the trace is empty */
                 this.setStartTime(TmfTimestamp.BIG_BANG);
             } else {
@@ -105,55 +124,72 @@ public class CtfTmfTrace extends TmfTrace implements ITmfEventParser {
              */
             throw new TmfTraceException(e.getMessage(), e);
         }
-
-        super.initTrace(resource, path, eventType);
     }
 
-    /* (non-Javadoc)
-     * @see org.eclipse.linuxtools.tmf.core.trace.TmfTrace#dispose()
-     */
     @Override
     public synchronized void dispose() {
         CtfIteratorManager.removeTrace(this);
-        fTrace = null;
+        if (fTrace != null) {
+            fTrace.dispose();
+            fTrace = null;
+        }
         super.dispose();
     }
 
     /**
-     * Method validate.
-     * @param project IProject
-     * @param path String
-     * @return boolean
-     * @see org.eclipse.linuxtools.tmf.core.trace.ITmfTrace#validate(IProject, String)
+     * {@inheritDoc}
+     * <p>
+     * The default implementation sets the confidence to 10 if the trace is a
+     * valid CTF trace.
      */
     @Override
-    public boolean validate(final IProject project, final String path) {
+    public IStatus validate(final IProject project, final String path) {
+        IStatus validTrace = new TraceValidationStatus(CONFIDENCE, Activator.PLUGIN_ID);
         try {
             final CTFTrace temp = new CTFTrace(path);
-            return temp.majortIsSet(); // random test
+            if (!temp.majorIsSet()) {
+                validTrace = new Status(IStatus.ERROR, Activator.PLUGIN_ID, Messages.CtfTmfTrace_MajorNotSet);
+            } else {
+                CTFTraceReader ctfTraceReader = new CTFTraceReader(temp);
+                if (!ctfTraceReader.hasMoreEvents()) {
+                    // TODO: This will need an additional check when we support live traces
+                    // because having no event is valid for a live trace
+                    validTrace = new Status(IStatus.ERROR, Activator.PLUGIN_ID, Messages.CtfTmfTrace_NoEvent);
+                }
+                ctfTraceReader.dispose();
+            }
+            temp.dispose();
         } catch (final CTFReaderException e) {
-            /* Nope, not a CTF trace we can read */
-            return false;
+            validTrace = new Status(IStatus.ERROR, Activator.PLUGIN_ID, Messages.CtfTmfTrace_ReadingError +": " + e.toString()); //$NON-NLS-1$
+        } catch (final BufferOverflowException e){
+            validTrace = new Status(IStatus.ERROR, Activator.PLUGIN_ID, Messages.CtfTmfTrace_ReadingError +": " + Messages.CtfTmfTrace_BufferOverflowErrorMessage); //$NON-NLS-1$
         }
+
+        return validTrace;
     }
 
     /**
      * Method getCurrentLocation. This is not applicable in CTF
+     *
      * @return null, since the trace has no knowledge of the current location
      * @see org.eclipse.linuxtools.tmf.core.trace.ITmfTrace#getCurrentLocation()
+     * @since 3.0
      */
     @Override
     public ITmfLocation getCurrentLocation() {
         return null;
     }
 
+    /**
+     * @since 3.0
+     */
     @Override
     public double getLocationRatio(ITmfLocation location) {
         final CtfLocation curLocation = (CtfLocation) location;
-        final CtfTmfLightweightContext context = new CtfTmfLightweightContext(this);
+        final CtfTmfContext context = new CtfTmfContext(this);
         context.setLocation(curLocation);
         context.seek(curLocation.getLocationInfo());
-        final CtfLocationData currentTime = ((CtfLocationData)context.getLocation().getLocationInfo());
+        final CtfLocationInfo currentTime = ((CtfLocationInfo) context.getLocation().getLocationInfo());
         final long startTime = getIterator(this, context).getStartTime();
         final long endTime = getIterator(this, context).getEndTime();
         return ((double) currentTime.getTimestamp() - startTime)
@@ -162,13 +198,16 @@ public class CtfTmfTrace extends TmfTrace implements ITmfEventParser {
 
     /**
      * Method seekEvent.
-     * @param location ITmfLocation<?>
+     *
+     * @param location
+     *            ITmfLocation<?>
      * @return ITmfContext
+     * @since 3.0
      */
     @Override
     public synchronized ITmfContext seekEvent(final ITmfLocation location) {
         CtfLocation currentLocation = (CtfLocation) location;
-        CtfTmfLightweightContext context = new CtfTmfLightweightContext(this);
+        CtfTmfContext context = new CtfTmfContext(this);
         if (fTrace == null) {
             context.setLocation(null);
             context.setRank(ITmfContext.UNKNOWN_RANK);
@@ -180,7 +219,7 @@ public class CtfTmfTrace extends TmfTrace implements ITmfEventParser {
          * by rank for now.
          */
         if (currentLocation == null) {
-            currentLocation = new CtfLocation(new CtfLocationData(0L, 0L));
+            currentLocation = new CtfLocation(new CtfLocationInfo(0L, 0L));
             context.setRank(0);
         }
         if (currentLocation.getLocationInfo() == CtfLocation.INVALID_LOCATION) {
@@ -193,16 +232,15 @@ public class CtfTmfTrace extends TmfTrace implements ITmfEventParser {
                 currentLocation = new CtfLocation(event.getTimestamp().getValue(), 0);
             }
         }
-        if(context.getRank() != 0) {
+        if (context.getRank() != 0) {
             context.setRank(ITmfContext.UNKNOWN_RANK);
         }
         return context;
     }
 
-
     @Override
     public synchronized ITmfContext seekEvent(double ratio) {
-        CtfTmfLightweightContext context = new CtfTmfLightweightContext(this);
+        CtfTmfContext context = new CtfTmfContext(this);
         if (fTrace == null) {
             context.setLocation(null);
             context.setRank(ITmfContext.UNKNOWN_RANK);
@@ -219,7 +257,9 @@ public class CtfTmfTrace extends TmfTrace implements ITmfEventParser {
 
     /**
      * Method readNextEvent.
-     * @param context ITmfContext
+     *
+     * @param context
+     *            ITmfContext
      * @return CtfTmfEvent
      * @see org.eclipse.linuxtools.tmf.core.trace.ITmfTrace#getNext(ITmfContext)
      */
@@ -229,11 +269,11 @@ public class CtfTmfTrace extends TmfTrace implements ITmfEventParser {
             return null;
         }
         CtfTmfEvent event = null;
-        if (context instanceof CtfTmfLightweightContext) {
+        if (context instanceof CtfTmfContext) {
             if (context.getLocation() == null || CtfLocation.INVALID_LOCATION.equals(context.getLocation().getLocationInfo())) {
                 return null;
             }
-            CtfTmfLightweightContext ctfContext = (CtfTmfLightweightContext) context;
+            CtfTmfContext ctfContext = (CtfTmfContext) context;
             event = ctfContext.getCurrentEvent();
 
             if (event != null) {
@@ -247,80 +287,128 @@ public class CtfTmfTrace extends TmfTrace implements ITmfEventParser {
     }
 
     /**
-     * @since 2.0
+     * gets the CTFtrace that this is wrapping
+     *
+     * @return the CTF trace
+     */
+    public CTFTrace getCTFTrace() {
+        return fTrace;
+    }
+
+    /**
+     * Ctf traces have a clock with a unique uuid that will be used to identify
+     * the host. Traces with the same clock uuid will be known to have been made
+     * on the same machine.
+     *
+     * Note: uuid is an optional field, it may not be there for a clock.
      */
     @Override
-    public ITmfStateSystem getStateSystem() {
-        return this.ss;
+    public String getHostId() {
+        CTFClock clock = getCTFTrace().getClock();
+        if (clock != null) {
+            String clockHost = (String) clock.getProperty(CLOCK_HOST_PROPERTY);
+            if (clockHost != null) {
+                return clockHost;
+            }
+        }
+        return super.getHostId();
     }
 
+    // -------------------------------------------
+    // ITmfTraceProperties
+    // -------------------------------------------
+
     /**
-     * gets the CTFtrace that this is wrapping
-     * @return the CTF trace
+     * @since 2.0
      */
-    public CTFTrace getCTFTrace() {
-        return fTrace;
+    @Override
+    public Map<String, String> getTraceProperties() {
+        return fTrace.getEnvironment();
     }
 
+    // -------------------------------------------
+    // Clocks
+    // -------------------------------------------
 
-    //-------------------------------------------
-    //        Environment Parameters
-    //-------------------------------------------
     /**
-     * Method getNbEnvVars.
+     * gets the clock offset
      *
-     * @return int
+     * @return the clock offset in ns
      */
-    public int getNbEnvVars() {
-        return this.fTrace.getEnvironment().size();
+    public long getOffset() {
+        if (fTrace != null) {
+            return fTrace.getOffset();
+        }
+        return 0;
     }
 
     /**
-     * Method getEnvNames.
+     * Returns whether or not an event is in the metadata of the trace,
+     * therefore if it can possibly be in the trace. It does not verify whether
+     * or not the event is actually in the trace
      *
-     * @return String[]
+     * @param eventName
+     *            The name of the event to check
+     * @return Whether the event is in the metadata or not
+     * @since 2.1
      */
-    public String[] getEnvNames() {
-        final String[] s = new String[getNbEnvVars()];
-        return this.fTrace.getEnvironment().keySet().toArray(s);
+    public boolean hasEvent(final String eventName) {
+        Map<Long, IEventDeclaration> events = fTrace.getEvents(0L);
+        if (events != null) {
+            for (IEventDeclaration decl : events.values()) {
+                if (decl.getName().equals(eventName)) {
+                    return true;
+                }
+            }
+        }
+        return false;
     }
 
     /**
-     * Method getEnvValue.
+     * Return whether all requested events are in the metadata
      *
-     * @param key
-     *            String
-     * @return String
+     * @param names
+     *            The array of events to check for
+     * @return Whether all events are in the metadata
+     * @since 2.1
      */
-    public String getEnvValue(final String key) {
-        return this.fTrace.getEnvironment().get(key);
+    public boolean hasAllEvents(String[] names) {
+        for (String name : names) {
+            if (!hasEvent(name)) {
+                return false;
+            }
+        }
+        return true;
     }
 
-    //-------------------------------------------
-    //        Clocks
-    //-------------------------------------------
-
     /**
-     * gets the clock offset
-     * @return the clock offset in ns
+     * Returns whether the metadata contains at least one of the requested
+     * events
+     *
+     * @param names
+     *            The array of event names of check for
+     * @return Whether one of the event is present in trace metadata
+     * @since 2.1
      */
-    public long getOffset(){
-        if( fTrace != null ) {
-            return fTrace.getOffset();
+    public boolean hasAtLeastOneOfEvents(String[] names) {
+        for (String name : names) {
+            if (hasEvent(name)) {
+                return true;
+            }
         }
-        return 0;
+        return false;
     }
 
-    //-------------------------------------------
-    //        Parser
-    //-------------------------------------------
+    // -------------------------------------------
+    // Parser
+    // -------------------------------------------
 
     @Override
     public CtfTmfEvent parseEvent(ITmfContext context) {
         CtfTmfEvent event = null;
-        if( context instanceof CtfTmfLightweightContext ){
-            CtfTmfLightweightContext itt = (CtfTmfLightweightContext) context.clone();
-            event = itt.getCurrentEvent();
+        if (context instanceof CtfTmfContext) {
+            final ITmfContext tmpContext = seekEvent(context.getLocation());
+            event = getNext(tmpContext);
         }
         return event;
     }
@@ -332,11 +420,69 @@ public class CtfTmfTrace extends TmfTrace implements ITmfEventParser {
         setCacheSize(DEFAULT_CACHE_SIZE);
     }
 
-    //-------------------------------------------
-    //          Helpers
-    //-------------------------------------------
+    // -------------------------------------------
+    // Helpers
+    // -------------------------------------------
 
-    private static CtfIterator getIterator(CtfTmfTrace trace,  CtfTmfLightweightContext context) {
+    private static CtfIterator getIterator(CtfTmfTrace trace, CtfTmfContext context) {
         return CtfIteratorManager.getIterator(trace, context);
     }
+
+    /**
+     * Get an iterator to the trace
+     *
+     * @return an iterator to the trace
+     * @since 2.0
+     */
+    public CtfIterator createIterator() {
+        try {
+            return new CtfIterator(this);
+        } catch (CTFReaderException e) {
+            Activator.logError(e.getMessage(), e);
+        }
+        return null;
+    }
+
+    // ------------------------------------------------------------------------
+    // Timestamp transformation functions
+    // ------------------------------------------------------------------------
+
+    /**
+     * @since 3.0
+     */
+    @Override
+    public CtfTmfTimestamp createTimestamp(long ts) {
+        return new CtfTmfTimestamp(getTimestampTransform().transform(ts));
+    }
+
+    private static int fCheckpointSize = -1;
+
+    /**
+     * @since 3.0
+     */
+    @Override
+    public synchronized int getCheckpointSize() {
+        if (fCheckpointSize == -1) {
+            TmfCheckpoint c = new TmfCheckpoint(new CtfTmfTimestamp(0), new CtfLocation(0, 0), 0);
+            ByteBuffer b = ByteBuffer.allocate(ITmfCheckpoint.MAX_SERIALIZE_SIZE);
+            b.clear();
+            c.serialize(b);
+            fCheckpointSize = b.position();
+        }
+
+        return fCheckpointSize;
+    }
+
+    @Override
+    protected ITmfTraceIndexer createIndexer(int interval) {
+        return new TmfBTreeTraceIndexer(this, interval);
+    }
+
+    /**
+     * @since 3.0
+     */
+    @Override
+    public ITmfLocation restoreLocation(ByteBuffer bufferIn) {
+        return new CtfLocation(bufferIn);
+    }
 }
This page took 0.033955 seconds and 5 git commands to generate.