temporary re-factoring project
authorAlvaro Sanchez-Leon <alvsan09@gmail.com>
Thu, 11 Feb 2010 16:48:17 +0000 (16:48 +0000)
committerAlvaro Sanchez-Leon <alvsan09@gmail.com>
Thu, 11 Feb 2010 16:48:17 +0000 (16:48 +0000)
37 files changed:
org.eclipse.linuxtools.lttng/META-INF/MANIFEST.MF
org.eclipse.linuxtools.lttng/plugin.properties
org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/LTTngCorePlugin.java
org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/TraceDebug.java
org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/event/LttngEvent.java
org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/event/LttngEventContent.java
org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/jni/JniEvent.java [new file with mode: 0644]
org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/jni/JniException.java [new file with mode: 0644]
org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/jni/JniMarker.java [new file with mode: 0644]
org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/jni/JniMarkerField.java [new file with mode: 0644]
org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/jni/JniParser.java [new file with mode: 0644]
org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/jni/JniTime.java [new file with mode: 0644]
org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/jni/JniTrace.java [new file with mode: 0644]
org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/jni/JniTracefile.java [new file with mode: 0644]
org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/jni/Jni_C_Common.java [new file with mode: 0644]
org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/jni/Jni_C_Pointer.java [new file with mode: 0644]
org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/IStateDataRequestListener.java [new file with mode: 0644]
org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/LttngStateInputRef.java [new file with mode: 0644]
org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/RequestCompletedSignal.java [new file with mode: 0644]
org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/RequestStartedSignal.java [new file with mode: 0644]
org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/StateDataRequest.java
org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/StateManager.java [new file with mode: 0644]
org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/StateStacksHandler.java [new file with mode: 0644]
org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/evProcessor/AbsEventProcessorFactory.java [new file with mode: 0644]
org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/evProcessor/EventProcessorProxy.java
org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/evProcessor/IEventProcessing.java [new file with mode: 0644]
org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/evProcessor/state/AbsStateUpdate.java
org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/evProcessor/state/StateUpdateFactory.java [new file with mode: 0644]
org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/evProcessor/state/StateUpdateHandlers.java
org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/experiment/StateExperimentManager.java
org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/experiment/StateManagerFactory.java
org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/model/ILttngStateInputRef.java [new file with mode: 0644]
org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/model/LttngTraceState.java
org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/model/LttngTrapState.java
org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/model/StateModelFactory.java
org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/trace/LTTngTextTrace.java
org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/trace/LTTngTrace.java

index 326bd6e351ef9c13f57916e4c107ec7e166c7f42..515753605b079c4d63ee5465db69ceb5f902912e 100644 (file)
@@ -6,22 +6,16 @@ Bundle-Version: 0.2.0.qualifier
 Bundle-Activator: org.eclipse.linuxtools.lttng.LTTngCorePlugin
 Bundle-Vendor: %Bundle-Vendor
 Require-Bundle: org.eclipse.core.runtime,
- org.eclipse.linuxtools.tmf;bundle-version="0.2.0",
- org.eclipse.linuxtools.lttng.jni;bundle-version="0.2.0"
+ org.eclipse.linuxtools.tmf;bundle-version="0.2.0"
 Bundle-RequiredExecutionEnvironment: J2SE-1.5
 Bundle-ActivationPolicy: lazy
 Export-Package: org.eclipse.linuxtools.lttng,
- org.eclipse.linuxtools.lttng.control,
  org.eclipse.linuxtools.lttng.event,
- org.eclipse.linuxtools.lttng.model,
- org.eclipse.linuxtools.lttng.request,
- org.eclipse.linuxtools.lttng.signal,
+ org.eclipse.linuxtools.lttng.jni,
  org.eclipse.linuxtools.lttng.state,
  org.eclipse.linuxtools.lttng.state.evProcessor,
  org.eclipse.linuxtools.lttng.state.evProcessor.state,
  org.eclipse.linuxtools.lttng.state.experiment,
  org.eclipse.linuxtools.lttng.state.model,
- org.eclipse.linuxtools.lttng.state.resource,
- org.eclipse.linuxtools.lttng.state.trace,
  org.eclipse.linuxtools.lttng.trace
 Bundle-Localization: plugin
index 9415eb31023a14da709a499381c8507bc369d49d..da1d0fbac83c9fa01ccef6c96da87c9b99308a3e 100644 (file)
@@ -1,3 +1,3 @@
 #Properties file for org.eclipse.linuxtools.lttng
-Bundle-Vendor = Eclipse Linux Tools
+Bundle-Vendor = Eclipse
 Bundle-Name = LTTng - Linux Tracing Toolkit (Incubation)
\ No newline at end of file
index 533f53704e379c626248064a14f76a6642d2e538..779ae5e9f82c7555b29309d78040f7262d20a038 100644 (file)
@@ -67,7 +67,7 @@ public class LTTngCorePlugin extends Plugin {
        public void start(BundleContext context) throws Exception {
                super.start(context);
                plugin = this;
-               LttngFactory.init();
+               TraceDebug.init();
        }
 
        /*
index c2cd34637df0d8ceef8760e7089a94f9d10ba391..96eb50dd49614e658df48d2666181bed99dc30de 100644 (file)
@@ -95,8 +95,6 @@ public class TraceDebug {
                int earliestRequested = numOfStackLines > 0 ? stackCalledFromIdx\r
                                + numOfStackLines : stackCalledFromIdx;\r
                StringBuilder sb = new StringBuilder();\r
-               int max = Thread.currentThread().getStackTrace().length - 1;\r
-               earliestRequested = earliestRequested > max ? max : earliestRequested;\r
                for (int i = earliestRequested; i >= stackCalledFromIdx; i--) {\r
                        sb.append(trace(Thread.currentThread().getStackTrace(), i) + "\n");\r
                }\r
@@ -104,8 +102,7 @@ public class TraceDebug {
        }\r
 \r
        private static String trace(StackTraceElement e[], int level) {\r
-               if (e != null) {\r
-                       level = level >= e.length ? e.length - 1 : level;\r
+               if (e != null && e.length >= level) {\r
                        StackTraceElement s = e[level];\r
                        if (s != null) {\r
                                String simpleClassName = s.getClassName();\r
index ea4a01025b9ec40d848f600c1c22746d31358cb8..81a6f2f32ba4939a75306a97f6a09e8b728e7302 100644 (file)
@@ -3,7 +3,6 @@ package org.eclipse.linuxtools.lttng.event;
 import org.eclipse.linuxtools.lttng.jni.JniEvent;
 import org.eclipse.linuxtools.tmf.event.TmfEvent;
 import org.eclipse.linuxtools.tmf.event.TmfEventSource;
-import org.eclipse.linuxtools.tmf.trace.TmfTrace;
 
 /**
  * <b><u>LttngEvent</u></b><p>
@@ -17,10 +16,7 @@ public class LttngEvent extends TmfEvent {
     
     // Reference to the JNI JniEvent. Should only be used INTERNALLY
     private JniEvent jniEventReference = null;
-    
-    // Reference to the parent trace that own this event
-    private TmfTrace<LttngEvent> parentTrace = null;
-    
+
     /**
      * Constructor with parameters.<p>
      * 
@@ -38,12 +34,11 @@ public class LttngEvent extends TmfEvent {
      * @see org.eclipse.linuxtools.lttng.event.LttngEventReference
      * @see org.eclipse.linuxtools.org.eclipse.linuxtools.lttng.jni.JniEvent
      */
-    public LttngEvent(TmfTrace<LttngEvent> parent, LttngTimestamp timestamp, TmfEventSource source, LttngEventType type, LttngEventContent content, LttngEventReference reference, JniEvent lttEvent) { 
+    public LttngEvent(LttngTimestamp timestamp, TmfEventSource source, LttngEventType type, LttngEventContent content, LttngEventReference reference, JniEvent lttEvent) { 
         super(timestamp, source, type, reference);
         
         fContent = content;
         jniEventReference = lttEvent;
-        setParentTrace(parent);
     }
     
     /**
@@ -52,9 +47,7 @@ public class LttngEvent extends TmfEvent {
      * @param oldEvent         Event we want to copy from.
      */
     public LttngEvent(LttngEvent oldEvent) {
-        this(  
-                       oldEvent.getParentTrace(),
-                       (LttngTimestamp)oldEvent.getTimestamp(), 
+        this(  (LttngTimestamp)oldEvent.getTimestamp(), 
                        (TmfEventSource)oldEvent.getSource(), 
                        (LttngEventType)oldEvent.getType(), 
                        (LttngEventContent)oldEvent.getContent(), 
@@ -65,25 +58,6 @@ public class LttngEvent extends TmfEvent {
     
     
     /**
-     * Return the parent trace asoociated with this event
-     * 
-     * @return Parent trace
-     */
-    public TmfTrace<LttngEvent> getParentTrace() {
-               return parentTrace;
-       }
-    
-    /**
-     * Set a new parent trace for this event
-     * 
-     * @param parentTrace      The new parent
-     */
-    public void setParentTrace(TmfTrace<LttngEvent> parentTrace) {
-               this.parentTrace = parentTrace;
-       }
-    
-    
-       /**
      * Return the channel name of this event.<p>
      * 
      * @return Channel (tracefile) for this event
@@ -110,6 +84,19 @@ public class LttngEvent extends TmfEvent {
         return ( (LttngEventType)this.getType() ).getMarkerName();
     }
     
+    /**
+     * Set a new JniReference for this event.<p>
+     * 
+     * Note : Reference is used to get back to the Jni during event parsing and need to be consistent.
+     * 
+     * @param newJniEventReference     New reference
+     * 
+     * @see org.eclipse.linuxtools.org.eclipse.linuxtools.lttng.jni.JniEvent
+     */
+    public void updateJniEventReference(JniEvent newJniEventReference) {
+        this.jniEventReference = newJniEventReference;
+    }
+    
     @Override
     public LttngEventContent getContent() {
         return (LttngEventContent)fContent;
@@ -128,18 +115,6 @@ public class LttngEvent extends TmfEvent {
         fType = newType;
     }
     
-    /**
-     * Set a new JniReference for this event.<p>
-     * 
-     * Note : Reference is used to get back to the Jni during event parsing and need to be consistent.
-     * 
-     * @param newJniEventReference     New reference
-     * 
-     * @see org.eclipse.linuxtools.org.eclipse.linuxtools.lttng.jni.JniEvent
-     */
-    public synchronized void updateJniEventReference(JniEvent newJniEventReference) {
-        this.jniEventReference = newJniEventReference;
-    }
     
     /**
      * Convert this event into a Jni JniEvent.<p>
@@ -151,7 +126,7 @@ public class LttngEvent extends TmfEvent {
      * 
      * @see org.eclipse.linuxtools.org.eclipse.linuxtools.lttng.jni.JniEvent
      */
-    public synchronized JniEvent convertEventTmfToJni() {
+    public JniEvent convertEventTmfToJni() {
         JniEvent tmpEvent = null;
         
         // ***TODO***
@@ -170,13 +145,13 @@ public class LttngEvent extends TmfEvent {
     
     @Override
        public String toString() {
-       StringBuffer result= new StringBuffer("[LttngEvent(");
-       result.append("Timestamp:" + getTimestamp().getValue());
-       result.append(",Channel:"  + getChannelName());
-       result.append(",CPU:"      + getCpuId());
-       result.append(",Marker:"   + getMarkerName());
-       result.append(",Content:"  + getContent() + ")]");
+       String returnedData="";
+       
+       returnedData += "Event timestamp:" + this.getTimestamp().getValue() + " ";
+       returnedData += "Channel:" + getChannelName() + " ";
+       returnedData += "CPU:" + getCpuId() + " ";
+       returnedData += "Marker:" + getMarkerName() + " ";
        
-       return result.toString();
+       return returnedData;
     }
 }
index c8b6d454082c79711811b4c684d3766a419da3a4..92ee00dc3cdb8469ea9305b421382c1cd6861657 100644 (file)
@@ -14,9 +14,7 @@ package org.eclipse.linuxtools.lttng.event;
 
 import java.util.HashMap;
 
-import org.eclipse.linuxtools.lttng.jni.JniEvent;
 import org.eclipse.linuxtools.tmf.event.TmfEventContent;
-import org.eclipse.linuxtools.tmf.event.TmfNoSuchFieldException;
 
 /**
  * <b><u>LttngEventContent</u></b><p>
@@ -87,9 +85,11 @@ public class LttngEventContent extends TmfEventContent {
     @Override
        public LttngEventType getType() {
         return (LttngEventType)fParentEvent.getType();
+//        return (LttngEventType)fEventType;
     }
     public void setType(LttngEventType newType) {
         ((LttngEvent)fParentEvent).setType(newType);
+//        fEventType = newType;
     }
     
     
@@ -100,7 +100,7 @@ public class LttngEventContent extends TmfEventContent {
     }
     
     // ***VERIFY***
-    // A bit weird to return the _currently_parsed fields (unlike all fields like getFields() )
+    // A bit weird to return the _currently_parsed fields (unlike all like getFields() )
     // Should we keep this?
     /**
      * Return currently parsed fields in an object array format.<p>
@@ -154,30 +154,17 @@ public class LttngEventContent extends TmfEventContent {
      * @see @see org.eclipse.linuxtools.lttng.event.LttngEventField
      */
     @Override
-    public synchronized LttngEventField[] getFields() {
-        if ( fFieldsMap.size() < fParentEvent.getType().getNbFields() ) {
-               LttngEventField tmpField = null;
-               LttngEventType tmpType = (LttngEventType)fParentEvent.getType();
-               
-               for ( int pos=0; pos<tmpType.getNbFields(); pos++ ) {
-                   String name = null;
-                               JniEvent tmpEvent = ((LttngEvent)getEvent()).convertEventTmfToJni();
-                               
-                               // tmpEvent == null probably mean there is a discrepancy between Eclipse and C library
-                               // An error was probably printed in convertEventTmfToJni() already, but keep in mind this is SERIOUS
-                               if ( tmpEvent != null ) {
-                                       try {
-                                               name = tmpType.getLabel(pos);
-                                       
-                                               Object newValue = tmpEvent.parseFieldByName(name);
-                                               tmpField = new LttngEventField(this, name, newValue );
-                                               fFieldsMap.put(name, tmpField);
-                                       }
-                                       catch (TmfNoSuchFieldException e) {
-                                               System.out.println("Invalid field position requested : " + pos + ", ignoring (getFields).");
-                                       }
-                   }
-               }
+    public LttngEventField[] getFields() {
+        LttngEventField tmpField = null;
+        
+        LttngEventType tmpType = (LttngEventType)fParentEvent.getType();
+        
+        for ( int pos=0; pos<tmpType.getNbFields(); pos++ ) {
+            String name = tmpType.getLabel(pos);
+            Object newValue = ((LttngEvent)getEvent()).convertEventTmfToJni().parseFieldByName(name);
+            
+            tmpField = new LttngEventField(this, name, newValue );
+            fFieldsMap.put(name, tmpField);
         }
         return fFieldsMap.values().toArray(new LttngEventField[fFieldsMap.size()]);
     }
@@ -192,15 +179,11 @@ public class LttngEventContent extends TmfEventContent {
     @Override
     public LttngEventField getField(int position) {
         LttngEventField returnedField = null;
-        String label = null;
-               try {
-                       label = fParentEvent.getType().getLabel(position);
-                       
-                       returnedField = this.getField(label);
-               } 
-               catch (TmfNoSuchFieldException e) {
-                       System.out.println("Invalid field position requested : " + position + ", ignoring (getField).");
-               }
+        String label = fParentEvent.getType().getLabel(position);
+        
+        if ( label != null ) {
+            returnedField = this.getField(label);
+        }
         
         return returnedField;
     }
@@ -213,8 +196,8 @@ public class LttngEventContent extends TmfEventContent {
      * @see @see org.eclipse.linuxtools.lttng.event.LttngEventField
      */
     @Override
-    public synchronized LttngEventField getField(String name) {
-       // *** VERIFY ***
+    public LttngEventField getField(String name) {
+        // *** VERIFY ***
         // Should we check if the field exists in LttngType before parsing? 
         // It could avoid calling parse for non-existent fields but would waste some cpu cycle on check?
         LttngEventField returnedField = fFieldsMap.get(name);
@@ -222,16 +205,12 @@ public class LttngEventContent extends TmfEventContent {
         if ( returnedField == null ) {
             // *** VERIFY ***
             // Should we really make sure we didn't get null before creating/inserting a field?
-               JniEvent tmpEvent = ((LttngEvent)getEvent()).convertEventTmfToJni();
-               
-               if ( tmpEvent != null) {
-                       Object newValue =  tmpEvent.parseFieldByName(name);
-                   
-                   if ( newValue!= null ) {
-                       returnedField = new LttngEventField(this, name, newValue);
-                       fFieldsMap.put(name, returnedField );
-                   }
-               }
+               Object newValue = ((LttngEvent)getEvent()).convertEventTmfToJni().parseFieldByName(name);
+            
+            if ( newValue!= null ) {
+                returnedField = new LttngEventField(this, name, newValue);
+                fFieldsMap.put(name, returnedField );
+            }
         }
         
         return returnedField;
@@ -251,15 +230,15 @@ public class LttngEventContent extends TmfEventContent {
      */
     @Override
     public String toString() {
+        String returnedString = "";
+        
         LttngEventField[] allFields = getFields();
         
-        StringBuffer strBuffer = new StringBuffer();
         for ( int pos=0; pos < allFields.length; pos++) {
-               if (pos != 0) strBuffer.append(",");
-               strBuffer.append(allFields[pos].toString());
+            returnedString +=  allFields[pos].toString() + " ";
         }
         
-        return strBuffer.toString();
+        return returnedString;
         
     }
 }
\ No newline at end of file
diff --git a/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/jni/JniEvent.java b/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/jni/JniEvent.java
new file mode 100644 (file)
index 0000000..c9acabe
--- /dev/null
@@ -0,0 +1,478 @@
+package org.eclipse.linuxtools.lttng.jni;
+/*******************************************************************************
+ * Copyright (c) 2009 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:
+ *   William Bourque (wbourque@gmail.com) - Initial API and implementation
+ *******************************************************************************/
+
+
+import java.util.HashMap;
+
+/**
+ * <b><u>JniEvent</u></b> <p>
+ * 
+ * A JniEvent has the actual content that got traced by Lttng.<br>
+ * Provides access to the LttEvent C structure in java. <p>
+ * 
+ * Most important fields in the JniEvent are :
+ * <ul>
+ * <li>an event time, which is a digested timestamp.
+ * </ul>
+ * Note that the JniEvent content is not directly accessibe and should be obtained
+ * using the parseAllFields() or parseFieldBy...() methods.
+ */
+public final class JniEvent extends Jni_C_Common implements Comparable<JniEvent> {
+    // Variables to detect if the event have been filled at least once
+    // this make possible the detection of "uninitialized" struct in Ltt
+    // Can be "EOK", "ERANGE" or "EPERM" (defined in Jaf_C_Common)
+    private int eventState = EPERM; // Start with EPERM to ensure sanity
+
+    // Internal C pointer of the JniEvent used in LTT
+    private Jni_C_Pointer thisEventPtr = new Jni_C_Pointer();
+
+    // Reference to the parent tracefile
+    private JniTracefile parentTracefile = null;
+
+    // This map hold marker relative to the parent tracefile of this event
+    // They are "our" marker in this event
+    private HashMap<Integer, JniMarker> markersMap = null;
+
+    // Data we should populate from ltt
+    // Note that all type have been scaled up as there is no "unsigned" in java
+    // This might be a problem about "unsigned long" as there is no equivalent
+    // in java
+    private Jni_C_Pointer tracefilePtr = new Jni_C_Pointer();
+    private JniTime eventTime = null;
+
+    // These methods need a tracefile pointer, instead of a event pointer
+    private native int      ltt_readNextEvent(long tracefilePtr);
+    private native int      ltt_seekEvent(long tracefilePtr, JniTime givenTime);
+    private native int      ltt_positionToFirstEvent(long tracefilePtr);
+        
+    // Native access functions
+    private native long     ltt_getTracefilePtr(long eventPtr);
+    @SuppressWarnings("unused")
+    private native long     ltt_getBlock(long eventPtr);
+    @SuppressWarnings("unused")
+    private native long     ltt_getOffset(long eventPtr);
+    @SuppressWarnings("unused")
+    private native long     ltt_getCurrentTimestampCounter(long eventPtr);
+    @SuppressWarnings("unused")
+    private native long     ltt_getTimestamp(long eventPtr);
+    private native int      ltt_getEventMarkerId(long eventPtr);
+    private native long     ltt_getNanosencondsTime(long eventPtr);
+    @SuppressWarnings("unused")
+    private native void     ltt_feedEventTime(long eventPtr, JniTime eventTime);
+    private native long     ltt_getEventDataSize(long eventPtr);
+    @SuppressWarnings("unused")
+    private native long     ltt_getEventSize(long eventPtr);
+    @SuppressWarnings("unused")
+    private native int      ltt_getCount(long eventPtr);
+    @SuppressWarnings("unused")
+    private native long     ltt_getOverflowNanoSeconds(long eventPtr);
+        
+    // This method an event pointer
+    private native void     ltt_getDataContent(long eventPtr, long dataSize, byte[] returnedContent);
+        
+    // Debug native function, ask LTT to print event structure
+    private native void     ltt_printEvent(long eventPtr);
+
+    static {
+        System.loadLibrary("lttvtraceread");
+    }
+
+    
+    /**
+     * Default constructor is forbidden
+     */
+    @SuppressWarnings("unused")
+    private JniEvent() {
+    };
+
+    /**
+     * Copy constructor.<p>
+     * 
+     * @param oldEvent      Reference to the JniEvent you want to copy. 
+     */
+    public JniEvent(JniEvent oldEvent) {
+        thisEventPtr = oldEvent.thisEventPtr;
+        markersMap = oldEvent.markersMap;
+        parentTracefile = oldEvent.parentTracefile;
+        eventState = oldEvent.eventState;
+
+        tracefilePtr = oldEvent.tracefilePtr;
+        eventTime = oldEvent.eventTime;
+    }
+    
+    /**
+     * Constructor with parameters<p>
+     * 
+     * This constructor could throw. It will happen if an event can not be populated on <u>first read</u>.<br>
+     * In that case, the parent tracefile is probably useless and should be deleted.
+     * 
+     * @param newEventPtr         C pointer (converted in long) of the LttEvent C structure.
+     * @param newMarkersMap       Reference an already populated HashMap of JniMarker objects 
+     * @param newParentTracefile  Reference to the parent JniTracefile of this JniEvent
+     *            
+     * @exception JniException
+     * 
+     * @see org.eclipse.linuxtools.lttng.jni.eclipse.linuxtools.lttng.jni.Jni_C_Pointer
+     * @see org.eclipse.linuxtools.lttng.jni.eclipse.linuxtools.lttng.jni.JniMarker
+     * @see org.eclipse.linuxtools.lttng.jni.eclipse.linuxtools.lttng.jni.JniTracefile
+     */
+    public JniEvent(Jni_C_Pointer newEventPtr, HashMap<Integer, JniMarker> newMarkersMap, JniTracefile newParentTracefile) throws JniException {
+
+        // Basic test to make sure we didn't get null/empty value 
+        if ((newEventPtr.getPointer() == NULL)
+                || (newMarkersMap == null) 
+                || (newMarkersMap.size() == 0)
+                || (newParentTracefile == null)) {
+            throw new JniEventException("Null or empty value passed to constructor, object is invalid! (JniEvent)");
+        }
+        
+        thisEventPtr = newEventPtr;
+        tracefilePtr = newParentTracefile.getTracefilePtr();
+        markersMap = newMarkersMap;
+        parentTracefile = newParentTracefile;
+
+        eventTime = new JniTime();
+        
+        // Try to move to the first event
+        // If the event is Out of Range (ERANGE) at the first read, 
+        //  this event type will never be usable.
+        // In that case, throw JniNoSuchEventException to warn the tracefile.
+        eventState = positionToFirstEvent();
+        if (eventState != EOK)  {
+            throw new JniNoSuchEventException("Object not populated, unusable. There is probably no event of that type in the trace. (JniEvent)");
+        }
+        else {
+            populateEventInformation();
+        }
+    }
+
+    /**
+     * Move to the next event and populate the java object with LttEvent structure.<p>
+     * 
+     * If the move fails, the event will not get populated and the last event data will still be available.
+     * 
+     * @return LTT read status, as defined in Jni_C_Common.
+     * 
+     * @see org.eclipse.linuxtools.lttng.jni.eclipse.linuxtools.lttng.jni.Jni_C_Common
+     */
+     public int readNextEvent() {
+        // Ask Ltt to read the next event for this particular tracefile
+        eventState = ltt_readNextEvent( tracefilePtr.getPointer() );
+        // If the event state is sane populate it
+        if (eventState == EOK) {
+            populateEventInformation();
+        }
+        
+        return eventState;
+    }
+
+    /**
+     * Seek to a certain time.<p>
+     * 
+     * Seek to a certain time and read event at this exact time or the next one if there is no event there.<p>
+     * 
+     * Note that this function can seek in an invalid position if the timestamp is after the last event.<br>
+     * In that case, a seek back would be required to get back to a consistent state.<p>
+     * 
+     * If the seek fails, the event will not get populated and the last event data will still be available.<p>
+     * 
+     * @return LTT read status, as defined in Jni_C_Common
+     * 
+     * @see org.eclipse.linuxtools.lttng.jni.eclipse.linuxtools.lttng.jni.Jni_C_Common
+     */
+    public int seekToTime(JniTime seekTime) {
+        // Ask Ltt to read the next event for this particular tracefile
+        eventState = ltt_seekEvent(tracefilePtr.getPointer(), seekTime);
+
+        // If the event state is sane populate it
+        if (eventState == EOK) {
+            populateEventInformation();
+        }
+
+        return eventState;
+    }
+
+    /**
+     * Try to seek to a certain time and seek back if it failed.<p>
+     * 
+     * Seek to a certain time and read event at this exact time or the next one if there is no event there.<p>
+     * 
+     * If the seek fails, we will seek back to the previous position, so the event will stay in a consistent state.<p> 
+     * 
+     * @return LTT read status, as defined in Jni_C_Common
+     * 
+     * @see org.eclipse.linuxtools.lttng.jni.eclipse.linuxtools.lttng.jni.Jni_C_Common
+     */
+    public int seekOrFallBack(JniTime seekTime) {
+        // Save the old time
+        JniTime oldTime = new JniTime(eventTime);
+
+        // Call seek to move ahead
+        // Save the state for the return (eventState will be modified if we seek back)
+        int returnState = seekToTime(seekTime);
+
+        // If the event state is sane populate it
+        if (returnState == EOK) {
+            populateEventInformation();
+        }
+        else {
+            seekToTime(oldTime);
+        }
+
+        return returnState;
+    }
+
+    /**
+     * Position on the first event in the tracefile.<p>
+     * 
+     * The function return the read status after the first event.<p>
+     * 
+     * A status different of EOK probably means there is no event associated to this tracefile.
+     * 
+     * @return LTT read status, as defined in Jni_C_Common
+     * 
+     * @see org.eclipse.linuxtools.lttng.jni.eclipse.linuxtools.lttng.jni.Jni_C_Common
+     */
+    public int positionToFirstEvent() {
+        eventState = ltt_positionToFirstEvent(tracefilePtr.getPointer());
+        
+        return eventState;
+    }
+    
+    /**
+     * Obtain a marker associated with this tracefile's event.
+     * 
+     * @return Reference to the marker for this tracefile's event or null if none.
+     *  
+     * @see org.eclipse.linuxtools.lttng.jni.eclipse.linuxtools.lttng.jni.JniMarker
+     */
+    public JniMarker requestEventMarker() {
+        return markersMap.get(getEventMarkerId());
+    }
+
+    /**
+     * Obtain the raw data of a LttEvent object.<p>
+     * 
+     * The data will be in raw C bytes, not java bytes.<br>
+     * Note : This function is mostly untested and provided "as is".
+     * 
+     * @return  Bytes array of raw data (contain raw C bytes).
+     */
+    public byte[] requestEventContent() {
+        byte dataContent[] = new byte[(int) getEventDataSize()];
+
+        ltt_getDataContent(thisEventPtr.getPointer(), getEventDataSize(), dataContent);
+
+        return dataContent;
+    }
+    
+    /**
+     * Obtain an event source.<p>
+     * 
+     * This is not implemented yet and will always return "Kernel core" for now.
+     * 
+     * @return  Reference to the JniMarker object for this event or null if none. 
+     * 
+     * @see org.eclipse.linuxtools.lttng.jni.eclipse.linuxtools.lttng.jni.JniMarker
+     */
+    public String requestEventSource() {
+        // *** TODO ***
+        // No "Source" of event exists in Ltt so far
+        // It would be a good addition to have a way to detect where an event come
+        // from, like "kernel" or "userspace"
+        // 
+        return "Kernel Core";
+    }
+    
+    /**
+     * Parse a particular field in the event payload, identified by its id (position).<p>
+     * 
+     * Note : Position are relative to an event marker (i.e. requestEventMarker().getMarkerFieldsArrayList() )
+     * 
+     * @param fieldId   Position of the field to parse.
+     * 
+     * @return Object that contain the parsed payload
+     * 
+     * @see org.eclipse.linuxtools.lttng.jni.eclipse.linuxtools.lttng.jni.JniParser
+     */
+    public Object parseFieldById(int fieldId) {
+        return JniParser.parseField(this, fieldId);
+    }
+    
+    /**
+     * Parse a particular field in the event payload, identified by its name.<p>
+     * 
+     * Note : Name are relative to an event marker (i.e. requestEventMarker().getMarkerFieldsHashMap() )
+     * 
+     * @param fieldName   Position of the field to parse.
+     * 
+     * @return Object that contain the parsed payload
+     * 
+     * @see org.eclipse.linuxtools.lttng.jni.eclipse.linuxtools.lttng.jni.JniParser
+     */
+    public Object parseFieldByName(String fieldName) {
+        return JniParser.parseField(this, fieldName);
+    }
+    
+    /**
+     * Method to parse all the event payload.<p>
+     * 
+     * @return HashMap<String, Object> which is the parsedContent objects and their name as key.
+     * 
+     * @see org.eclipse.linuxtools.lttng.jni.eclipse.linuxtools.lttng.jni.JniParser 
+     */
+    public HashMap<String, Object> parseAllFields() {
+        return JniParser.parseAllFields(this);
+    }
+
+    /* 
+     * This function populates the event data with data from LTT
+     * 
+     * NOTE : To get better performance, we copy very few data into memory here
+     * 
+     */
+    private void populateEventInformation() {
+       // We need to save the time, as it is not a primitive (can't be dynamically called in getter)
+       eventTime.setTime(ltt_getNanosencondsTime(thisEventPtr.getPointer() ));
+    }
+    
+    public JniTime getEventTime() {
+        return eventTime;
+    }
+    
+    // *** To get better performance, all getter belows call LTT directly ****
+    //     That way, we can avoid copying data into memory
+    public int getEventMarkerId() {
+        return ltt_getEventMarkerId(thisEventPtr.getPointer());
+    }
+
+    public long getEventDataSize() {
+        return ltt_getEventDataSize(thisEventPtr.getPointer());
+    }
+
+    public HashMap<Integer, JniMarker> getMarkersMap() {
+        return markersMap;
+    }
+
+    /**
+     * Pointer to the parent LTTTracefile C structure.<br>
+     * <br>
+     * The pointer should only be used <u>INTERNALY</u>, do not use unless you
+     * know what you are doing.
+     * 
+     * @return The actual (long converted) pointer or NULL.
+     * 
+     * @see org.eclipse.linuxtools.lttng.jni.eclipse.linuxtools.lttng.jni.Jni_C_Pointer
+     */
+    public Jni_C_Pointer getTracefilePtr() {
+        return new Jni_C_Pointer( ltt_getTracefilePtr(thisEventPtr.getPointer()) );
+    }
+
+    /**
+     * Pointer to the LttEvent C structure.<br>
+     * <br>
+     * The pointer should only be used <u>INTERNALY</u>, do not use unless you
+     * know what you are doing.
+     * 
+     * @return The actual (long converted) pointer or NULL.
+     * 
+     * @see org.eclipse.linuxtools.lttng.jni.eclipse.linuxtools.lttng.jni.Jni_C_Pointer
+     */
+    public Jni_C_Pointer getEventPtr() {
+        return thisEventPtr;
+    }
+
+    public int getEventState() {
+        return eventState;
+    }
+
+    /**
+     * Getter to the parent tracefile for this event.
+     *
+     * @return  The parent tracefile 
+     * 
+     * @see org.eclipse.linuxtools.lttng.jni.eclipse.linuxtools.lttng.jni.JniTracefile
+     */
+    public JniTracefile getParentTracefile() {
+        return parentTracefile;
+    }
+    
+    /**
+     * Compare fonction for JNIEvent.<p>
+     * <p>
+     * This will compare the current JNIEvent with a passed one by timestamp AND tracefile ("type").<br>
+     * If both are equal but type differs, current event is considered to be older (-1 returned).
+     * 
+     * @return -1 if given event happens before, 0 if equal, 1 if passed event happens after.
+     */
+    public int compareTo(JniEvent rightEvent ){
+       
+       // Note : this = left hand operand
+       
+        // By default, we consider the current event to be older.
+        int eventComparaison = -1; 
+        
+        // Test against null before performing anything
+        if ( rightEvent != null ) {
+            // Compare the timestamp first
+            eventComparaison = this.getEventTime().compareTo( rightEvent.getEventTime() );
+            
+            // If timestamp is equal, compare the parent tracefile ("event type")
+            if ( (eventComparaison == 0) && ( !this.parentTracefile.equals(rightEvent.parentTracefile)) ) {
+                eventComparaison = 1;
+            }
+        }
+        return eventComparaison;
+    }
+    
+    /**
+     * Print information for this event. 
+     * <u>Intended to debug</u><br>
+     * 
+     * This function will call Ltt to print, so information printed will be 
+     * the one from the C structure, not the one populated in java.<p>
+     * 
+     * This function will not throw but will complain loudly if pointer is NULL.
+     */
+    public void printEventInformation() {
+
+        // If null pointer, print a warning!
+        if (thisEventPtr.getPointer() == NULL) {
+            printlnC("Pointer is NULL, cannot print. (printEventInformation)");
+        }
+        else {
+            ltt_printEvent(thisEventPtr.getPointer());
+        }
+    }
+    
+    /**
+     * toString() method. 
+     * <u>Intended to debug.</u><p>
+     * 
+     * @return Attributes of the object concatenated in String
+     */
+    @Override
+       public String toString() {
+        String returnData = "";
+
+        returnData += "tracefilePtr            : " + tracefilePtr + "\n";
+        returnData += "eventMarkerId           : " + getEventMarkerId() + "\n";
+        returnData += "eventTime               : " + eventTime.getReferenceToString() + "\n";
+        returnData += "   seconds              : " + eventTime.getSeconds() + "\n";
+        returnData += "   nanoSeconds          : " + eventTime.getNanoSeconds() + "\n";
+        returnData += "eventDataSize           : " + getEventDataSize() + "\n";
+        returnData += "markersMap              : " + markersMap.keySet() + "\n"; // Hack to avoid ending up with markersMap.toString()
+
+        return returnData;
+    }
+}
diff --git a/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/jni/JniException.java b/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/jni/JniException.java
new file mode 100644 (file)
index 0000000..7f8adf6
--- /dev/null
@@ -0,0 +1,169 @@
+package org.eclipse.linuxtools.lttng.jni;
+/*******************************************************************************
+ * Copyright (c) 2009 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:
+ *   William Bourque (wbourque@gmail.com) - Initial API and implementation
+ *******************************************************************************/
+
+
+/**
+ * <b><u>JniException</u></b>
+ * <p>
+ * Super class for JNI exception.
+ */
+public class JniException extends Exception {
+    private static final long serialVersionUID = -6620784221853154537L;
+
+    JniException(String errMsg) {
+        super(errMsg);
+    }
+}
+
+/**
+ * <b><u>JniTraceException</u></b>
+ * <p>
+ * Basic exception class for the JniTrace class
+ */
+class JniTraceException extends JniException {
+    private static final long serialVersionUID = -6873007333085268143L;
+
+    JniTraceException(String errMsg) {
+        super(errMsg);
+    }
+}
+
+/**
+ * <b><u>JniOpenTraceFailedException</u></b>
+ * <p>
+ * Sub-exception class type for JniTraceException
+ * This type will get thrown when a trace fail to open
+ * Most likely to be caused by a bad tracepath
+ */
+class JniOpenTraceFailedException extends JniTraceException {
+    private static final long serialVersionUID = 877769692366394895L;
+
+    JniOpenTraceFailedException(String errMsg) {
+        super(errMsg);
+    }
+}
+
+/**
+ * <b><u>JniNoNextEventInTraceException</u></b>
+ * <p>
+ * Sub-exception class type for JniTraceException
+ * This type will get thrown when we can't find any "next" event
+ * This should usually mean there is no more event in the trace
+
+ */
+class JniNoNextEventInTraceException extends JniTraceException {
+    private static final long serialVersionUID = -2887528566100063849L;
+
+    JniNoNextEventInTraceException(String errMsg) {
+        super(errMsg);
+    }
+}
+
+// 
+/**
+ * <b><u>JniTracefileException</u></b>
+ * <p>
+ * Basic exception class for the JniTracefile class
+ */
+class JniTracefileException extends JniException {
+    private static final long serialVersionUID = 5081317864491800084L;
+
+    JniTracefileException(String errMsg) {
+        super(errMsg);
+    }
+}
+
+/**
+ * <b><u>JniTracefileWithoutEventException</u></b>
+ * <p>
+ * Sub-exception class type for JniTracefileException
+ * This type will get thrown when a trace file contain no readable events
+ * The proper course of action would usually be to ignore this useless trace file
+ */
+class JniTracefileWithoutEventException extends JniTracefileException {
+    private static final long serialVersionUID = -8183967479236071261L;
+
+    JniTracefileWithoutEventException(String errMsg) {
+        super(errMsg);
+    }
+}
+
+/**
+ * <b><u>JniEventException</u></b>
+ * <p>
+ * Basic exception class for the JniEvent class
+ */
+class JniEventException extends JniException {
+    private static final long serialVersionUID = -5891749130387304519L;
+
+    JniEventException(String errMsg) {
+        super(errMsg);
+    }
+}
+
+/**
+ * <b><u>JniNoSuchEventException</u></b>
+ * <p>
+ * Sub-exception type for the JniEventException type
+ * This exception type will get thrown when an event is unavailable
+ * This might happen at construction because some events type are not present in
+ * the trace
+ */
+class JniNoSuchEventException extends JniEventException {
+    private static final long serialVersionUID = -4379712949891538051L;
+
+    JniNoSuchEventException(String errMsg) {
+        super(errMsg);
+    }
+}
+
+/**
+ * <b><u>JniEventOutOfRangeException</u></b>
+ * <p>
+ * Sub-exception type for the JniEventException type
+ * This exception type will get thrown when there is no more event of this type
+ * available
+ */
+class JniEventOutOfRangeException extends JniEventException {
+    private static final long serialVersionUID = -4645877232795324541L;
+
+    JniEventOutOfRangeException(String errMsg) {
+        super(errMsg);
+    }
+}
+
+/**
+ * <b><u>JniMarkerException</u></b>
+ * <p>
+ * Basic Exception class for the JniMarker class
+ */
+class JniMarkerException extends JniException {
+    private static final long serialVersionUID = -4694173610721983794L;
+
+    JniMarkerException(String errMsg) {
+        super(errMsg);
+    }
+}
+
+/**
+ * <b><u>JniMarkerFieldException</u></b>
+ * <p>
+ * Basic Exception class for the JniMarkerField class
+ */
+class JniMarkerFieldException extends JniException {
+    private static final long serialVersionUID = 6066381741374806879L;
+
+    JniMarkerFieldException(String errMsg) {
+        super(errMsg);
+    }
+}
diff --git a/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/jni/JniMarker.java b/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/jni/JniMarker.java
new file mode 100644 (file)
index 0000000..3990bfc
--- /dev/null
@@ -0,0 +1,235 @@
+package org.eclipse.linuxtools.lttng.jni;
+/*******************************************************************************
+ * Copyright (c) 2009 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:
+ *   William Bourque (wbourque@gmail.com) - Initial API and implementation
+ *******************************************************************************/
+
+
+import java.util.ArrayList;
+import java.util.HashMap;
+
+/**
+ * <b><u>JniMarker</u></b><p>
+ * 
+ * A JniMarker contain information how to interpret the unparsed content (payload) of an event.<br>
+ * Each JniMarker contains several MarkerFields for each fields in the event's payload.
+ * 
+ * Provides access to the marker_info C structure (from LTT) in java. 
+ * 
+ * Most important fields in the JniMarker are :
+ * <ul>
+ * <li> the name of the marker in String
+ * <li> an overview of the marker format (in C style printf format)
+ * <li> a reference to an ArrayList that contains MarkerFields object of this JniMarker
+ * </ul>
+ */
+public final class JniMarker extends Jni_C_Common
+{
+    // Internal C pointer of the JniEvent used in LTT
+    private Jni_C_Pointer thisMarkerPtr = new Jni_C_Pointer();
+
+    private String name = "";
+    private String formatOverview = "";
+    
+    // These two contains hold references to the same MarkerField object
+    //  The ArrayList can be used to efficiently find a field by its position
+    //  The HashMap can be used to find a field by its name
+    private HashMap<String, JniMarkerField> markerFieldsHashMap = null;
+    private ArrayList<JniMarkerField> markerFieldsArrayList = null;
+
+    // Native access method
+    private native String ltt_getName(long markerPtr);   
+    private native String ltt_getFormatOverview(long markerPtr);
+    @SuppressWarnings("unused")
+    private native long ltt_getSize(long markerPtr);
+    @SuppressWarnings("unused")
+    private native short ltt_getLargestAlign(long markerPtr);
+    @SuppressWarnings("unused")
+    private native short ltt_getIntSize(long markerPtr);
+    @SuppressWarnings("unused")
+    private native short ltt_getLongSize(long markerPtr);
+    @SuppressWarnings("unused")
+    private native short ltt_getPointerSize(long markerPtr);
+    @SuppressWarnings("unused")
+    private native short ltt_getSize_tSize(long markerPtr);
+    private native void ltt_getAllMarkerFields(long tracePtr);
+    @SuppressWarnings("unused")
+    private native short ltt_getAlignement(long markerPtr);
+    @SuppressWarnings("unused")
+    private native long ltt_getNextMarkerPtr(long markerPtr);
+
+    // Debug native function, ask LTT to print marker structure
+    private native void ltt_printMarker(long markerPtr);
+
+    static {
+        System.loadLibrary("lttvtraceread");
+    }
+
+    /*
+     * Default constructor is forbidden
+     */
+    @SuppressWarnings("unused")
+    private JniMarker() {
+    }
+    
+    /**
+     * Copy constructor.<p>
+     * 
+     * @param oldMarker Reference to the JniMarker you want to copy. 
+     */
+    public JniMarker(JniMarker oldMarker) {
+        thisMarkerPtr = oldMarker.thisMarkerPtr;
+        name = oldMarker.name;
+        formatOverview = oldMarker.formatOverview;
+        markerFieldsHashMap = oldMarker.markerFieldsHashMap;
+        markerFieldsArrayList = oldMarker.markerFieldsArrayList;
+
+    }
+
+    /**
+     * Constructor, using pointer.<p>
+     * 
+     * @param newMarkerPtr  Pointer to a C marker_info structure
+     * 
+     * @exception JniException
+     */
+    public JniMarker(Jni_C_Pointer newMarkerPtr) throws JniException {
+        thisMarkerPtr = newMarkerPtr;
+        markerFieldsArrayList = new ArrayList<JniMarkerField>();
+        markerFieldsHashMap = new HashMap<String, JniMarkerField>();
+
+        // Populate the marker
+        populateMarkerInformation();
+    }
+
+    
+    /* 
+     * This function populates the marker data with data from LTT
+     * 
+     */
+    private void populateMarkerInformation() throws JniException {
+        if (thisMarkerPtr.getPointer() == NULL) {
+            throw new JniMarkerException("Pointer is NULL, trace closed? (populateMarkerInformatOverviewion)");
+        } else {
+            name = ltt_getName( thisMarkerPtr.getPointer() );
+            formatOverview = ltt_getFormatOverview( thisMarkerPtr.getPointer() );
+            // To fill the markerFieldArray is a bit different
+            ltt_getAllMarkerFields( thisMarkerPtr.getPointer() );
+        }
+    }
+
+    /* 
+     * Fills a map of all the JniMarkerField associated with this JniMarker.
+     * 
+     * Note: This function is called from C and there is no way to propagate
+     * exception back to the caller without crashing JNI. Therefore, it MUST
+     * catch all exceptions.
+     * 
+     * @param markerName        Name of the parent marker
+     * @param markerFieldPtr    C Pointer (converted in long) to marker_field C Structure
+     */
+    @SuppressWarnings("unused")
+    private void addMarkerFieldFromC(String markerFieldName, long markerFieldPtr) {
+        // Create a new Jaf_markerField object and insert it in the map
+        // the maker field fill itself with LTT data while being constructed
+        try {
+            JniMarkerField newMarkerField = new JniMarkerField( new Jni_C_Pointer(markerFieldPtr) );
+            markerFieldsArrayList.add(newMarkerField);
+            markerFieldsHashMap.put(markerFieldName, newMarkerField);
+            
+        } catch (JniException e) {
+            printlnC("Failed to add marker field " + markerFieldName + " to marker fields list!(addMarkerFieldFromC)\n\tException raised : " + e.toString() );
+        }
+    }
+
+    // Access to class variable. Most of them doesn't have setter
+    public String getName() {
+        return name;
+    }
+
+    public String getFormatOverview() {
+        return formatOverview;
+    }
+
+    public HashMap<String,JniMarkerField> getMarkerFieldsHashMap() {
+        return markerFieldsHashMap;
+    }
+    
+    public ArrayList<JniMarkerField> getMarkerFieldsArrayList() {
+        return markerFieldsArrayList;
+    }
+    
+    /**
+     * Pointer to the marker_info C structure.<p>
+     * 
+     * The pointer should only be used <u>INTERNALY</u>, do not use unless you
+     * know what you are doing.<p>
+     * 
+     * @return The actual (long converted) pointer or NULL
+     * 
+     * @see org.eclipse.linuxtools.lttng.jni.eclipse.linuxtools.lttng.jni.Jni_C_Pointer
+     */
+    public Jni_C_Pointer getMarkerPtr() {
+        return thisMarkerPtr;
+    }
+    
+    
+    /**
+     * Print information for this JniMarker. 
+     * <u>Intended to debug</u><br>
+     * 
+     * This function will call Ltt to print, so information printed will be the one from 
+     * the C structure, not the one populated in java.<p>
+     * 
+     * This function will not throw but will complain loudly if pointer is NULL
+     */
+    public void printMarkerInformation() {
+
+        // If null pointer, print a warning!
+        if (thisMarkerPtr.getPointer() == NULL) {
+            printlnC("Pointer is NULL, cannot print. (printMarkerInformation)");
+        } else {
+            ltt_printMarker(thisMarkerPtr.getPointer());
+        }
+    }
+    
+    /**
+     * Print information for ALL marker fields for this marker. 
+     * <u>Intended to debug</u><br>
+     * 
+     * This function will call Ltt to print, so information printed will be the one from 
+     * the C structure, not the one populated in java.
+     */
+    public void printAllMarkerFieldsInformation() {
+        Object[] allMarkersField = markerFieldsArrayList.toArray();
+
+        for (int pos = 0; pos < allMarkersField.length; pos++) {
+            printlnC(allMarkersField[pos].toString());
+        }
+    }
+    
+    /**
+     * toString() method. 
+     * <u>Intended to debug</u><br>
+     * 
+     * @return Attributes of the object concatenated in String
+     */
+    @Override
+       public String toString() {
+        String returnData = "";
+
+        returnData += "name                    : " + name + "\n";
+        returnData += "formatOverview          : " + formatOverview + "\n";
+        returnData += "markerFieldArrayList    : " + markerFieldsArrayList.toArray() + "\n";
+
+        return returnData;
+    }
+    
+}
diff --git a/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/jni/JniMarkerField.java b/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/jni/JniMarkerField.java
new file mode 100644 (file)
index 0000000..de2422f
--- /dev/null
@@ -0,0 +1,158 @@
+package org.eclipse.linuxtools.lttng.jni;
+/*******************************************************************************
+ * Copyright (c) 2009 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:
+ *   William Bourque (wbourque@gmail.com) - Initial API and implementation
+ *******************************************************************************/
+
+
+/**
+ * <b><u>JniMarkerField</u></b> <p>
+ * A JniMarkerField is one of the field of the unparsed content (payload) of an event. <p>
+ * 
+ * Provides access to the marker_field C structure (from LTT) in java.<p>
+ * 
+ * Most important attributes in the JniMarkerField are :
+ * <ul>
+ * <li> the name (field) of in String
+ * <li> the marker field format (in C style printf format)
+ * </ul>
+ */
+public final class JniMarkerField extends Jni_C_Common
+{
+    // Internal C pointer of the JniEvent used in LTT
+    private Jni_C_Pointer thisMarkerFieldPtr = new Jni_C_Pointer();
+
+    private String field = "";
+    private String format = "";
+    
+    // Native access method
+    private native String ltt_getField(long markerFieldPtr);
+    @SuppressWarnings("unused")
+    private native int ltt_getType(long markerFieldPtr);
+    @SuppressWarnings("unused")
+    private native long ltt_getOffset(long markerFieldPtr);
+    @SuppressWarnings("unused")
+    private native long ltt_getSize(long markerFieldPtr);
+    @SuppressWarnings("unused")
+    private native long ltt_getAlignment(long markerFieldPtr);
+    @SuppressWarnings("unused")
+    private native long ltt_getAttributes(long markerFieldPtr);
+    @SuppressWarnings("unused")
+    private native int ltt_getStatic_offset(long markerFieldPtr);
+    private native String ltt_getFormat(long markerFieldPtr);
+
+    // Debug native function, ask LTT to print marker structure
+    private native void ltt_printMarkerField(long markerFieldPtr);
+
+    static {
+        System.loadLibrary("lttvtraceread");
+    }
+
+    /*
+     * Default constructor is forbidden
+     */
+    @SuppressWarnings("unused")
+    private JniMarkerField() {
+    }
+
+    /**
+     * Copy constructor.<p>
+     * 
+     * @param oldMarkerField Reference to the JniMarkerField you want to copy. 
+     */
+    public JniMarkerField(JniMarkerField oldMarkerField) {
+        thisMarkerFieldPtr = oldMarkerField.getMarkerFieldPtr();
+        field = oldMarkerField.getField();
+        format = oldMarkerField.getFormat();
+    }
+
+    /**
+     * Constructor, using pointer.<p>
+     * 
+     * @param newMarkerFieldPtr  Pointer to a C marker_field structure
+     * 
+     * @exception JniException
+     */
+    public JniMarkerField(Jni_C_Pointer newMarkerFieldPtr) throws JniException {
+        thisMarkerFieldPtr = newMarkerFieldPtr;
+
+        // Populate the marker field
+        populateMarkerFieldInformation();
+    }
+
+    /* 
+     * This function populates the marker field data with data from LTT
+     * 
+     */
+    private void populateMarkerFieldInformation() throws JniException {
+        if (thisMarkerFieldPtr.getPointer() == NULL) {
+            throw new JniMarkerFieldException(
+                    "Pointer is NULL, trace closed? (populateMarkerInformation)");
+        } else {
+            field = ltt_getField(thisMarkerFieldPtr.getPointer());
+            format = ltt_getFormat(thisMarkerFieldPtr.getPointer());
+        }
+    }
+
+    public String getField() {
+        return field;
+    }
+
+    public String getFormat() {
+        return format;
+    }
+
+    /**
+     * Pointer to the marker_field C structure.<p>
+     * 
+     * The pointer should only be used <u>INTERNALY</u>, do not use these unless you
+     * know what you are doing.<p>
+     * 
+     * @return The actual (long converted) pointer or NULL
+     * 
+     * @see org.eclipse.linuxtools.lttng.jni.eclipse.linuxtools.lttng.jni.Jni_C_Pointer
+     */
+    public Jni_C_Pointer getMarkerFieldPtr() {
+        return thisMarkerFieldPtr;
+    }
+    
+    /**
+     * Print information for this event. <u>Intended to debug</u><br>
+     * 
+     * This function will call Ltt to print, so information printed will be the one from 
+     * the C structure, not the one populated in java.<p>
+     * 
+     * This function will not throw but will complain loudly if pointer is NULL
+     */
+    public void printMarkerFieldInformation() {
+
+        // If null pointer, print a warning!
+        if (thisMarkerFieldPtr.getPointer() == NULL) {
+            printlnC("Pointer is NULL, cannot print. (printMarkerFieldInformation)");
+        } else {
+            ltt_printMarkerField(thisMarkerFieldPtr.getPointer());
+        }
+    }
+    
+    /**
+     * toString() method. 
+     * <u>Intended to debug</u><br>
+     * 
+     * @return Attributes of the object concatenated in String
+     */
+    @Override
+    public String toString() {
+        String returnData = "";
+        returnData += "field                   : " + field + "\n";
+        returnData += "format                  : " + format + "\n";
+        
+        return returnData;
+    }
+}
diff --git a/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/jni/JniParser.java b/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/jni/JniParser.java
new file mode 100644 (file)
index 0000000..4f1ee63
--- /dev/null
@@ -0,0 +1,304 @@
+package org.eclipse.linuxtools.lttng.jni;
+/*******************************************************************************
+ * Copyright (c) 2009 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:
+ *   William Bourque (wbourque@gmail.com) - Initial API and implementation
+ *******************************************************************************/
+
+
+import java.util.HashMap;
+import java.util.Iterator;
+
+/**
+ * <b><u>JniParser</u></b><p>
+ * 
+ * JniParser is used to parse an event payload into something usable.<p>
+ * 
+ * All methods are static, the parser shouldn't be instantiated.
+ */
+public class JniParser extends Jni_C_Common
+{
+    private static native void ltt_getParsedData(ParsedObjectContent parseddata, long eventPtr, long markerFieldPtr);
+
+    static {
+        System.loadLibrary("lttvtraceread");
+    }
+    
+    // *** HACK ***
+    // We cannot use "Object" directly as java does not support swapping primitive value
+    //    We either need to create a new object type or to use a "non-primitive" type that have "Setter()" functions
+    //    Another (ugly) hack would be to pass an array to modify the reference's reference.
+    // ***
+    private static ParsedObjectContent parsedData = new ParsedObjectContent();
+    
+    /*
+     * Default constructor is forbidden
+     */
+    private JniParser() {
+    }
+    
+    
+    /**
+     * Method to parse a single field identified by its id.<p>
+     * 
+     * All parsing will be done on C side as we need LTT functions.
+     * 
+     * @param   eventToParse    The jni event we want to parse. 
+     * @param   fieldPosition   The position (or id) of the field we want to parse
+     * 
+     * @return                  An Object that contain the JniEvent payload parsed by the C, or null, if if was impossible to parse (i.e., wrong position)
+     * 
+     * @see org.eclipse.linuxtools.lttng.jni.eclipse.linuxtools.lttng.jni.JniEvent
+     */
+    static public Object parseField(JniEvent eventToParse, int fieldPosition) {
+        
+        // Sanity check
+        if ( (fieldPosition < 0) || ( fieldPosition >= eventToParse.requestEventMarker().getMarkerFieldsArrayList().size() ) ){
+            return null;
+        }
+        
+        JniMarkerField tmpField = eventToParse.requestEventMarker().getMarkerFieldsArrayList().get(fieldPosition);
+        
+        // Call the parsing function in C. The result will be put in parsedData object
+        ltt_getParsedData(parsedData, eventToParse.getEventPtr().getPointer(), tmpField.getMarkerFieldPtr().getPointer() );
+        
+        return parsedData.getData();
+    }
+    
+    
+    /**
+     * Method to parse a single field identified by its name.<p>
+     * 
+     * All parsing will be done on C side as we need LTT functions.
+     * 
+     * @param   eventToParse    The jni event we want to parse. 
+     * @param   fieldName       The name of the field we want to parse.
+     * 
+     * @return                  An Object that contain the JniEvent payload parsed by the C, or null, if if was impossible to parse (i.e., wrong position)
+     * 
+     * @see org.eclipse.linuxtools.lttng.jni.eclipse.linuxtools.lttng.jni.JniEvent
+     */
+    static public Object parseField(JniEvent eventToParse, String fieldName) {
+        
+        JniMarkerField tmpField = eventToParse.requestEventMarker().getMarkerFieldsHashMap().get(fieldName);
+        
+        // return immediately if there is no field by that name
+        if ( tmpField == null ) {
+            return null;
+        }
+        
+        ltt_getParsedData(parsedData, eventToParse.getEventPtr().getPointer(), tmpField.getMarkerFieldPtr().getPointer() );
+        
+        return parsedData.getData();
+    }
+    
+    
+    
+    /**
+     * Method to parse all fields at once.<p>
+     * 
+     * All parsing will be done on C side as we need LTT functions.
+     * 
+     * @param   eventToParse    The jni event we want to parse.  
+     * @return                  An HashMap of Object that contain the is the JniEvent's payload parsed by the C
+     * 
+     * @see org.eclipse.linuxtools.lttng.jni.eclipse.linuxtools.lttng.jni.JniEvent
+     */
+    static public HashMap<String, Object> parseAllFields(JniEvent eventToParse) {
+        HashMap<String,JniMarkerField> markerFieldData = eventToParse.requestEventMarker().getMarkerFieldsHashMap();
+               
+               // This hashmap will contain the parsed content.
+               // ParsedContent is a local class defined at the end of this file
+               
+               // *** HACK ***
+               // We want (need?) the map that contain the parsed data to be in the same order as markerField map
+               // The "instinctive way" would be to use : 
+               //       HashMap<String, Object> parsedDataMap = new HashMap<String, Object>(nbMarkerField);
+               //
+               // However, we cannot ensure that the newly created hashmap will use the same order.
+               // The hard way would be to override the default hash function for both hashmap
+               // However, this is way easier to abuse the fact that both hashmap are of type <String, something...>
+               // Therefore we can abuse the java-cast with clone() : 
+               //       HashMap<String, Object> parsedDataMap = (HashMap<String, Object>)markerFieldData.clone();
+               // Or even safer, use HashMap constructor to do so : 
+        HashMap<String, Object> parsedDataMap = new HashMap<String, Object>(markerFieldData);
+                
+        String              newKey             = null; 
+        JniMarkerField      newMarkerField  = null;
+        Iterator<String>    iterator        = markerFieldData.keySet().iterator();
+        
+        while ( iterator.hasNext() ) {
+            newKey = iterator.next();
+            newMarkerField = markerFieldData.get(newKey);
+            // Call the C to parse the data
+            ltt_getParsedData(parsedData, eventToParse.getEventPtr().getPointer(), newMarkerField.getMarkerFieldPtr().getPointer() );
+            // Save the result into the HashMap
+            parsedDataMap.put(newMarkerField.getField(), parsedData.getData() );
+        }
+        return parsedDataMap;
+    }
+    
+    
+    /* 
+     * Add a parsed String value to the Array<br>
+     * <br>
+     * Note : this function will be called from the C side.
+     * Note2: contentHolder is of type "Object" instead of "ParsedObjectContent" to be able to use the most generic function signature on the C side.
+     *          its goal is to give a generic interface to people that would like to use the JNI library
+     * 
+     * @param parsedArray   Array where to store the value
+     * @param fieldName     The name of the parsed field
+     * @param stringToAdd   The parsed data to add
+     * @param formatToAdd   The format of the raw data
+     */
+    @SuppressWarnings("unused")
+    static private void addStringToParsingFromC(Object contentHolder, String stringToAdd) {
+        ((ParsedObjectContent)contentHolder).setData( stringToAdd);
+    }
+
+    /* 
+     * Add a parsed 64 bits Pointer value to the Array<br>
+     * <br>
+     * Note : this function will be called from the C side.
+     * Note2: contentHolder is of type "Object" instead of "ParsedObjectContent" to be able to use the most generic function signature on the C side.
+     *          its goal is to give a generic interface to people that would like to use the JNI library
+     * 
+     * @param contentHolder Object where to store the parsed value
+     * @param fieldName     The name of the parsed field
+     * @param pointerToAdd  The parsed data to add (in 64 bits long!)
+     * @param formatToAdd   The format of the raw data
+     */
+    @SuppressWarnings("unused")
+    static private void addLongPointerToParsingFromC(Object contentHolder, long pointerToAdd) {
+        ((ParsedObjectContent)contentHolder).setData( new Jni_C_Pointer((long) pointerToAdd));
+    }
+
+    /* 
+     * Add a parsed 32 bits Pointer value to the Array<br>
+     * <br>
+     * Note : this function will be called from the C side.
+     * Note2: contentHolder is of type "Object" instead of "ParsedObjectContent" to be able to use the most generic function signature on the C side.
+     *          its goal is to give a generic interface to people that would like to use the JNI library
+     * 
+     * @param contentHolder Object where to store the parsed value
+     * @param fieldName     The name of the parsed field
+     * @param pointerToAdd  The parsed data to add (converted in 64 bits long!)
+     * @param formatToAdd   The format of the raw data
+     */
+    @SuppressWarnings("unused")
+    static private void addIntPointerToParsingFromC(Object contentHolder, long pointerToAdd) {
+        ((ParsedObjectContent)contentHolder).setData( new Jni_C_Pointer((int) pointerToAdd));
+    }
+
+    /* 
+     * Add a parsed short value to the Array<br>
+     * <br>
+     * Note : this function will be called from the C side.
+     * Note2: contentHolder is of type "Object" instead of "ParsedObjectContent" to be able to use the most generic function signature on the C side.
+     *          its goal is to give a generic interface to people that would like to use the JNI library
+     * 
+     * @param contentHolder Object where to store the parsed value
+     * @param fieldName     The name of the parsed field
+     * @param shortToAdd    The parsed data to add
+     * @param formatToAdd   The format of the raw data
+     */
+    @SuppressWarnings("unused")
+    static private void addShortToParsingFromC(Object contentHolder, short shortToAdd) {
+        ((ParsedObjectContent)contentHolder).setData( new Short(shortToAdd));
+    }
+
+    /* 
+     * Add a parsed integer value to the Array<br>
+     * <br>
+     * Note : this function will be called from the C side.
+     * Note2: contentHolder is of type "Object" instead of "ParsedObjectContent" to be able to use the most generic function signature on the C side.
+     *          its goal is to give a generic interface to people that would like to use the JNI library
+     * 
+     * @param contentHolder Object where to store the parsed value
+     * @param fieldName     The name of the parsed field
+     * @param intToAdd      The parsed data to add
+     * @param formatToAdd   The format of the raw data
+     */
+    @SuppressWarnings("unused")
+    static private void addIntegerToParsingFromC(Object contentHolder, int intToAdd) {
+        ((ParsedObjectContent)contentHolder).setData( new Integer(intToAdd));
+    }
+
+    /* 
+     * Add a parsed long value to the Array<br>
+     * <br>
+     * Note : this function will be called from the C side.
+     * Note2: contentHolder is of type "Object" instead of "ParsedObjectContent" to be able to use the most generic function signature on the C side.
+     *          its goal is to give a generic interface to people that would like to use the JNI library
+     * 
+     * @param contentHolder Object where to store the parsed value
+     * @param fieldName     The name of the parsed field
+     * @param longToAdd     The parsed data to add
+     * @param formatToAdd   The format of the raw data
+     */
+    @SuppressWarnings("unused")
+    static private void addLongToParsingFromC(Object contentHolder, long longToAdd) {
+        ((ParsedObjectContent)contentHolder).setData( new Long(longToAdd));
+    }
+
+    /* 
+     * Add a parsed float value to the Array<br>
+     * <br>
+     * Note : this function will be called from the C side.
+     * Note2: contentHolder is of type "Object" instead of "ParsedObjectContent" to be able to use the most generic function signature on the C side.
+     *          its goal is to give a generic interface to people that would like to use the JNI library
+     * 
+     * @param contentHolder Object where to store the parsed value
+     * @param fieldName     The name of the parsed field
+     * @param floatToAdd    The parsed data to add
+     * @param formatToAdd   The format of the raw data
+     */
+    @SuppressWarnings("unused")
+    static private void addFloatToParsingFromC(Object contentHolder, float floatToAdd) {
+        ((ParsedObjectContent)contentHolder).setData( new Float(floatToAdd));
+    }
+
+    /* 
+     * Add a parsed double value to the Array<br>
+     * <br>
+     * Note : this function will be called from the C side.
+     * Note2: contentHolder is of type "Object" instead of "ParsedObjectContent" to be able to use the most generic function signature on the C side.
+     *          its goal is to give a generic interface to people that would like to use the JNI library
+     * 
+     * 
+     * @param contentHolder Object where to store the parsed value
+     * @param fieldName     The name of the parsed field
+     * @param doubleToAdd   The parsed data to add
+     * @param formatToAdd   The format of the raw data
+     */
+    @SuppressWarnings("unused")
+    static private void addDoubleToParsingFromC(Object contentHolder, double doubleToAdd) {
+        ((ParsedObjectContent)contentHolder).setData( new Double(doubleToAdd));
+    }
+    
+}
+
+/**
+ * <b><u>ParsedObjectContent</u></b><p>
+ * 
+ * ParsedObjectContent class.
+ * Only be used locally in this object to parse event data more efficiently in the C.
+ */
+class ParsedObjectContent {
+    private Object parsedData = null;
+    
+    public Object getData() {
+        return parsedData;
+    }
+    
+    public void setData(Object newData) {
+        parsedData = newData;
+    }
+}
\ No newline at end of file
diff --git a/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/jni/JniTime.java b/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/jni/JniTime.java
new file mode 100644 (file)
index 0000000..e6d64de
--- /dev/null
@@ -0,0 +1,178 @@
+package org.eclipse.linuxtools.lttng.jni;
+/*******************************************************************************
+ * Copyright (c) 2009 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:
+ *   William Bourque (wbourque@gmail.com) - Initial API and implementation
+ *******************************************************************************/
+
+
+/**
+ * <b><u>JniTime</u></b>
+ * <p>
+ * Used to store (event, trace, tracefile, ...) timestamp.
+ * 
+ * Mimic the behavior of the LttTime C structure.
+ */
+public final class JniTime extends Jni_C_Common implements Comparable<JniTime>
+{
+    private long time = 0;
+
+    /**
+     * Default constructor.<p>
+     * 
+     * Note : Time will be set to 0.
+     * 
+     */
+    public JniTime() {
+        time = 0;
+    }
+
+    /**
+     * Copy constructor.
+     * 
+     * @param oldTime   Reference to the JniTime you want to copy.           
+     */
+    public JniTime(JniTime oldTime) {
+        time = oldTime.getTime();
+    }
+
+    /**
+     * Constructor with parameters.<p>
+     * 
+     * "LTT style" constructor with Seconds et Nanoseconds
+     * 
+     * @param newSec      Seconds of the JniTime
+     * @param newNanoSec  Nanoseconds of the JniTime
+     */
+    public JniTime(long newSec, long newNanoSec) {
+        time = (newSec * NANO) + newNanoSec;
+    }
+
+    /**
+     * Constructor with parameters.<p>
+     * 
+     * Usual "nanosecond only" constructor.
+     * 
+     * @param newNanoSecTime  Time in nanoseconds
+     */
+    public JniTime(long newNanoSecTime) {
+        time = newNanoSecTime;
+    }
+
+    /**
+     * Second of the time.<p>
+     * 
+     * Returns seconds, i.e. multiple of 1 000 000, of the stored nanoseconds time.
+     * 
+     * @return Second of this time.
+     */
+    public long getSeconds() {
+        return (time / NANO);
+    }
+
+    /**
+     * Getter for the nanosecond of the time.<p>
+     * 
+     * Returns nanoseconds part, i.e. modulo of 1 000 000, of the stored nanoseconds time.
+     * 
+     * @return Nanoseconds of this time
+     */
+    public long getNanoSeconds() {
+        return time % NANO;
+    }
+
+    /**
+     * Full time, in nanoseconds.<p>
+     * 
+     * @return Complete time in nanoseconds
+     */
+    public long getTime() {
+        return time;
+    }
+    
+    /**
+     * Changes the current time for this object<p>
+     * 
+     * @param newTime  New time to set, in nanoseconds.
+     */
+    public void setTime(long newTime) {
+        time = newTime;
+    }
+    
+    /* 
+     * Populate this time object
+     * 
+     * Note: This function is called from C side.
+     * 
+     * @param newTime The time we want to populate
+     */
+    @SuppressWarnings("unused")
+    private void setTimeFromC(long newTime) {
+        time = newTime;
+    }
+    
+    /**
+     * Comparaison operator smaller or equal than "<=" .<p>
+     * 
+     * @param comparedTime  The time we want to compare with this one
+     * 
+     * @return true if compared time is smaller or equal, false otherwise
+     */
+    public boolean isSmallerOrEqual(JniTime comparedTime) {
+
+        // NOTE : We check <= instead of just <
+        // This mean the LEFT OPERAND (comparedTime) always prevails
+        if (this.getTime() <= comparedTime.getTime() ) {
+            return true;
+        } 
+        else {
+            return false;
+        }
+    }
+    
+    /**
+     * compareTo operator.<p>
+     * 
+     * @param right  The time we want to compare with this one
+     * 
+     * @return int of value -1, 0 or 1, as the pased argument is bigger, equal or smaller than this time
+     */
+    public int compareTo(JniTime right) {
+        long leftTime = this.getTime();
+        long rightTime = right.getTime();
+        
+        if ( leftTime < rightTime ) { 
+            return -1;
+        }
+        else if ( leftTime > rightTime ) {
+            return  1;
+        }
+        else {
+            return 0;
+        }
+    }
+    
+    /**
+     * toString() method.
+     * <u>Intended to debug</u><p>
+     * 
+     * NOTE : We output the time in the same format as LTT (seconds and nanosecond separatly)
+     * 
+     * @return String Attributes of the object concatenated in String
+     */
+    @Override
+       public String toString() {
+        String returnData = "";
+
+        returnData += "seconds     : " + this.getSeconds() + "\n";
+        returnData += "nanoSeconds : " + this.getNanoSeconds() + "\n";
+
+        return returnData;
+    }
+}
diff --git a/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/jni/JniTrace.java b/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/jni/JniTrace.java
new file mode 100644 (file)
index 0000000..113c041
--- /dev/null
@@ -0,0 +1,785 @@
+package org.eclipse.linuxtools.lttng.jni;
+/*******************************************************************************
+ * Copyright (c) 2009 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:
+ *   William Bourque (wbourque@gmail.com) - Initial API and implementation
+ *******************************************************************************/
+
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.PriorityQueue;
+
+/**
+ * <b><u>JniTrace</u></b>
+ * <p>
+ * This is the top level class in the JNI. It provides access to the 
+ * LttTrace C structure in java.
+ * <p>
+ * Most important fields in the JniTrace are :
+ * <ul>
+ * <li>a JniTrace path (a trace <b>directory</b>)
+ * <li>a HashMap of tracefiles that exists in this trace
+ * </ul>
+ */
+public class JniTrace extends Jni_C_Common {
+    
+    private final static boolean DEFAULT_LTT_DEBUG = false;
+    
+    // Internal C pointer of the JniTrace used in LTT
+    private Jni_C_Pointer thisTracePtr = new Jni_C_Pointer();
+
+    // Data we should populate from LTT
+    // Note that all type have been scaled up as there is no "unsigned" in java
+    // This might be a problem about "unsigned long" as there is no equivalent
+    // in java
+
+    private String tracepath = ""; // Path of the trace. Should be a directory (like : /tmp/traceX)
+    private int    cpuNumber = 0;
+    private long   archType = 0;
+    private long   archVariant = 0;
+    private short  archSize = 0;
+    private short  lttMajorVersion = 0;
+    private short  lttMinorVersion = 0;
+    private short  flightRecorder = 0;
+    private long   freqScale = 0;
+    private long   startFreq = 0;
+    private long   startTimestampCurrentCounter = 0;
+    private long   startMonotonic = 0;
+    private JniTime startTimeNoAdjustement = null;
+    private JniTime startTime = null;
+    private JniTime endTime = null;
+    
+    // This Map holds a reference to the tracefiles owned by this trace
+    private HashMap<String, JniTracefile> tracefilesMap = null;
+    // The priority queue (similar to heap) hold events 
+    private PriorityQueue<JniEvent> eventsHeap = null;
+    
+    // This variable will hold the content of the "last" event we read
+    private JniEvent currentEvent = null;  
+    
+    // Should we print debug in the C library or not?
+    private boolean printLttDebug = DEFAULT_LTT_DEBUG;
+    
+    // Open/close native functions
+    private native long ltt_openTrace(String pathname, boolean printDebug);
+    private native void ltt_closeTrace(long tracePtr);
+
+    // Native access functions
+    private native String ltt_getTracepath(long tracePtr);
+    private native int    ltt_getCpuNumber(long tracePtr);
+    private native long   ltt_getArchType(long tracePtr);
+    private native long   ltt_getArchVariant(long tracePtr);
+    private native short  ltt_getArchSize(long tracePtr);
+    private native short  ltt_getLttMajorVersion(long tracePtr);
+    private native short  ltt_getLttMinorVersion(long tracePtr);
+    private native short  ltt_getFlightRecorder(long tracePtr);
+    private native long   ltt_getFreqScale(long tracePtr);
+    private native long   ltt_getStartFreq(long tracePtr);
+    private native long   ltt_getStartTimestampCurrentCounter(long tracePtr);
+    private native long   ltt_getStartMonotonic(long tracePtr);
+    
+    // Native function to fill out startTime
+    private native void ltt_feedStartTime(long tracePtr, JniTime startTime);
+    
+    // Native function to fill out startTimeFromTimestampCurrentCounter
+    private native void ltt_feedStartTimeFromTimestampCurrentCounter(long tracePtr, JniTime startTime);
+
+    // Native function to fill out tracefilesMap
+    private native void ltt_feedAllTracefiles(long tracePtr);
+    
+    // Native function to fill out the start and end time of the trace
+    private native void ltt_feedTracefileTimeRange(long tracePtr, JniTime startTime, JniTime endTime);
+    
+    // Debug native function, ask LTT to print trace structure
+    private native void ltt_printTrace(long tracePtr);
+
+    static {
+        System.loadLibrary("lttvtraceread");
+    }
+    
+    /*
+     * Default constructor is forbidden
+     */
+    @SuppressWarnings("unused")
+    private JniTrace() {
+    }
+    
+    /**
+     * Constructor that takes a tracepath parameter.<p>
+     * 
+     * This constructor also opens the trace.
+     * 
+     * @param newpath The <b>directory</b> of the trace to be opened
+     * @param newPrintDebug Should the debug information be printed in the LTT C library
+     * 
+     * @exception JniException
+     */
+    public JniTrace(String newpath, boolean newPrintDebug) throws JniException {
+        tracepath = newpath;
+        thisTracePtr = new Jni_C_Pointer();
+        printLttDebug = newPrintDebug;
+        
+        openTrace(newpath);
+    }
+    
+    /**
+     * Copy constructor.
+     * 
+     * @param oldTrace  A reference to the JniTrace to copy.           
+     */
+    public JniTrace(JniTrace oldTrace) {
+        thisTracePtr  = oldTrace.thisTracePtr;
+        
+        tracepath       = oldTrace.tracepath;
+        cpuNumber       = oldTrace.cpuNumber;
+        archType        = oldTrace.archType;
+        archVariant     = oldTrace.archVariant;
+        archSize        = oldTrace.archSize;
+        lttMajorVersion = oldTrace.lttMajorVersion;
+        lttMinorVersion = oldTrace.lttMinorVersion;
+        flightRecorder  = oldTrace.flightRecorder;
+        freqScale       = oldTrace.freqScale;
+        startFreq       = oldTrace.startFreq;
+        startTimestampCurrentCounter = oldTrace.startTimestampCurrentCounter;
+        startMonotonic  = oldTrace.startMonotonic;
+        startTimeNoAdjustement = oldTrace.startTimeNoAdjustement;
+        startTime       = oldTrace.startTime;
+        endTime         = oldTrace.endTime;
+
+        tracefilesMap = new HashMap<String, JniTracefile>(oldTrace.tracefilesMap.size());
+        tracefilesMap = oldTrace.tracefilesMap;
+        
+        eventsHeap = new PriorityQueue<JniEvent>( oldTrace.eventsHeap.size());
+        eventsHeap = oldTrace.eventsHeap;
+        
+        printLttDebug = oldTrace.printLttDebug;
+    }        
+        
+    /**
+     * Constructor, using C pointer.<p>
+     * 
+     * @param newPtr The pointer to an already opened LttTrace C structure.
+     * @param newPrintDebug Should the debug information be printed in the LTT C library
+     *            
+     * @exception JniException
+     * 
+     * @see org.eclipse.linuxtools.lttng.jni.eclipse.linuxtools.lttng.jni.Jni_C_Pointer
+     */
+    public JniTrace(Jni_C_Pointer newPtr, boolean newPrintDebug) throws JniException {
+        thisTracePtr = newPtr;
+        printLttDebug = newPrintDebug;
+        
+        // Populate our trace
+        populateTraceInformation();
+    }
+        
+    /**
+     * Open an existing trace.<p>
+     * 
+     * The tracepath is a directory and needs to exist, otherwise
+     * a JafOpenTraceFailedException is throwed.
+     * 
+     * @param newPath The <b>directory</b> of the trace to be opened
+     * 
+     * @exception JniOpenTraceFailedException Thrown if the open failed
+     */
+    public void openTrace(String newPath) throws JniException {
+        // If open is called while a trace is already opened, we will try to close it first
+        if (thisTracePtr.getPointer() != NULL) {
+            closeTrace();
+        }
+
+        // Set the tracepath and open it
+        tracepath = newPath;
+        openTrace();
+    }
+        
+    /**
+     * Open an existing trace.<p>
+     * 
+     * The tracepath should have been set already,
+     * 
+     * @exception JniOpenTraceFailedException  Thrown if the open failed
+     */
+    public void openTrace() throws JniException {
+        
+        // Raise an exception if the tracepath is empty, otherwise open the trace
+        if (tracepath == "") {
+            throw new JniTraceException("Tracepath is not set. (openTrace)");
+        }
+        
+        // If the file is already opened, close it first
+        if (thisTracePtr.getPointer() != NULL) {
+            closeTrace();
+        }
+
+        // Call the LTT to open the trace
+        long newPtr = ltt_openTrace(tracepath, printLttDebug);
+        if (newPtr == NULL) {
+            throw new JniOpenTraceFailedException("Error while opening trace. Is the tracepath correct? (openTrace)");
+        }
+        
+        // This is OUR pointer
+        thisTracePtr = new Jni_C_Pointer(newPtr);
+
+        // Populate the trace with LTT information
+        populateTraceInformation();
+    }
+        
+    /**
+     * Close a trace.<p>
+     * 
+     * If the trace is already closed, will silently do nothing.
+     */
+    public void closeTrace() {
+        if (thisTracePtr.getPointer() != NULL) {
+            ltt_closeTrace(thisTracePtr.getPointer());
+            thisTracePtr = new Jni_C_Pointer(NULL);
+
+            // Clear the tracefile map
+            tracefilesMap.clear();
+            tracefilesMap = null;
+            
+            // Clear the eventsHeap and make it points to null
+            eventsHeap.clear();
+            eventsHeap = null;
+
+            // Ask the garbage collector to make a little pass here, as we could
+            // be left with 100's of unreferenced objects
+            System.gc();
+        }
+    }
+
+    /* 
+     * This function populates the trace data with data from LTT
+     * 
+     * @throws JniException
+     */
+    private void populateTraceInformation() throws JniException {
+        if (thisTracePtr.getPointer() == NULL) {
+            throw new JniTraceException("Pointer is NULL, trace not opened/already closed? (populateTraceInformation)");
+        }
+
+        // Populate from the LTT library
+        tracepath   = ltt_getTracepath( thisTracePtr.getPointer() );
+        cpuNumber   = ltt_getCpuNumber( thisTracePtr.getPointer() );
+        archType    = ltt_getArchType( thisTracePtr.getPointer() );
+        archVariant = ltt_getArchVariant( thisTracePtr.getPointer() );
+        archSize    = ltt_getArchSize( thisTracePtr.getPointer() );
+        lttMajorVersion = ltt_getLttMajorVersion( thisTracePtr.getPointer() );
+        lttMinorVersion = ltt_getLttMinorVersion( thisTracePtr.getPointer() );
+        flightRecorder  = ltt_getFlightRecorder( thisTracePtr.getPointer() );
+        freqScale   = ltt_getFreqScale( thisTracePtr.getPointer() );
+        startFreq   = ltt_getStartFreq( thisTracePtr.getPointer() );
+        startTimestampCurrentCounter = ltt_getStartTimestampCurrentCounter( thisTracePtr.getPointer() );
+        startMonotonic = ltt_getStartMonotonic( thisTracePtr.getPointer() );
+
+        // Creation of time is a bit different, we need to pass the object reference to C
+        //
+        // *** NOTE : LTTv consider "raw startTime" (time without any frequency adjustement) to be default startTime
+        //                       So "startTimeNoAdjustement" is obtain throught "ltt_feedStartTime()" and
+        //                       "startTime" is obtained from ltt_feedStartTimeFromTimestampCurrentCounter()
+        startTimeNoAdjustement = new JniTime();
+        ltt_feedStartTime( thisTracePtr.getPointer(), startTimeNoAdjustement );
+        
+        startTime = new JniTime();
+        ltt_feedStartTimeFromTimestampCurrentCounter( thisTracePtr.getPointer(), startTime );
+
+        // Call the fill up function for the tracefiles map
+        if ( tracefilesMap== null ) {
+            tracefilesMap = new HashMap<String, JniTracefile>();
+        }
+        ltt_feedAllTracefiles( thisTracePtr.getPointer() );
+        
+        // Now, obtain the trace "endTime"
+        // Note that we discard "startTime" right away, as we already have it
+        endTime = new JniTime();
+        ltt_feedTracefileTimeRange(thisTracePtr.getPointer(), new JniTime(), endTime);
+        
+        if (eventsHeap == null) {
+            eventsHeap = new PriorityQueue<JniEvent>(tracefilesMap.size());
+        }
+        
+        // Populate the heap with events
+        populateEventHeap();
+    }
+    
+    /* 
+     * This function populates the event heap with one event from each tracefile
+     * It should be called after each seek or when the object is constructed
+     */
+    private void populateEventHeap() {
+        currentEvent = null;
+        eventsHeap.clear();
+        
+        Object new_key = null;
+        JniTracefile tmpTracefile = null;
+        
+        Iterator<String> iterator = tracefilesMap.keySet().iterator();
+        while( iterator.hasNext() ) {
+            new_key = iterator.next();
+            
+            tmpTracefile = tracefilesMap.get(new_key);
+            if ( tmpTracefile.getCurrentEvent().getEventState() == EOK ) {
+                eventsHeap.add( tmpTracefile.getCurrentEvent() );
+            }
+        }
+    }
+
+    /* 
+     * Fills a map of all the trace files.
+     * 
+     * Note: This function is called from C and there is no way to propagate
+     * exception back to the caller without crashing JNI. Therefore, it MUST
+     * catch all exceptions.
+     * 
+     * @param tracefileName
+     * @param tracefilePtr
+     */
+    @SuppressWarnings("unused")
+    private void addTracefileFromC(String tracefileName, long tracefilePtr) {
+        
+        JniTracefile newTracefile = null;
+            
+        // Create a new tracefile object and insert it in the map
+        //    the tracefile fill itself with LTT data while being constructed
+        try {
+            newTracefile = new JniTracefile( new Jni_C_Pointer(tracefilePtr), this );
+            tracefilesMap.put( (tracefileName + newTracefile.getCpuNumber()), newTracefile);
+        }
+        catch(JniTracefileWithoutEventException e) {
+            printlnC("JniTracefile " + tracefileName + " has no event (addTracefileFromC). Ignoring.");
+        }
+        catch(Exception e) {
+            printlnC("Failed to add tracefile " + tracefileName + " to tracefilesMap!(addTracefileFromC)\n\tException raised : " + e.toString() );
+        }
+    }
+    
+    /**
+     * Return the top event in the events stack, determined by timestamp, in the trace (all the tracefiles).<p>
+     * 
+     * Note : If the events were read before, the top event and the event currently loaded (currentEvent) are most likely the same.
+     * 
+     * @return The top event in the stack or null if no event is available.
+     * 
+     * @see org.eclipse.linuxtools.lttng.jni.eclipse.linuxtools.lttng.jni.JniEvent
+     */
+    public JniEvent findNextEvent() {
+        return eventsHeap.peek();
+    }
+    
+    /**
+     * Return the next event in the events stack, determined by timestamp, in the trace (all the tracefiles).<p>
+     * 
+     * @return The next event in the trace or null if no event is available.
+     * 
+     * @see org.eclipse.linuxtools.lttng.jni.eclipse.linuxtools.lttng.jni.JniEvent
+     */
+    public JniEvent readNextEvent() {
+        // Get the "next" event on the top of the heap but DO NOT remove it
+        JniEvent tmpEvent = eventsHeap.peek();
+        
+        // If the event is null, it was the last one in the trace we can leave the function
+        if (tmpEvent == null) {
+            return null;
+        }
+        
+        // Otherwise, we need to make sure the timestamp of the event we got is not the same as the last "NextEvent" we requested 
+        // NOTE : JniEvent.compareTo() compare by timestamp AND type, as 2 events of different type could have the same timestamp.
+        if ( tmpEvent.compareTo(currentEvent) == 0 ) {
+            // Remove the event on top as it is the same currentEventTimestamp
+            eventsHeap.poll();
+            
+            // Read the next event for this particular event type
+            tmpEvent.readNextEvent();
+            
+            // If the event state is sane (not Out of Range), put it back in the heap
+            if ( tmpEvent.getEventState() == EOK ) {
+                eventsHeap.add(tmpEvent);
+            }
+            
+            // Pick the top event again
+            tmpEvent = eventsHeap.peek();
+            
+            // Save the event we just read as the "current event"
+            currentEvent = tmpEvent;
+        }
+        // If the event on top has different timestamp than the currentTimestamp, just save this timestamp as current
+        else {
+            currentEvent = tmpEvent;
+        }
+        
+        return tmpEvent;
+    }
+    
+    /**
+     * Read the next event on a certain tracefile.<p>
+     * 
+     * By calling this function make sure the "global" readNextEvent() stay synchronised.
+     * Calling  readNextEvent() after this function will consider this tracefile moved and is then consistent.
+     * 
+     * @param targetTracefile  The tracefile object to read from
+     * 
+     * @return The next event in the tracefile or null if no event is available.
+     * 
+     * @see org.eclipse.linuxtools.lttng.jni.eclipse.linuxtools.lttng.jni.JniTracefile
+     * @see org.eclipse.linuxtools.lttng.jni.eclipse.linuxtools.lttng.jni.JniEvent
+     */
+    public JniEvent readNextEvent(JniTracefile targetTracefile) {
+        JniEvent returnedEvent = null;
+       
+        // There is 2 special cases where we should read the CURRENT event, not the next one
+        // 1- The currentEvent is null                      --> We never read or we just seeked
+        // 2- The currentEvent is of another type  --> We last read on a DIFFERENT tracefile
+        if ( (currentEvent == null) || 
+              (currentEvent.getParentTracefile().equals(targetTracefile) == false)
+            ) {
+            returnedEvent = targetTracefile.getCurrentEvent();
+            // Save the event we read
+            currentEvent = returnedEvent; 
+        }
+        else {
+               // Remove from the event related to this tracefile from the event heap, if it exists.
+               // WARNING : This only safe as long getCurrentEvent() never return "null" in any case.
+               eventsHeap.remove(targetTracefile.getCurrentEvent() );
+               
+               // If status EOK, we can return the event, otherwise something wrong happen (out of range, read error, etc...)
+               if ( targetTracefile.readNextEvent() == EOK) {
+                   returnedEvent = targetTracefile.getCurrentEvent();
+                       // Add back to the heap the read event
+                       eventsHeap.add(returnedEvent);
+               }
+               // Save the event we read... 
+               // Note : might be null if the read failed and it's ok
+               currentEvent = targetTracefile.getCurrentEvent(); 
+        }
+        
+       return returnedEvent;
+    }
+    
+    /**
+    * Seek to a certain time but <b>do not</b> read the next event.<p>
+    * 
+    * This only position the trace, it will not return anything.<p>
+    * 
+    * @param seekTime     The time where we want to seek to
+    * 
+    * @see org.eclipse.linuxtools.lttng.jni.eclipse.linuxtools.lttng.jni.JniTime
+    */
+    public void seekToTime(JniTime seekTime) {
+        
+        // Invalidate the last read event
+        currentEvent = null;
+        
+        Object tracefile_name = null;
+       Iterator<String> iterator = tracefilesMap.keySet().iterator();
+       
+       while (iterator.hasNext() ) {
+           // We seek to the given event for ALL tracefiles
+           tracefile_name = iterator.next();
+               seekToTime(seekTime, tracefilesMap.get(tracefile_name));
+       }
+       
+       populateEventHeap();
+    }
+       
+    /**
+    * Seek to a certain time on a certain tracefile but <b>do not</b> read the next event.<p>
+    * 
+    * This only position the trace, it will not return anything.<p>
+    * 
+    * @param targetTracefile   The tracefile object to read from
+    * @param seekTime                  The time where we want to seek to
+    * 
+    * @see org.eclipse.linuxtools.lttng.jni.eclipse.linuxtools.lttng.jni.JniTracefile
+    * @see org.eclipse.linuxtools.lttng.jni.eclipse.linuxtools.lttng.jni.JniTime
+    */
+    public void seekToTime(JniTime seekTime, JniTracefile targetTracefile) {
+        // Invalidate the current read event
+        currentEvent = null;
+        
+        // Remove from the event related to this tracefile from the event heap, if it exists.
+        // WARNING : This is only safe as long getCurrentEvent() never return "null" in any case.
+        eventsHeap.remove(targetTracefile.getCurrentEvent() );
+        
+        // Perform the actual seek on the tracefile
+        // Add the event to the heap if it succeed
+        if ( targetTracefile.seekToTime(seekTime) == EOK) {
+               // Add back to the heap the read event
+            eventsHeap.add(targetTracefile.getCurrentEvent());
+        }
+    }
+       
+    /**
+    * Seek to a certain timestamp and read the next event.
+    * <p>
+    * If no more events are available or an error happen, null will be returned.
+    * 
+    * @param seekTime      The time where we want to seek to.
+    * 
+    * @return The event just after the seeked time or null if none available.
+    * 
+    * @see org.eclipse.linuxtools.lttng.jni.eclipse.linuxtools.lttng.jni.JniEvent
+    * @see org.eclipse.linuxtools.lttng.jni.eclipse.linuxtools.lttng.jni.JniTime
+    */
+    public JniEvent seekAndRead(JniTime seekTime) { 
+         JniEvent returnedEvent = null;
+         seekToTime(seekTime);
+            
+         // The trace should be correctly positionned, let's get the event
+         returnedEvent = readNextEvent();
+             
+         return returnedEvent;
+    }
+       
+    /**
+    * Seek to a certain timestamp on a certain tracefile and read the next event.<p>
+    * 
+    * If no more events are available or an error happen, null will be returned.
+    * 
+    * Calling  readNextEvent() after this function will consider this tracefile moved and is then consistent.<br>
+    * 
+    * @param tracefileName   The tracefile object to read from
+    * @param seekTime           The time where we want to seek to
+    * 
+    * @return The event just after the seeked time or null if none available.
+    * 
+    * @see org.eclipse.linuxtools.lttng.jni.eclipse.linuxtools.lttng.jni.JniTracefile
+    * @see org.eclipse.linuxtools.lttng.jni.eclipse.linuxtools.lttng.jni.JniTime
+    * @see org.eclipse.linuxtools.lttng.jni.eclipse.linuxtools.lttng.jni.JniEvent
+    */
+    public JniEvent seekAndRead(JniTime seekTime, JniTracefile targetTracefile) { 
+        seekToTime(seekTime, targetTracefile);
+        return readNextEvent(targetTracefile);
+    }
+     
+    /**
+     * Get a certain tracefile from its given name.<p>
+     * 
+     * @param tracefileName     The name of the tracefile.
+     * 
+     * @return The tracefile found or null if none.
+     * 
+     * @see org.eclipse.linuxtools.lttng.jni.eclipse.linuxtools.lttng.jni.JniTracefile
+     */
+    public JniTracefile requestTracefileByName(String tracefileName) {
+        return tracefilesMap.get(tracefileName);
+    }        
+        
+    /**
+     * Get a certain event associated to a tracefile from the tracefile name.<p>
+     * 
+     * @param tracefileName     The name of the trace file.
+     * 
+     * @return Event of the tracefile or null if none found.
+     * 
+     * @see org.eclipse.linuxtools.lttng.jni.eclipse.linuxtools.lttng.jni.JniEvent
+     */
+    public JniEvent requestEventByName(String tracefileName) {
+        JniEvent returnValue = null;
+
+        JniTracefile tmpTracefile = tracefilesMap.get(tracefileName);
+
+        // If the tracefile is found, return the current event
+        // There should always be an event linked to a tracefile
+        if (tmpTracefile != null) {
+            returnValue = tmpTracefile.getCurrentEvent();
+        }
+
+        return returnValue;
+    }   
+        
+    // Access to class variable. Most of them doesn't have setter
+    public String getTracepath() {
+        return tracepath;
+    }
+
+    public int getCpuNumber() {
+        return cpuNumber;
+    }
+
+    public long getArchType() {
+        return archType;
+    }
+
+    public long getArchVariant() {
+        return archVariant;
+    }
+
+    public short getArchSize() {
+        return archSize;
+    }
+
+    public short getLttMajorVersion() {
+        return lttMajorVersion;
+    }
+
+    public short getLttMinorVersion() {
+        return lttMinorVersion;
+    }
+
+    public short getFlightRecorder() {
+        return flightRecorder;
+    }
+
+    public long getFreqScale() {
+        return freqScale;
+    }
+
+    public long getStartFreq() {
+        return startFreq;
+    }
+
+    public long getStartTimestampCurrentCounter() {
+        return startTimestampCurrentCounter;
+    }
+
+    public long getStartMonotonic() {
+        return startMonotonic;
+    }
+
+    public JniTime getStartTime() {
+        return startTime;
+    }
+    
+    public JniTime getEndTime() {
+        return endTime;
+    }
+
+    public JniTime getStartTimeNoAdjustement() {
+        return startTimeNoAdjustement;
+    }
+    
+    public HashMap<String, JniTracefile> getTracefilesMap() {
+        return tracefilesMap;
+    }        
+    
+    /**
+     * The timestamp of the last read event.<p>
+     * 
+     * Note : If no event is available, Long.MAX_VALUE is returned.
+     * 
+     * @return Time of the last event read
+     * 
+     * @see org.eclipse.linuxtools.lttng.jni.eclipse.linuxtools.lttng.jni.JniTime
+     */
+    public JniTime getCurrentEventTimestamp() {
+        JniTime returnedTime = null;
+        
+        // If no event were read or we reach the last event in the trace, 
+        //      currentEvent will be null
+        if (  currentEvent != null ) {
+            returnedTime = currentEvent.getEventTime();
+        }
+        else {
+            returnedTime = new JniTime(Long.MAX_VALUE);
+        }
+        return returnedTime;
+    }
+    
+    /**
+     * Pointer to the LttTrace C structure.<p>
+     * 
+     * The pointer should only be used <u>INTERNALY</u>, do not use unless you
+     * know what you are doing.
+     * 
+     * @return The actual (long converted) pointer or NULL.
+     * 
+     * @see org.eclipse.linuxtools.lttng.jni.eclipse.linuxtools.lttng.jni.Jni_C_Pointer
+     */
+    public Jni_C_Pointer getTracePtr() {
+        return thisTracePtr;
+    }        
+    
+    /**
+     * Return boolean value saying if the debug is enabled in LTT or not.<p>
+     * 
+     * Note : this need to be set at construction.
+     * 
+     * @return If the debug is set or not
+     */
+    public boolean isPrintingLttDebug() {
+        return printLttDebug;
+    }
+    
+    /**
+     * Print information for all the tracefiles associated with this trace.
+     * <u>Intended to debug</u><p>
+     * 
+     * This function will call Ltt to print, so information printed will be the
+     * one from the C structure, not the one populated in java.
+     * 
+     * @see org.eclipse.linuxtools.lttng.jni.eclipse.linuxtools.lttng.jni.JniTracefile
+     */
+    public void printAllTracefilesInformation() {
+        JniTracefile tracefile = null;
+
+        Iterator<String> iterator = tracefilesMap.keySet().iterator();
+        while (iterator.hasNext()) {
+            tracefile = tracefilesMap.get(iterator.next());
+            tracefile.printTracefileInformation();
+        }
+    }        
+        
+    /**
+     * Print information for this trace. 
+     * <u>Intended to debug</u><p>
+     * 
+     * This function will call Ltt to print, so information printed will be the
+     * one from the C structure, not the one populated in java.<p>
+     * <br>
+     * This function will not throw but will complain loudly if pointer is NULL
+     */
+    public void printTraceInformation() {
+
+        // If null pointer, print a warning!
+        if (thisTracePtr.getPointer() == NULL) {
+            printlnC("Pointer is NULL, cannot print. (printTraceInformation)");
+        } 
+        else {
+            ltt_printTrace( thisTracePtr.getPointer() );
+        }
+    }
+        
+    /**
+     * toString() method. 
+     * <u>Intended to debug</u><br>
+     * 
+     * @return Attributes of the object concatenated in String
+     */
+    @Override
+       public String toString() {
+        String returnData = "";
+        returnData += "tracepath                            : " + tracepath + "\n";
+        returnData += "cpuNumber                            : " + cpuNumber + "\n";
+        returnData += "archType                             : " + archType + "\n";
+        returnData += "archVariant                          : " + archVariant + "\n";
+        returnData += "archSize                             : " + archSize + "\n";
+        returnData += "lttMajorVersion                      : " + lttMajorVersion + "\n";
+        returnData += "lttMinorVersion                      : " + lttMinorVersion + "\n";
+        returnData += "flightRecorder                       : " + flightRecorder + "\n";
+        returnData += "freqScale                            : " + freqScale + "\n";
+        returnData += "startFreq                            : " + startFreq + "\n";
+        returnData += "startTimestampCurrentCounter         : " + startTimestampCurrentCounter + "\n";
+        returnData += "startMonotonic                       : " + startMonotonic + "\n";
+        returnData += "startTimeNoAdjustement               : " + startTimeNoAdjustement.getReferenceToString() + "\n";
+        returnData += "   seconds                           : " + startTimeNoAdjustement.getSeconds() + "\n";
+        returnData += "   nanoSeconds                       : " + startTimeNoAdjustement.getNanoSeconds() + "\n";
+        returnData += "startTime                            : " + startTime.getReferenceToString() + "\n";
+        returnData += "   seconds                           : " + startTime.getSeconds() + "\n";
+        returnData += "   nanoSeconds                       : " + startTime.getNanoSeconds() + "\n";
+        returnData += "endTime                              : " + endTime.getReferenceToString() + "\n";
+        returnData += "   seconds                           : " + endTime.getSeconds() + "\n";
+        returnData += "   nanoSeconds                       : " + endTime.getNanoSeconds() + "\n";
+        returnData += "tracefilesMap                        : " + tracefilesMap.keySet() + "\n";      // Hack to avoid ending up with tracefilesMap.toString()
+
+        return returnData;
+    }
+}
\ No newline at end of file
diff --git a/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/jni/JniTracefile.java b/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/jni/JniTracefile.java
new file mode 100644 (file)
index 0000000..e3a4927
--- /dev/null
@@ -0,0 +1,465 @@
+package org.eclipse.linuxtools.lttng.jni;
+/*******************************************************************************
+ * Copyright (c) 2009 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:
+ *   William Bourque (wbourque@gmail.com) - Initial API and implementation
+ *******************************************************************************/
+
+
+import java.util.HashMap;
+
+/**
+ * <b><u>JniTracefile</u></b>
+ * <p>
+ * A tracefile own an event of a certain type.<br>
+ * Provides access to the LttTracefile C structure in java.
+ * <p>
+ * Most important fields in the JniTracefile are :
+ * <ul>
+ * <li> a JniTracefile path (a tracefile <b>file</b> within a JniTrace directory)
+ * <li> a name (basically the name without the directory part)
+ * <li> a reference to a single event object
+ * <li> a HashMap of marker associated with this tracefile
+ * </ul>
+ */
+public final class JniTracefile extends Jni_C_Common {
+        
+    // Internal C pointer of the JniTracefile used in LTT
+    private Jni_C_Pointer thisTracefilePtr = new Jni_C_Pointer();
+    
+    // Reference to the parent trace
+    private JniTrace parentTrace = null;
+    
+    // Data we should populate from LTT
+    // Note that all type have been scaled up as there is no "unsigned" in java
+    // This might be a problem about "unsigned long" as there is no equivalent in java
+    private boolean isCpuOnline = false;
+    private String  tracefilePath = "";
+    private String  tracefileName = "";
+    private long    cpuNumber = 0;
+    private long    tid = 0;
+    private long    pgid = 0;
+    private long    creation = 0;
+    
+    // Internal C pointer for trace and marker
+    private Jni_C_Pointer tracePtr = null;
+    private Jni_C_Pointer markerDataPtr = null;
+    
+    private int     CFileDescriptor = 0;
+    private long    fileSize = 0;
+    private long    blocksNumber = 0;
+    private boolean isBytesOrderReversed = false;
+    private boolean isFloatWordOrdered = false;
+    private long    alignement = 0;
+    private long    bufferHeaderSize = 0;
+    private int     bitsOfCurrentTimestampCounter = 0;
+    private int     bitsOfEvent = 0;
+    private long    currentTimestampCounterMask = 0;
+    private long    currentTimestampCounterMaskNextBit = 0;
+    private long    eventsLost = 0;
+    private long    subBufferCorrupt = 0;
+    private JniEvent   currentEvent = null;
+    
+    // Internal C pointer for trace and marker
+    private Jni_C_Pointer bufferPtr = null;
+    
+    private long    bufferSize = 0;
+
+    // This map will hold markers_info owned by this tracefile
+    private HashMap<Integer, JniMarker> tracefileMarkersMap = null;        
+
+    // Native access functions
+    private native boolean  ltt_getIsCpuOnline(long tracefilePtr);
+    private native String   ltt_getTracefilepath(long tracefilePtr);
+    private native String   ltt_getTracefilename(long tracefilePtr);
+    private native long     ltt_getCpuNumber(long tracefilePtr);
+    private native long     ltt_getTid(long tracefilePtr);
+    private native long     ltt_getPgid(long tracefilePtr);
+    private native long     ltt_getCreation(long tracefilePtr);
+    private native long     ltt_getTracePtr(long tracefilePtr);
+    private native long     ltt_getMarkerDataPtr(long tracefilePtr);
+    private native int      ltt_getCFileDescriptor(long tracefilePtr);
+    private native long     ltt_getFileSize(long tracefilePtr);
+    private native long     ltt_getBlockNumber(long tracefilePtr);
+    private native boolean  ltt_getIsBytesOrderReversed(long tracefilePtr);
+    private native boolean  ltt_getIsFloatWordOrdered(long tracefilePtr);
+    private native long     ltt_getAlignement(long tracefilePtr);
+    private native long     ltt_getBufferHeaderSize(long tracefilePtr);
+    private native int      ltt_getBitsOfCurrentTimestampCounter(long tracefilePtr);
+    private native int      ltt_getBitsOfEvent(long tracefilePtr);
+    private native long     ltt_getCurrentTimestampCounterMask(long tracefilePtr);
+    private native long     ltt_getCurrentTimestampCounterMaskNextBit(long tracefilePtr);
+    private native long     ltt_getEventsLost(long tracefilePtr);
+    private native long     ltt_getSubBufferCorrupt(long tracefilePtr);
+    private native long     ltt_getEventPtr(long tracefilePtr);
+    private native long     ltt_getBufferPtr(long tracefilePtr);
+    private native long     ltt_getBufferSize(long tracefilePtr);
+
+    // Method to fill a map with marker object
+    private native void ltt_feedAllMarkers(long tracefilePtr);
+    
+    // Debug native function, ask LTT to print tracefile structure
+    private native void ltt_printTracefile(long tracefilePtr);
+    
+    static {
+        System.loadLibrary("lttvtraceread");
+    }
+        
+    /*
+     * Default constructor is forbidden
+     */
+    @SuppressWarnings("unused")
+    private JniTracefile() {
+    };
+
+    /**
+     * Copy constructor.<p>
+     * 
+     * @param oldTracefile      Reference to the JniTracefile you want to copy. 
+     */
+    public JniTracefile(JniTracefile oldTracefile) {
+        thisTracefilePtr    = oldTracefile.thisTracefilePtr;
+        parentTrace         = oldTracefile.parentTrace;
+        tracefileMarkersMap = oldTracefile.tracefileMarkersMap;
+        isCpuOnline         = oldTracefile.isCpuOnline;
+        tracefilePath       = oldTracefile.tracefilePath;
+        tracefileName       = oldTracefile.tracefileName;
+        cpuNumber           = oldTracefile.cpuNumber;
+        tid                 = oldTracefile.tid;
+        pgid                = oldTracefile.pgid;
+        creation            = oldTracefile.creation;
+        tracePtr            = oldTracefile.tracePtr;
+        markerDataPtr       = oldTracefile.markerDataPtr;
+        CFileDescriptor     = oldTracefile.CFileDescriptor;
+        fileSize            = oldTracefile.fileSize;
+        blocksNumber        = oldTracefile.blocksNumber;
+        isBytesOrderReversed = oldTracefile.isBytesOrderReversed;
+        isFloatWordOrdered  = oldTracefile.isFloatWordOrdered;
+        alignement          = oldTracefile.alignement;
+        bufferHeaderSize    = oldTracefile.bufferHeaderSize;
+        bitsOfCurrentTimestampCounter = oldTracefile.bitsOfCurrentTimestampCounter;
+        bitsOfEvent         = oldTracefile.bitsOfEvent;
+        currentTimestampCounterMask = oldTracefile.currentTimestampCounterMask;
+        currentTimestampCounterMaskNextBit = oldTracefile.currentTimestampCounterMaskNextBit;
+        eventsLost          = oldTracefile.eventsLost;
+        subBufferCorrupt    = oldTracefile.subBufferCorrupt;
+        currentEvent        = oldTracefile.currentEvent;
+        bufferPtr           = oldTracefile.bufferPtr;
+        bufferSize          = oldTracefile.bufferSize;
+    }
+
+    /**
+     * Constructor, using C pointer.<p>
+     * 
+     * @param newPtr  The pointer of an already opened LttTracefile C Structure
+     * 
+     * @exception JniException
+     * 
+     * @see org.eclipse.linuxtools.lttng.jni.eclipse.linuxtools.lttng.jni.JniTrace
+     * @see org.eclipse.linuxtools.lttng.jni.eclipse.linuxtools.lttng.jni.Jni_C_Pointer
+     */
+    public JniTracefile(Jni_C_Pointer newPtr, JniTrace newParentTrace) throws JniException {
+        thisTracefilePtr = newPtr;
+        parentTrace = newParentTrace;
+        tracefileMarkersMap = new HashMap<Integer, JniMarker>();
+
+        // Retrieve the trace file information and load the first event.
+        try {
+            populateTracefileInformation();
+        } catch (JniNoSuchEventException e) {
+            throw new JniTracefileWithoutEventException(
+                    "JniEvent constructor reported that no event of this type are usable. (Jaf_Tracefile)");
+        }
+    }        
+
+    /**
+     * Read the next event of this tracefile.<p>
+     * 
+     * Note : If the read succeed, the event will be populated.<p>
+     *      
+     * @return LTT read status, as defined in Jni_C_Common
+     * 
+     * @see org.eclipse.linuxtools.lttng.jni.eclipse.linuxtools.lttng.jni.Jni_C_Common
+     */
+    public int readNextEvent() {
+        return currentEvent.readNextEvent();
+    }        
+
+    /**
+     * Seek to the given time.<p>
+     * 
+     * Note : If the seek succeed, the event will be populated.
+     * 
+     * @param seekTime      The timestamp where to seek.
+     * 
+     * @return LTT read status, as defined in Jni_C_Common
+     * 
+     * @see org.eclipse.linuxtools.lttng.jni.eclipse.linuxtools.lttng.jni.Jni_C_Common
+     */
+    public int seekToTime(JniTime seekTime) {
+        return currentEvent.seekToTime(seekTime);
+    }
+
+    /* 
+     * This function populates the tracefile data with data from LTT
+     * 
+     * @throws JniException
+     */
+    private void populateTracefileInformation() throws JniException {
+        if (thisTracefilePtr.getPointer() == NULL) {
+            throw new JniTracefileException(
+                    "Pointer is NULL, trace closed? (populateTracefileInformation)");
+        }
+
+        isCpuOnline = ltt_getIsCpuOnline( thisTracefilePtr.getPointer() );
+        tracefilePath = ltt_getTracefilepath( thisTracefilePtr.getPointer() );
+        tracefileName = ltt_getTracefilename( thisTracefilePtr.getPointer() );
+        cpuNumber = ltt_getCpuNumber( thisTracefilePtr.getPointer() );
+        tid = ltt_getTid( thisTracefilePtr.getPointer() );
+        pgid = ltt_getPgid( thisTracefilePtr.getPointer() );
+        creation = ltt_getCreation( thisTracefilePtr.getPointer() );
+        tracePtr = new Jni_C_Pointer(ltt_getTracePtr( thisTracefilePtr.getPointer()) );
+        markerDataPtr = new Jni_C_Pointer(ltt_getMarkerDataPtr( thisTracefilePtr.getPointer()) );
+        CFileDescriptor = ltt_getCFileDescriptor( thisTracefilePtr.getPointer() );
+        fileSize = ltt_getFileSize( thisTracefilePtr.getPointer() );
+        blocksNumber = ltt_getBlockNumber( thisTracefilePtr.getPointer() );
+        isBytesOrderReversed = ltt_getIsBytesOrderReversed( thisTracefilePtr.getPointer() );
+        isFloatWordOrdered = ltt_getIsFloatWordOrdered( thisTracefilePtr.getPointer() );
+        alignement = ltt_getAlignement( thisTracefilePtr.getPointer() );
+        bufferHeaderSize = ltt_getBufferHeaderSize( thisTracefilePtr.getPointer() );
+        bitsOfCurrentTimestampCounter = ltt_getBitsOfCurrentTimestampCounter( thisTracefilePtr.getPointer() );
+        bitsOfEvent = ltt_getBitsOfEvent( thisTracefilePtr.getPointer() );
+        currentTimestampCounterMask = ltt_getCurrentTimestampCounterMask( thisTracefilePtr.getPointer() );
+        currentTimestampCounterMaskNextBit = ltt_getCurrentTimestampCounterMaskNextBit( thisTracefilePtr.getPointer() );
+        eventsLost = ltt_getEventsLost( thisTracefilePtr.getPointer() );
+        subBufferCorrupt = ltt_getSubBufferCorrupt( thisTracefilePtr.getPointer() );
+        bufferPtr = new Jni_C_Pointer(ltt_getBufferPtr( thisTracefilePtr.getPointer()) );
+        bufferSize = ltt_getBufferSize( thisTracefilePtr.getPointer() );
+
+        // To fill the map is a bit different
+        ltt_feedAllMarkers( thisTracefilePtr.getPointer() );
+
+        Jni_C_Pointer tmpEventPointer = new Jni_C_Pointer(ltt_getEventPtr(thisTracefilePtr.getPointer()));
+        currentEvent = new JniEvent(tmpEventPointer , tracefileMarkersMap, this);
+    }        
+    
+    /* 
+     * Fills a map of all the markers associated with this tracefile.
+     * 
+     * Note: This function is called from C and there is no way to propagate
+     * exception back to the caller without crashing JNI. Therefore, it MUST
+     * catch all exceptions.
+     * 
+     * @param markerId          Id of the marker (int)
+     * @param markerInfoPtr     C Pointer to a marker_info C structure 
+     */
+    @SuppressWarnings("unused")
+    private void addMarkersFromC(int markerId, long markerInfoPtr) {
+        // Create a new tracefile object and insert it in the map
+        // the tracefile fill itself with LTT data while being constructed
+        try {
+            JniMarker newMarker = new JniMarker( new Jni_C_Pointer(markerInfoPtr) );
+
+            tracefileMarkersMap.put(markerId, newMarker);
+        } catch (Exception e) {
+            printlnC("Failed to add marker to tracefileMarkersMap!(addMarkersFromC)\n\tException raised : " + e.toString());
+        }
+    }
+    
+    // Access to class variable. Most of them doesn't have setter
+    public boolean getIsCpuOnline() {
+        return isCpuOnline;
+    }
+    
+    public String getTracefilePath() {
+        return tracefilePath;
+    }
+
+    public String getTracefileName() {
+        return tracefileName;
+    }
+
+    public long getCpuNumber() {
+        return cpuNumber;
+    }
+
+    public long getTid() {
+        return tid;
+    }
+
+    public long getPgid() {
+        return pgid;
+    }
+
+    public long getCreation() {
+        return creation;
+    }
+
+    public Jni_C_Pointer getTracePtr() {
+        return tracePtr;
+    }
+
+    public Jni_C_Pointer getMarkerDataPtr() {
+        return markerDataPtr;
+    }
+
+    public int getCFileDescriptor() {
+        return CFileDescriptor;
+    }
+
+    public long getFileSize() {
+        return fileSize;
+    }
+
+    public long getBlocksNumber() {
+        return blocksNumber;
+    }
+
+    public boolean getIsBytesOrderReversed() {
+        return isBytesOrderReversed;
+    }
+
+    public boolean getIsFloatWordOrdered() {
+        return isFloatWordOrdered;
+    }
+
+    public long getAlignement() {
+        return alignement;
+    }
+
+    public long getBufferHeaderSize() {
+        return bufferHeaderSize;
+    }
+
+    public int getBitsOfCurrentTimestampCounter() {
+        return bitsOfCurrentTimestampCounter;
+    }
+
+    public int getBitsOfEvent() {
+        return bitsOfEvent;
+    }
+
+    public long getCurrentTimestampCounterMask() {
+        return currentTimestampCounterMask;
+    }
+
+    public long getCurrentTimestampCounterMaskNextBit() {
+        return currentTimestampCounterMaskNextBit;
+    }
+
+    public long getEventsLost() {
+        return eventsLost;
+    }
+
+    public long getSubBufferCorrupt() {
+        return subBufferCorrupt;
+    }
+
+    public JniEvent getCurrentEvent() {
+        return currentEvent;
+    }
+
+    public Jni_C_Pointer getBufferPtr() {
+        return bufferPtr;
+    }
+
+    public long getBufferSize() {
+        return bufferSize;
+    }
+
+    public HashMap<Integer, JniMarker> getTracefileMarkersMap() {
+        return tracefileMarkersMap;
+    }
+
+    /**
+     * Parent trace of this tracefile.<p>
+     *
+     * @return The parent trace
+     * 
+     * @see org.eclipse.linuxtools.lttng.jni.eclipse.linuxtools.lttng.jni.JniTrace
+     */
+    public JniTrace getParentTrace() {
+        return parentTrace;
+    }
+    
+    /**
+     * Pointer to the LttTracefile C structure<p>
+     * 
+     * The pointer should only be used <u>INTERNALY</u>, do not use unless you
+     * know what you are doing.<p>
+     * 
+     * @return The actual (long converted) pointer or NULL.
+     * 
+     * @see org.eclipse.linuxtools.lttng.jni.eclipse.linuxtools.lttng.jni.Jni_C_Pointer
+     */
+    public Jni_C_Pointer getTracefilePtr() {
+        return thisTracefilePtr;
+    }
+    
+    /**
+     * Print information for this tracefile. 
+     * <u>Intended to debug</u><p>
+     * 
+     * This function will call Ltt to print, so information printed will be the
+     * one from the C structure, not the one populated in java.<p>
+     * 
+     * This function will not throw but will complain loudly if pointer is NULL.
+     */
+    public void printTracefileInformation() {
+
+        // If null pointer, print a warning!
+        if (thisTracefilePtr.getPointer() == NULL) {
+            printlnC("Pointer is NULL, cannot print. (printTracefileInformation)");
+        } 
+        else {
+            ltt_printTracefile( thisTracefilePtr.getPointer() );
+        }
+    }
+    
+    /**
+     * toString() method. 
+     * <u>Intended to debug</u><p>
+     * 
+     * @return Attributes of the object concatenated in String
+     */
+       @Override
+       public String toString() {
+        String returnData = "";
+                
+        returnData += "isCpuOnline                        : " + isCpuOnline + "\n";
+        returnData += "tracefilePath                      : " + tracefilePath + "\n";
+        returnData += "tracefileName                      : " + tracefileName + "\n";
+        returnData += "cpuNumber                          : " + cpuNumber + "\n";
+        returnData += "tid                                : " + tid + "\n";
+        returnData += "pgid                               : " + pgid + "\n";
+        returnData += "creation                           : " + creation + "\n";
+        returnData += "tracePtr                           : " + tracePtr + "\n";
+        returnData += "markerDataPtr                      : " + markerDataPtr + "\n";
+        returnData += "CFileDescriptor                    : " + CFileDescriptor + "\n";
+        returnData += "fileSize                           : " + fileSize + "\n";
+        returnData += "blocksNumber                       : " + blocksNumber + "\n";
+        returnData += "isBytesOrderReversed               : " + isBytesOrderReversed + "\n";
+        returnData += "isFloatWordOrdered                 : " + isFloatWordOrdered + "\n";
+        returnData += "alignement                         : " + alignement + "\n";
+        returnData += "bufferHeaderSize                   : " + bufferHeaderSize + "\n";
+        returnData += "bitsOfCurrentTimestampCounter      : " + bitsOfCurrentTimestampCounter + "\n";
+        returnData += "bitsOfEvent                        : " + bitsOfEvent + "\n";
+        returnData += "currentTimestampCounterMask        : " + currentTimestampCounterMask + "\n";
+        returnData += "currentTimestampCounterMaskNextBit : " + currentTimestampCounterMaskNextBit + "\n";
+        returnData += "eventsLost                         : " + eventsLost + "\n";
+        returnData += "subBufferCorrupt                   : " + subBufferCorrupt + "\n";
+        returnData += "currentEvent                       : " + currentEvent.getReferenceToString() + "\n"; // Hack to avoid ending up with event.toString()
+        returnData += "bufferPtr                          : " + bufferPtr + "\n";
+        returnData += "bufferSize                         : " + bufferSize + "\n";
+        returnData += "tracefileMarkersMap                : " + tracefileMarkersMap.keySet() + "\n"; // Hack to avoid ending up with tracefileMarkersMap.toString()
+
+        return returnData;
+    }
+}
+
diff --git a/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/jni/Jni_C_Common.java b/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/jni/Jni_C_Common.java
new file mode 100644 (file)
index 0000000..2390460
--- /dev/null
@@ -0,0 +1,75 @@
+package org.eclipse.linuxtools.lttng.jni;
+/*******************************************************************************
+ * Copyright (c) 2009 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:
+ *   William Bourque (wbourque@gmail.com) - Initial API and implementation
+ *******************************************************************************/
+
+
+/**
+ * <b><u>Jni_C_Common</u></b>
+ * <p>
+ * Common constants and methods that should be shared between JNI objects
+ */
+public abstract class Jni_C_Common {
+    
+    // Needed for native types
+    public static final int NULL = 0;
+
+    // C errno correspondance. Used to interpret LTT return value
+    public static final int EOK    =  0;
+    public static final int EPERM  =  1;
+    public static final int ERANGE = 34;
+
+    // Timestamps are in nanoseconds, this const ease up the math
+    public static final long NANO = 1000000000;
+
+    // Native console printing function
+    private native void ltt_printC(String string_to_print);
+
+    // Load LTTV library (order is important)
+    static {
+        System.loadLibrary("lttvtraceread");
+    }
+
+    /**
+     * Java-side console printing function.<p>
+     * 
+     * Call the C printing function to make sure all printing happen on the same side.
+     * 
+     * @param msg   The string to print in C.
+     */
+    public void printC(String msg) {
+        // Need to escape "%" for C printf 
+        msg = msg.replaceAll("%", "%%");
+        ltt_printC(msg);
+    }
+
+    /**
+     * Java-side console printing function that add carriage return. <p>
+     * 
+     * Call the C printing function to make sure all printing happen on the same side.
+     * 
+     * @param msg   The string to print in C.
+     */
+    public void printlnC(String msg) {
+        printC(msg + "\n");
+    }
+
+    /**
+     * "Alternate" .toString()<p>
+     * 
+     * Simulates the way Java Object implements "toString()"
+     * 
+     * @return The Java hashed UID of the object (i.e. : NAME@HASH)
+     */
+    public String getReferenceToString() {
+        return this.getClass().getName() + "@" + Integer.toHexString(this.hashCode());
+    }
+}
\ No newline at end of file
diff --git a/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/jni/Jni_C_Pointer.java b/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/jni/Jni_C_Pointer.java
new file mode 100644 (file)
index 0000000..7cfec13
--- /dev/null
@@ -0,0 +1,94 @@
+package org.eclipse.linuxtools.lttng.jni;
+
+
+/**
+ * <b><u>Jni_C_Pointer</u></b>
+ * <p>
+ * Class pointer to handle properly "C pointer" <p>
+ * 
+ * Can transparently handle pointer of 32 or 64 bits.
+ */
+public class Jni_C_Pointer extends Jni_C_Common {
+
+    private long ptr = NULL;
+    private boolean isLong = true;
+    
+    /**
+     * Default constructor.<p>
+     * 
+     * Note : Pointer will be set to a 64bits "NULL".
+     */
+    public Jni_C_Pointer() {
+        ptr  = NULL;
+    }
+    
+    /**
+     * Constructor with parameters for 64bits pointers.
+     * 
+     * @param newPtr    long-converted (64 bits) C pointer.
+     */
+    public Jni_C_Pointer(long newPtr) {
+        ptr = newPtr;
+        isLong = true; 
+    }
+    
+    /**
+     * Constructor with parameters for 32bits pointers.
+     * 
+     * @param newPtr    int-converted (32 bits) C pointer.
+     */
+    public Jni_C_Pointer(int newPtr) {
+        ptr = (long)newPtr;
+        isLong = false; 
+    }
+    
+    /**
+     * Get the current pointer.
+     * 
+     * @return  The current pointer, in long.
+     */
+    public long getPointer() {
+        return ptr;
+    }
+    
+    /**
+     * Set the pointer, as a 64bits pointer.
+     * 
+     * @param newPtr    long-converted (64 bits) C pointer.
+     */
+    public void setPointer(long newPtr) {
+        ptr = newPtr;
+        isLong = true;
+    }
+    
+    /**
+     * Set the pointer, as a 64bits pointer.
+     * 
+     * @param newPtr    int-converted (32 bits) C pointer.
+     */
+    public void setPointer(int newPtr) {
+        ptr = newPtr;
+        isLong = false;
+    }
+
+    /**
+     * toString() method. <p>
+     * 
+     * Convert the pointer to a nice looking int/long hexadecimal format. 
+     * 
+     * @return Attributes of the object concatenated in String
+     */
+    @Override
+    public String toString() {
+        String returnData = "0x";
+
+        if (isLong == true) {
+            returnData += Long.toHexString(ptr);
+        }
+        else {
+            returnData += Integer.toHexString((int) ptr);
+        }
+
+        return returnData;
+    }
+}
diff --git a/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/IStateDataRequestListener.java b/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/IStateDataRequestListener.java
new file mode 100644 (file)
index 0000000..5cfe500
--- /dev/null
@@ -0,0 +1,38 @@
+/*******************************************************************************
+ * Copyright (c) 2009 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:
+ *   Alvaro Sanchez-Leon (alvsan09@gmail.com) - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.linuxtools.lttng.state;
+
+
+/**
+ * Interface to be used to receive notification of Processing start and
+ * completed
+ * 
+ * @author alvaro
+ * 
+ */
+public interface IStateDataRequestListener {
+       // ========================================================================
+       // Methods
+       // ========================================================================
+       
+       /**
+        * 
+        * @param request
+        * @return
+        */
+       public void processingStarted(RequestStartedSignal request);
+
+       /**
+        * @param signal
+        */
+       public void processingCompleted(RequestCompletedSignal signal);
+}
diff --git a/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/LttngStateInputRef.java b/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/LttngStateInputRef.java
new file mode 100644 (file)
index 0000000..2bb7bce
--- /dev/null
@@ -0,0 +1,105 @@
+/*******************************************************************************
+ * Copyright (c) 2009 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:
+ *   Alvaro Sanchez-Leon (alvsan09@gmail.com) - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.linuxtools.lttng.state;
+
+import org.eclipse.linuxtools.lttng.state.model.ILttngStateInputRef;
+import org.eclipse.linuxtools.lttng.trace.LTTngTextTrace;
+import org.eclipse.linuxtools.lttng.trace.LTTngTrace;
+import org.eclipse.linuxtools.tmf.event.TmfTimeRange;
+import org.eclipse.linuxtools.tmf.trace.TmfTrace;
+
+/**
+ * Interface data provider to the state.model package
+ * 
+ * @author alvaro
+ * 
+ */
+public class LttngStateInputRef implements ILttngStateInputRef {
+       
+       private int cpuNumber = -1;
+       
+       // ========================================================================
+       // Table data
+       // =======================================================================
+       TmfTrace log = null;
+
+       // ========================================================================
+       // Constructor
+       // ========================================================================
+       LttngStateInputRef(TmfTrace log) {
+               this.log = log;
+               
+               if ( log instanceof LTTngTrace) {
+                       cpuNumber = ((LTTngTrace)log).getCpuNumber();
+               }
+               else if ( log instanceof LTTngTextTrace) {
+                       cpuNumber = ((LTTngTextTrace)log).getCpuNumber();
+               }
+       }
+
+       // ========================================================================
+       // Methods
+       // =======================================================================
+       /*
+        * (non-Javadoc)
+        * 
+        * @seeorg.eclipse.linuxtools.lttng.ui.state.model.ILttngStateInputRef#
+        * getNumberOfCpus()
+        */
+       // @Override
+       public int getNumberOfCpus() {
+               return cpuNumber;
+       }
+
+       /*
+        * (non-Javadoc)
+        * 
+        * @seeorg.eclipse.linuxtools.lttng.ui.state.model.ILttngStateInputRef#
+        * getTraceTimeWindow()
+        */
+       // @Override
+       public TmfTimeRange getTraceTimeWindow() {
+               if (log != null) {
+                       return log.getTimeRange();
+                       
+               }
+               return null;
+       }
+
+       /*
+        * (non-Javadoc)
+        * 
+        * @see
+        * org.eclipse.linuxtools.lttng.state.model.ILttngStateInputRef#getTraceId()
+        */
+       public String getTraceId() {
+               if (log != null) {
+                       return log.getName();
+               }
+               return null;
+       }
+
+       /*
+        * (non-Javadoc)
+        * 
+        * @seeorg.eclipse.linuxtools.lttng.state.model.ILttngStateInputRef#
+        * getExperimentTimeWindow()
+        */
+       public TmfTimeRange getExperimentTimeWindow() {
+               // TODO Using the Trace time window temporarily, we need to replace with
+               // the Experiment level
+               if (log != null) {
+                       return log.getTimeRange();
+               }
+               return null;
+       }
+}
diff --git a/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/RequestCompletedSignal.java b/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/RequestCompletedSignal.java
new file mode 100644 (file)
index 0000000..c270b00
--- /dev/null
@@ -0,0 +1,18 @@
+package org.eclipse.linuxtools.lttng.state;
+
+import org.eclipse.linuxtools.tmf.signal.TmfSignal;
+
+public class RequestCompletedSignal extends TmfSignal {
+
+       StateDataRequest request;
+
+       public RequestCompletedSignal(StateDataRequest request) {
+               super(request);
+               this.request = request;
+       }
+
+       public StateDataRequest getRequest() {
+               return request;
+       }
+
+}
diff --git a/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/RequestStartedSignal.java b/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/RequestStartedSignal.java
new file mode 100644 (file)
index 0000000..1372f09
--- /dev/null
@@ -0,0 +1,18 @@
+package org.eclipse.linuxtools.lttng.state;
+
+import org.eclipse.linuxtools.tmf.signal.TmfSignal;
+
+public class RequestStartedSignal extends TmfSignal {
+
+       StateDataRequest request;
+
+       public RequestStartedSignal(StateDataRequest request) {
+               super(request);
+               this.request = request;
+       }
+
+       public StateDataRequest getRequest() {
+               return request;
+       }
+
+}
index 667426ef311fd8c0520b9ea8583deb3aaef3246e..62eb5be5bfa558fe77ec23440d203219de9095c7 100644 (file)
  *******************************************************************************/
 package org.eclipse.linuxtools.lttng.state;
 
+import java.util.Vector;
+
+import org.eclipse.linuxtools.tmf.event.TmfEvent;
+import org.eclipse.linuxtools.tmf.event.TmfTimeRange;
+import org.eclipse.linuxtools.tmf.request.TmfDataRequest;
+import org.eclipse.linuxtools.tmf.signal.TmfSignalManager;
+import org.eclipse.linuxtools.tmf.trace.TmfExperiment;
 
 /**
  * This class is an extension of Data Request which includes specific references
@@ -19,202 +26,163 @@ package org.eclipse.linuxtools.lttng.state;
  * @author alvaro
  * 
  */
-public class StateDataRequest {
-       // //
+public class StateDataRequest extends TmfDataRequest<TmfEvent> {
        // ========================================================================
-       // // Data
-       // //
+       // Data
        // =======================================================================
-       // private Vector<IStateDataRequestListener> listeners = new
-       // Vector<IStateDataRequestListener>();
-       // private String transactionId = ""; /* optional user's attribute */
-       // private StateManager manager = null;
-       // private long numOfEvents = 0;
-       // private boolean broadcast = false;
-       // private boolean clearDataInd = false;
-       // //
+       private Vector<IStateDataRequestListener> listeners = new Vector<IStateDataRequestListener>();
+       private String transactionId = ""; /* optional user's attribute */
+       private StateManager manager = null;
+       private long numOfEvents = 0;
+       private boolean broadcast = false;
+       private boolean clearDataInd = false;
        // ========================================================================
-       // // Constructors
-       // //
+       // Constructors
        // =======================================================================
-       // /**
-       // * @param range
-       // * @param offset
-       // * @param nbEvents
-       // * @param maxBlockSize
-       // * @param listener
-       // */
-       // public StateDataRequest(TmfTimeRange range, long offset, int nbEvents,
-       // int maxBlockSize, IStateDataRequestListener listener,
-       // StateManager manager) {
-       //              
-       // super(range, nbEvents, maxBlockSize);
-       // //super(0, nbEvents, maxBlockSize);
-       // this.manager = manager;
-       // if (listener != null && !listeners.contains(listener)) {
-       // listeners.add(listener);
-       // }
-       // }
-       //
-       // /**
-       // * @param range
-       // * @param offset
-       // * @param nbEvents
-       // * @param maxBlockSize
-       // * @param listener
-       // * @param transactionID
-       // * optional use by user application
-       // */
-       // public StateDataRequest(TmfTimeRange range, long offset, int nbEvents,
-       // int maxBlockSize, IStateDataRequestListener listener,
-       // String transactionID, StateManager manager) {
-       //
-       // this(range, offset, nbEvents, maxBlockSize, listener, manager);
-       // this.transactionId = transactionID;
-       // }
-       //
-       // //
+       /**
+        * @param range
+        * @param offset
+        * @param nbEvents
+        * @param maxBlockSize
+        * @param listener
+        */
+       public StateDataRequest(TmfTimeRange range, long offset, int nbEvents,
+                       int maxBlockSize, IStateDataRequestListener listener,
+                       StateManager manager) {
+               
+               super(range, nbEvents, maxBlockSize);
+               //super(0, nbEvents, maxBlockSize);
+               this.manager = manager;
+               if (listener != null && !listeners.contains(listener)) {
+                       listeners.add(listener);
+               }
+       }
+
+       /**
+        * @param range
+        * @param offset
+        * @param nbEvents
+        * @param maxBlockSize
+        * @param listener
+        * @param transactionID
+        *            optional use by user application
+        */
+       public StateDataRequest(TmfTimeRange range, long offset, int nbEvents,
+                       int maxBlockSize, IStateDataRequestListener listener,
+                       String transactionID, StateManager manager) {
+
+               this(range, offset, nbEvents, maxBlockSize, listener, manager);
+               this.transactionId = transactionID;
+       }
+
        // ========================================================================
-       // // Methods
-       // //
+       // Methods
        // =======================================================================
-       //
-       // /**
-       // * Trigger the start to process this request right after the notification
-       // to
-       // * the interested listeners
-       // *
-       // * @param experiment
-       // * @param broadcast
-       // * true: All views, false: only to registered listeners
-       // */
-       // public void startRequestInd(TmfExperiment experiment, boolean broadcast,
-       // boolean waitForCompletion) {
-       // if (broadcast) {
-       // // Notify all state views.
-       // this.broadcast = broadcast;
-       // // TmfSignalManager.dispatchSignal(new RequestStartedSignal(this));
-       // }
-       // // else {
-       // // // Notify specific state views
-       // // for (IStateDataRequestListener listener : listeners) {
-       // // listener.processingStarted(new RequestStartedSignal(this));
-       // // }
-       // // }
-       //
-       // // trigger the start to process this request
-       // experiment.processRequest(this, waitForCompletion);
-       // }
-       //
-       // /**
-       // * to be called by the handleCompletion in superclass method, notifies the
-       // * interested listeners. i.e. if the request start indicated broadcast,
-       // the
-       // * completion will also be broadcasted otherwise only registered listeners
-       // * will be notified.
-       // */
-       // public void notifyCompletion() {
-       // if (broadcast) {
-       // // Notify all state views.
-       // TraceDebug.debug("request completed" + this.toString());
-       // TmfSignalManager.dispatchSignal(new RequestCompletedSignal(this));
-       // } else {
-       // // Notify specific state views
-       // for (IStateDataRequestListener listener : listeners) {
-       // listener.processingCompleted(new RequestCompletedSignal(this));
-       // }
-       // }
-       // }
-       //
-       // public void notifyStarting() {
-       // if (broadcast) {
-       // // Notify all state views.
-       // TraceDebug.debug("request started" + this.toString());
-       // TmfSignalManager.dispatchSignal(new RequestStartedSignal(this));
-       // } else {
-       // for (IStateDataRequestListener listener : listeners) {
-       // listener.processingStarted(new RequestStartedSignal(this));
-       // }
-       // }
-       // }
-       //
-       // public String getTransactionId() {
-       // return transactionId;
-       // }
-       //
-       // public StateManager getStateManager() {
-       // return this.manager;
-       // }
-       //
-       // // public IStateDataRequestListener getListener() {
-       // // return listener;
-       // // }
-       //
-       // public void addListener(IStateDataRequestListener listener) {
-       // if (!listeners.contains(listener)) {
-       // listeners.add(listener);
-       // }
-       // }
-       //
-       // public void removeListener(IStateDataRequestListener listener) {
-       // if (listener != null) {
-       // listeners.remove(listener);
-       // }
-       // }
-       //
-       // /**
-       // * @param numOfEvents
-       // * the numOfEvents to set
-       // */
-       // public void setNumOfEvents(long numOfEvents) {
-       // this.numOfEvents = numOfEvents;
-       // }
-       //
-       // /**
-       // * @return the numOfEvents
-       // */
-       // public long getNumOfEvents() {
-       // return numOfEvents;
-       // }
-       //
-       // /**
-       // * @param clearAllData
-       // * indicates the need to clear all previous data e.g. a new
-       // * experiment selection
-       // */
-       // public void setclearDataInd(boolean clearAllData) {
-       // this.clearDataInd = clearAllData;
-       // }
-       //
-       // /**
-       // * Returns indication - clearing of all existing data model is required
-       // e.g
-       // * from the selection of a new experiment
-       // *
-       // * @return
-       // */
-       // public boolean isclearDataInd() {
-       // return clearDataInd;
-       // }
-       //
-       // /**
-       // * Compare the time range with a Data Request.
-       // *
-       // * @param trange
-       // * @return
-       // */
-       // public boolean equalTime(StateDataRequest otherRequest) {
-       // TmfTimeRange trange = otherRequest.getRange();
-       // TmfTimeRange myTimeRange = getRange();
-       // TmfTimestamp myStartTime = myTimeRange.getStartTime();
-       // TmfTimestamp myEndTime = myTimeRange.getEndTime();
-       //              
-       // if (myStartTime.equals(trange.getStartTime())) {
-       // if (myEndTime.equals(trange.getEndTime())) {
-       // return true;
-       // }
-       // }
-       //              
-       // return false;
+
+       /**
+        * Trigger the start to process this request right after the notification to
+        * the interested listeners
+        * 
+        * @param experiment
+        * @param broadcast
+        *            true: All views, false: only to registered listeners
+        */
+       public void startRequestInd(TmfExperiment experiment, boolean broadcast,
+                       boolean waitForCompletion) {
+               if (broadcast) {
+                       // Notify all state views.
+                       this.broadcast = broadcast;
+                       TmfSignalManager.dispatchSignal(new RequestStartedSignal(this));
+               } else {
+                       // Notify specific state views
+                       for (IStateDataRequestListener listener : listeners) {
+                               listener.processingStarted(new RequestStartedSignal(this));
+                       }
+               }
+
+               // trigger the start to process this request
+               experiment.processRequest(this, waitForCompletion);
+       }
+
+       /**
+        * to be called by the handleCompletion in superclass method, notifies the
+        * interested listeners. i.e. if the request start indicated broadcast, the
+        * completion will also be broadcasted otherwise only registered listeners
+        * will be notified.
+        */
+       public void notifyCompletion() {
+               if (broadcast) {
+                       // Notify all state views.
+                       TmfSignalManager.dispatchSignal(new RequestCompletedSignal(this));
+               } else {
+                       // Notify specific state views
+                       for (IStateDataRequestListener listener : listeners) {
+                               listener.processingCompleted(new RequestCompletedSignal(this));
+                       }
+               }
+       }
+
+       public void notifyStarting() {
+               for (IStateDataRequestListener listener : listeners) {
+                       listener.processingStarted(new RequestStartedSignal(this));
+               }
+       }
+
+       public String getTransactionId() {
+               return transactionId;
+       }
+
+       public StateManager getStateManager() {
+               return this.manager;
+       }
+
+       // public IStateDataRequestListener getListener() {
+       // return listener;
        // }
+
+       public void addListener(IStateDataRequestListener listener) {
+               if (!listeners.contains(listener)) {
+                       listeners.add(listener);
+               }
+       }
+
+       public void removeListener(IStateDataRequestListener listener) {
+               if (listener != null) {
+                       listeners.remove(listener);
+               }
+       }
+
+       /**
+        * @param numOfEvents
+        *            the numOfEvents to set
+        */
+       public void setNumOfEvents(long numOfEvents) {
+               this.numOfEvents = numOfEvents;
+       }
+
+       /**
+        * @return the numOfEvents
+        */
+       public long getNumOfEvents() {
+               return numOfEvents;
+       }
+
+       /**
+        * @param clearAllData
+        *            indicates the need to clear all previous data e.g. a new
+        *            experiment selection
+        */
+       public void setclearDataInd(boolean clearAllData) {
+               this.clearDataInd = clearAllData;
+       }
+
+       /**
+        * Returns indication - clearing of all existing data model is required e.g
+        * from the selection of a new experiment
+        * 
+        * @return
+        */
+       public boolean isclearDataInd() {
+               return clearDataInd;
+       }
 }
diff --git a/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/StateManager.java b/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/StateManager.java
new file mode 100644 (file)
index 0000000..bfa4bf2
--- /dev/null
@@ -0,0 +1,587 @@
+/*******************************************************************************
+ * Copyright (c) 2009 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:
+ *   Alvaro Sanchez-Leon (alvsan09@gmail.com) - Initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.linuxtools.lttng.state;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Observable;
+import java.util.Set;
+import java.util.Vector;
+
+import org.eclipse.linuxtools.lttng.TraceDebug;
+import org.eclipse.linuxtools.lttng.event.LttngTimestamp;
+import org.eclipse.linuxtools.lttng.state.evProcessor.AbsEventProcessorFactory;
+import org.eclipse.linuxtools.lttng.state.evProcessor.EventProcessorProxy;
+import org.eclipse.linuxtools.lttng.state.evProcessor.IEventProcessing;
+import org.eclipse.linuxtools.lttng.state.model.ILttngStateInputRef;
+import org.eclipse.linuxtools.lttng.state.model.LttngTraceState;
+import org.eclipse.linuxtools.lttng.state.model.StateModelFactory;
+import org.eclipse.linuxtools.tmf.event.TmfEvent;
+import org.eclipse.linuxtools.tmf.event.TmfTimeRange;
+import org.eclipse.linuxtools.tmf.event.TmfTimestamp;
+import org.eclipse.linuxtools.tmf.request.TmfDataRequest;
+import org.eclipse.linuxtools.tmf.trace.TmfExperiment;
+import org.eclipse.linuxtools.tmf.trace.TmfTrace;
+import org.eclipse.linuxtools.tmf.trace.TmfTraceCheckpoint;
+
+/**
+ * 
+ * @author alvaro
+ * 
+ */
+public class StateManager extends Observable {
+
+       private static final long LTTNG_STATE_SAVE_INTERVAL = 5000000L;
+
+       // These are used in the building of the data request.
+       private static final long DEFAULT_OFFSET = 0L;
+       private static final int DEFAULT_CHUNK = 1;
+
+       // ========================================================================
+       // Data
+       // =======================================================================
+       private TmfExperiment fExperiment = null;
+       private TmfTrace fEventLog = null;
+       private StateStacksHandler stateIn = null;
+       private Long eventCount = 0L;
+
+       private HashMap<Long, LttngTraceState> stateCheckpointsList = new HashMap<Long, LttngTraceState>();
+       private Vector<TmfTraceCheckpoint> timestampCheckpointsList = new Vector<TmfTraceCheckpoint>();
+
+       // ========================================================================
+       // Constructor
+       // =======================================================================
+
+       // /**
+       // * Default constructor
+       // * <p>
+       // * Instanciate its own StateStacksHandler.
+       // *
+       // */
+       // public StateManager() {
+       // this.stateIn = new StateStacksHandler();
+       // }
+
+       /**
+        * Constructor with parameter
+        * <p>
+        * 
+        * @param stateInputHandler
+        *            A valid StateStacksHandler
+        * 
+        */
+       public StateManager(StateStacksHandler stateInputHandler) {
+               this.stateIn = stateInputHandler;
+       }
+
+       // /**
+       // * Copy constructor
+       // * <p>
+       // *
+       // * @param oldStateManager
+       // * the StateManager we want to copy
+       // *
+       // */
+       // public StateManager(StateManager oldStateManager) {
+       // fEventLog = oldStateManager.fEventLog;
+       // stateIn = oldStateManager.stateIn;
+       // trace = oldStateManager.trace;
+       // eventCount = oldStateManager.eventCount;
+       //
+       // stateCheckpointsList = oldStateManager.stateCheckpointsList;
+       // timestampCheckpointsList = oldStateManager.timestampCheckpointsList;
+       // }
+
+       // ========================================================================
+       // Methods
+       // =======================================================================
+       /**
+        * A new Experiment or trace selected
+        * @param experiment
+        * @param clearPreviousData
+        */
+       public void setTraceSelection(TmfExperiment experiment,
+                       boolean clearPreviousData) {
+               // New log in use, read all events and build state transition stack
+               if (experiment != null) {
+                       if (fExperiment != null && fExperiment != experiment) {
+                               this.fExperiment.dispose();
+                       }
+
+                       this.fExperiment = experiment;
+
+                       // if (fEventLog != null) {
+                       // this.fEventLog.dispose();
+                       // }
+                       
+                       this.fEventLog = (TmfTrace)experiment.getTraces()[0];
+                       try {
+                               stateIn.init(fEventLog);
+                       } catch (LttngStateException e) {
+                               e.printStackTrace();
+                       }
+
+                       // Restart count and collections
+                       eventCount = 0L;
+                       stateCheckpointsList.clear();
+                       timestampCheckpointsList.clear();
+
+                       // Obtain a dataRequest to pass to the processRequest function
+                       TmfTimeRange allTraceWindow = fEventLog.getTimeRange();
+                       StateDataRequest request = getDataRequestStateSave(allTraceWindow,
+                                       null);
+                       request.setclearDataInd(clearPreviousData);
+
+                       // Wait for completion
+                       request.startRequestInd(fExperiment, true, true);
+
+                       if (TraceDebug.isDEBUG()) {
+                               StringBuilder sb = new StringBuilder(
+                                               "Total number of processes in the State provider: "
+                                                               + stateIn.getTraceStateModel().getProcesses().length);
+
+                               TmfTimeRange logTimes = fEventLog.getTimeRange();
+                               sb.append("\n\tLog file times "
+                                               + new LttngTimestamp(logTimes.getStartTime()));
+                               sb.append(" - " + new LttngTimestamp(logTimes.getEndTime()));
+
+                               sb.append("\n\tCheckPoints available at: ");
+                               for (TmfTraceCheckpoint cpoint : timestampCheckpointsList) {
+                                       sb.append("\n\t" + cpoint.getTimestamp());
+                               }
+                               TraceDebug.debug(sb.toString());
+                       }
+               }
+
+       }
+
+       /**
+        * TODO: Not ready for threading
+        * <p>
+        * Read events within specific time window
+        * </p>
+        * 
+        * @param trange
+        * @param obs
+        * @param transactionID
+        */
+       public void executeDataRequest(TmfTimeRange trange, String transactionID,
+                       IStateDataRequestListener listener) {
+               TmfTimestamp restoredStartTime = restoreCheckPointByTimestamp(trange
+                               .getStartTime());
+               // Adjust the time range to consider rewinding to the start time
+               trange = new TmfTimeRange(restoredStartTime, trange.getEndTime());
+               // Get a data request for the time range we want (nearest checkpoint
+               // to timestamp wanted)
+               eventCount = 0L;
+
+               // Process request to that point
+               StateDataRequest request = getDataRequestByTimeRange(trange, listener);
+               // don't wait for completion i.e. allow cancellations
+               request.startRequestInd(fExperiment, false, false);
+
+               if (TraceDebug.isDEBUG()) {
+                       TraceDebug
+                                       .debug(" Time Window requested, (start adjusted to checkpoint): "
+                                                       + trange.getStartTime()
+                                       + "-" + trange.getEndTime()
+                                       + " Total number of processes in the State provider: "
+                                       + stateIn.getTraceStateModel().getProcesses().length + " Completed");
+               }
+       }
+
+       /**
+        * Current value of event counter
+        * 
+        * @return Long The number of events, if it is known
+        */
+       public Long getEventCount() {
+               return eventCount;
+       }
+
+       /**
+        * used to obtain details on the log associated with this manager e.g.
+        * logid.
+        * 
+        * @return
+        */
+       public TmfTrace getEventLog() {
+               return fEventLog;
+       }
+
+       /**
+        * Used for troubleshooting when debug mode is on
+        * 
+        * @return Set<String> Set of event that were not handled
+        */
+       public Set<String> getEventsNotHandled() {
+               return stateIn.getEventsNotHandled();
+       }
+
+       /**
+        * Needed for verification purposes
+        * 
+        * @param listener
+        *            The IEventProcessing we want to register
+        */
+       void registerListener(IEventProcessing listener) {
+               stateIn.registerListener(listener);
+       }
+
+       /**
+        * Needed for verification purposes
+        * 
+        * @param listener
+        *            The IEventProcessing we want to unregister
+        */
+       void deregisterListener(IEventProcessing listener) {
+               stateIn.deregisterListener(listener);
+       }
+
+       /**
+        * Save a checkpoint if it is needed at that point
+        * <p>
+        * The function will use "eventCount" internally to determine if a save was
+        * needed
+        * 
+        * @param eventCounter
+        *            The event "count" or event "id" so far
+        * @param eventTime
+        *            The timestamp of this event
+        * 
+        * @return boolean True if a checkpoint was saved, false otherwise
+        */
+       private boolean saveCheckPointIfNeeded(Long eventCounter,
+                       TmfTimestamp eventTime) {
+               boolean saveHappened = false;
+               // Crate new location to store checkpoint reference
+               Long location = new Long(eventCounter.longValue());
+               // Save a checkpoint every LTTNG_STATE_SAVE_INTERVAL event
+               if ((location % LTTNG_STATE_SAVE_INTERVAL) == 0) {
+                       // Save the checkpoint
+                       stateCheckpointsList.put(location, stateIn.traceStateModel.clone());
+                       // Save correlation between timestamp and checkpoint index
+
+                       timestampCheckpointsList.add(new TmfTraceCheckpoint(eventTime,
+                                       location));
+
+                       saveHappened = true;
+               }
+
+               return saveHappened;
+       }
+
+       /**
+        * Restore to the closest checkpoint from TmfTimestamp
+        * <p>
+        * Note : it is heavier to restore by timestamp than by event position,
+        * restore by event position whichever possible.
+        * 
+        * @param eventTime
+        *            The timestamp of the event to restore to
+        * 
+        * @return TmfTimestamp indicates the nearest time used to restore the
+        *         state, null sent if input is invalid
+        */
+       public TmfTimestamp restoreCheckPointByTimestamp(TmfTimestamp eventTime) {
+               TmfTimeRange logRange = fExperiment.getTimeRange();
+               TmfTimestamp nearestTimeStamp = logRange.getStartTime();
+
+               // The GUI can have time limits higher than this log, since GUI can
+               // handle multiple logs
+               if ((eventTime.getValue() < 0)
+                               || (eventTime.getValue() > logRange.getEndTime().getValue())) {
+                       return null;
+               }
+               
+               // The GUI can have time limits lower than this log, since GUI can
+               // handle multiple logs
+               if ((eventTime.getValue() < logRange.getStartTime().getValue())) {
+                       eventTime = logRange.getStartTime();
+               }
+               
+               // Sort the checkpoints, required before the binary search
+               Collections.sort(timestampCheckpointsList);
+               // Initiate the compare with a checkpoint containing the target time
+               // stamp to find
+               int index = Collections.binarySearch(timestampCheckpointsList,
+                               new TmfTraceCheckpoint(eventTime, 0));
+               // adjust index to round down to earlier checkpoint when exact match not
+               // found
+               index = getPrevIndex(index);
+
+               LttngTraceState traceState;
+               Long location = 0L;
+               if (index == 0) {
+                       // No checkpoint restore is needed, start with a brand new
+                       // TraceState
+                       ILttngStateInputRef inputDataRef = new LttngStateInputRef(fEventLog);
+                       traceState = StateModelFactory.getStateEntryInstance(inputDataRef);
+               } else {
+                       // Useful CheckPoint found
+                       TmfTraceCheckpoint checkpoint = timestampCheckpointsList.get(index);
+                       nearestTimeStamp = checkpoint.getTimestamp();
+                       // get the location associated with the checkpoint
+                       location = (Long) (checkpoint.getLocation());
+                       // reference a new copy of the checkpoint template
+                       traceState = stateCheckpointsList.get(location).clone();
+               }
+
+               // Make sure eventCount stay consistent!
+               eventCount = new Long(location);
+
+               // Restore the stored traceState
+               stateIn.setTraceStateModel(traceState);
+
+               return nearestTimeStamp;
+       }
+
+       /**
+        * Adjust the result from a binary search to the round down position
+        * 
+        * @param position
+        *            if Negative is: (-(insertion point) -1)
+        * @return position or if no match found, earlier than insertion point
+        */
+       private int getPrevIndex(int position) {
+               int roundDownPosition = position;
+               if (position < 0) {
+                       roundDownPosition = -(position + 2);
+               }
+
+               roundDownPosition = roundDownPosition < 0 ? 0 : roundDownPosition;
+               return roundDownPosition;
+       }
+
+       // /**
+       // * Restore to the closest checkpoint from position
+       // * <p>
+       // *
+       // * @param position
+       // * The position of the event to restore to
+       // *
+       // * @return boolean True if a checkpoint was restored, false otherwise
+       // */
+       // private boolean restoreCheckPointByPosition(long position) {
+       // long nearestCheckPoint = (position - (position %
+       // LTTNG_STATE_SAVE_INTERVAL));
+       //
+       // // Some sanity check :
+       // // Not under 0
+       // // Not over eventCount
+       // // A checkpoint exist
+       // if ((nearestCheckPoint < 0) || (nearestCheckPoint > eventCount)
+       // || (stateCheckpointsList.get(nearestCheckPoint) == null)) {
+       // return false;
+       // } else {
+       // // Restore the stored traceState
+       // stateIn.setTraceStateModel(stateCheckpointsList
+       // .get(nearestCheckPoint));
+       //
+       // // Make sure eventCount stay consistent!
+       // eventCount = new Long(nearestCheckPoint);
+       //
+       // // * Rewind to the correct position
+       // // To do so, we need a request to the correct window
+       // // We will seek to nearestCheckPoint and read next events until
+       // // position
+       // TmfDataRequest<TmfEvent> request = getDataRequestByPosition(
+       // (int) nearestCheckPoint, (int) position);
+       //
+       // // Process request to that point
+       // fExperiment.processRequest(request, true);
+       //
+       // return true;
+       // }
+       // }
+
+       /**
+        * Get a Tmf data request for the current eventlog
+        * <p>
+        * 
+        * @param TmfTimeRange
+        *            The time range we want events from.
+        * 
+        * @return TmfDataRequest<TmfEvent> The request made
+        */
+       StateDataRequest getDataRequestByTimeRange(TmfTimeRange timeWindow,
+                       IStateDataRequestListener listener) {
+
+               final TmfEvent[] evt = new TmfEvent[1];
+
+               // ***TODO***
+               // The override of handlePartialResult is similar to the one in
+               // getDataRequestByPosition()
+               // ***
+
+               // Create the new request and override the handlePartialResult function
+               StateDataRequest request = new StateDataRequest(timeWindow,
+                               DEFAULT_OFFSET, TmfDataRequest.ALL_EVENTS, DEFAULT_CHUNK,
+                               listener, this) {
+                       @Override
+                       public void handleData() {
+                               TmfEvent[] result = getData();
+
+                               evt[0] = (result.length > 0) ? result[0] : null;
+                               // Dispatch information for Event processing
+                               stateIn.processEvent(evt[0]);
+
+                               // increment internal and external number of events
+                               setNumOfEvents(getNumOfEvents() + 1);
+                               eventCount++;
+                       }
+
+                       @Override
+                       public void handleCompleted() {
+                               if (isCancelled() || isFailed()) {
+                                       // No notification to end request handlers
+                               } else {
+                                       // notify the associated end request handlers
+                                       requestCompleted();
+                               }
+
+                               // notify listeners
+                               notifyCompletion();
+                       }
+               };
+
+               return request;
+       }
+
+       private StateDataRequest getDataRequestStateSave(TmfTimeRange timeWindow,
+                       IStateDataRequestListener requestListener) {
+
+               final TmfEvent[] evt = new TmfEvent[1];
+
+               // ***TODO***
+               // The override of handlePartialResult is similar to the one in
+               // getDataRequestByPosition()
+               // ***
+
+               // Create the new request and override the handlePartialResult function
+               StateDataRequest request = new StateDataRequest(timeWindow,
+                               DEFAULT_OFFSET, TmfDataRequest.ALL_EVENTS, DEFAULT_CHUNK,
+                               requestListener, this) {
+
+                       @Override
+                       public void handleData() {
+                               TmfEvent[] result = getData();
+                               
+                               evt[0] = (result.length > 0) ? result[0] : null;
+                               // Dispatch information for Event processing
+                               stateIn.processEvent(evt[0]);
+
+                               // Call the function that will save a checkpoint if needed at
+                               // that point
+                               // Note : We call this function before incrementing eventCount
+                               // to avoid skipping the "0th" event
+                               if (evt[0] != null) {
+                                       saveCheckPointIfNeeded(getNumOfEvents(), evt[0]
+                                                       .getTimestamp());
+                               }
+
+                               // increment internal and external counters
+                               setNumOfEvents(getNumOfEvents() + 1);
+                               eventCount++;
+                       }
+
+                       @Override
+                       public void handleCompleted() {
+                               if (isCancelled() || isFailed()) {
+                                       // No notification to end request handlers
+                               } else {
+                                       // notify the associated end request handlers
+                                       requestCompleted();
+                               }
+
+                               // notify listeners
+                               notifyCompletion();
+                               TraceDebug.debug("number of events processed on file opening"
+                                               + getNumOfEvents());
+                       }
+               };
+
+               return request;
+       }
+
+       // /**
+       // * Get a Tmf data request for the current eventlog
+       // * <p>
+       // *
+       // * @param startPosition
+       // * The position to start the get request from
+       // * @param endPosition
+       // * The position to ed the get request at
+       // *
+       // * @return TmfDataRequest<TmfEvent> The request made
+       // */
+       // private TmfDataRequest<TmfEvent> getDataRequestByPosition(
+       // long startPosition, long endPosition) {
+       // final TmfEvent[] evt = new TmfEvent[1];
+       //
+       // // ***FIXME***
+       // // The override of handlePartialResult is exactly the same as the one in
+       // // getDataRequestByPosition()
+       // // However, there is no way to override it in only one place to avoid
+       // // code duplication!
+       // // ***
+       //
+       // // Create the new request and override the handlePartialResult function
+       // TmfDataRequest<TmfEvent> request = new TmfDataRequest<TmfEvent>(
+       // (int) startPosition, DEFAULT_OFFSET,
+       // (int) (endPosition - startPosition), DEFAULT_CHUNK) {
+       // //@Override
+       // public void handlePartialResult() {
+       // TmfEvent[] result = getData();
+       //
+       // evt[0] = (result.length > 0) ? result[0] : null;
+       // // Dispatch information for Event processing
+       // stateIn.processEvent(evt[0]);
+       // }
+       // };
+       //
+       // return request;
+       // }
+
+       /**
+        * @return
+        */
+       public TmfTimeRange getExperimentTimeWindow() {
+               if (fExperiment != null) {
+                       return fExperiment.getTimeRange();
+               }
+               return null;
+       }
+
+       /**
+        * This method has to be called once all events of the associated Trace have
+        * been processed, this method then triggers the drawing of the final state
+        * which is necessary e.g when zooming.
+        */
+       public synchronized void requestCompleted() {
+               Set<AbsEventProcessorFactory> handlerRegister = EventProcessorProxy
+                               .getInstance().getProcessingFactories();
+               // Notify the FINISH handlers
+               for (Iterator<AbsEventProcessorFactory> iterator = handlerRegister
+                               .iterator(); iterator.hasNext();) {
+                       AbsEventProcessorFactory handlerRegistry = (AbsEventProcessorFactory) iterator
+                                       .next();
+                       IEventProcessing handler = handlerRegistry.getfinishProcessor();
+                       if (handler != null) {
+                               // process State Update
+                               handler.process(null, stateIn.traceStateModel);
+                       }
+               }
+       }
+}
diff --git a/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/StateStacksHandler.java b/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/StateStacksHandler.java
new file mode 100644 (file)
index 0000000..81ad12f
--- /dev/null
@@ -0,0 +1,199 @@
+/*******************************************************************************
+ * Copyright (c) 2009 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:
+ *   Alvaro Sanchez-Leon (alvsan09@gmail.com) - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.linuxtools.lttng.state;
+
+import java.util.Iterator;
+import java.util.Set;
+import java.util.Vector;
+
+import org.eclipse.linuxtools.lttng.TraceDebug;
+import org.eclipse.linuxtools.lttng.event.LttngEvent;
+import org.eclipse.linuxtools.lttng.state.evProcessor.AbsEventProcessorFactory;
+import org.eclipse.linuxtools.lttng.state.evProcessor.EventProcessorProxy;
+import org.eclipse.linuxtools.lttng.state.evProcessor.IEventProcessing;
+import org.eclipse.linuxtools.lttng.state.model.ILttngStateInputRef;
+import org.eclipse.linuxtools.lttng.state.model.LttngTraceState;
+import org.eclipse.linuxtools.tmf.event.TmfEvent;
+import org.eclipse.linuxtools.tmf.trace.TmfTrace;
+
+/**
+ * @author Alvaro
+ * 
+ */
+public class StateStacksHandler {
+       // ========================================================================
+       // Table data
+       // =======================================================================
+       protected LttngTraceState traceStateModel = null;
+       protected Set<String> eventsNotHandled = null;
+       protected Vector<IEventProcessing> listeners = new Vector<IEventProcessing>();
+
+       // ========================================================================
+       // Constructors
+       // ========================================================================
+       public StateStacksHandler(LttngTraceState model) {
+               // It's assumed to have one instance of this class per Trace
+               this.traceStateModel = model;
+       }
+
+       // ========================================================================
+       // Methods
+       // =======================================================================
+       /**
+        * Initialised by manager, any time a JniTrace selection is updated
+        * 
+        * @param trace
+        * @param log
+        * 
+        */
+       void init(TmfTrace log) throws LttngStateException {
+               if (log == null) {
+                       throw new LttngStateException("No TmfTrace object available!");
+               }
+
+               // this.trace = trace;
+               ILttngStateInputRef ref = new LttngStateInputRef(log);
+               this.traceStateModel.init(ref);
+       }
+
+
+       protected void processEvent(TmfEvent tmfEvent) /* throws LttngStateException */{
+               if (tmfEvent == null) {
+                       return;
+               }
+
+               if (!(tmfEvent instanceof LttngEvent)) {
+                       TraceDebug
+                                       .debug("The event received is not an instance of LttngEvent and can not be processed");
+               }
+
+               LttngEvent trcEvent = (LttngEvent) tmfEvent;
+//             LttngEventField[] fields = ((LttngEventContent)trcEvent.getContent()).getFields();
+
+               if (trcEvent != null) {
+                       String inEventName = trcEvent.getMarkerName();
+                       // String inChannel = trcEvent.getChannelName();
+                       // TraceDebug.debug("Event: " + inEventName);
+
+                       // Check if the received event is a transition state event
+                       // TODO: Remove temporarily to allow other events to go to the
+                       // statistics view.
+                       // Needs restructuring.
+                       // Events eventStruct = StateStrings.getInstance()
+                       // .getStateTransEventMap().get(inEventName);
+                       // if (eventStruct != null) {
+                       // String expectedChannel = eventStruct.getParent().getInName();
+                       // check that received channel is the expected channel in the
+                       // structure
+                       // if (inChannel.equals(expectedChannel)) {
+                       // Notify the before Handlers
+                       Set<AbsEventProcessorFactory> handlerRegister = EventProcessorProxy
+                                       .getInstance().getProcessingFactories();
+
+                       // Notify the state BEFORE update handlers
+                       for (Iterator<AbsEventProcessorFactory> iterator = handlerRegister
+                                       .iterator(); iterator.hasNext();) {
+                               AbsEventProcessorFactory handlerRegistry = (AbsEventProcessorFactory) iterator
+                                               .next();
+                               IEventProcessing handler = handlerRegistry
+                                               .getBeforeProcessor(inEventName);
+                               if (handler != null) {
+                                       // process State Update
+                                       handler.process(trcEvent, traceStateModel);
+                               }
+
+                       }
+
+                       // Notify the STATE UPDATE handlers
+                       // Only one state update expected
+                       for (Iterator<AbsEventProcessorFactory> iterator = handlerRegister
+                                       .iterator(); iterator.hasNext();) {
+                               AbsEventProcessorFactory handlerRegistry = (AbsEventProcessorFactory) iterator
+                                               .next();
+                               IEventProcessing handler = handlerRegistry
+                                               .getStateUpdaterProcessor(inEventName);
+                               if (handler != null) {
+                                       // process State Update
+                                       handler.process(trcEvent, traceStateModel);
+                               }
+
+                       }
+
+                       // Notify the AFTER update handlers
+                       for (Iterator<AbsEventProcessorFactory> iterator = handlerRegister
+                                       .iterator(); iterator.hasNext();) {
+                               AbsEventProcessorFactory handlerRegistry = (AbsEventProcessorFactory) iterator
+                                               .next();
+                               IEventProcessing handler = handlerRegistry
+                                               .getAfterProcessor(inEventName);
+                               if (handler != null) {
+                                       // process State Update
+                                       handler.process(trcEvent, traceStateModel);
+                               }
+                       }
+
+                       // } else {
+                       // StringBuilder sb = new StringBuilder(
+                       // "Unexpected channel received for: " + inEventName
+                       // + ", channel rec: " + inChannel
+                       // + " chanel expected: " + expectedChannel);
+                       // TraceDebug.debug(sb.toString());
+                       // }
+                       // }
+               }
+       }
+
+       /**
+        * Used for troubleshooting when debug mode is on
+        * 
+        * @return
+        */
+       Set<String> getEventsNotHandled() {
+               return eventsNotHandled;
+       }
+       
+       /**
+     * Needed for checkpoint
+     * 
+     * @param LttngTraceState
+     */
+    public LttngTraceState getTraceStateModel() {
+        return traceStateModel;
+    }
+    
+    /**
+     * Needed for checkpoint
+     * 
+     * @param LttngTraceState
+     */
+    public void setTraceStateModel(LttngTraceState newTraceState) {
+        traceStateModel = newTraceState;
+    }
+       
+       /**
+        * Needed for verification purposes
+        * 
+        * @param listener
+        */
+       void registerListener(IEventProcessing listener) {
+               this.listeners.add(listener);
+       }
+
+       /**
+        * Needed for verification purposes
+        * 
+        * @param listener
+        */
+       void deregisterListener(IEventProcessing listener) {
+               this.listeners.remove(listener);
+       }
+}
diff --git a/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/evProcessor/AbsEventProcessorFactory.java b/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/evProcessor/AbsEventProcessorFactory.java
new file mode 100644 (file)
index 0000000..c0a414d
--- /dev/null
@@ -0,0 +1,51 @@
+/*******************************************************************************
+ * Copyright (c) 2009 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:
+ *   Alvaro Sanchez-Leon (alvsan09@gmail.com) - Initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.linuxtools.lttng.state.evProcessor;
+
+/**
+ * @author alvaro
+ * 
+ */
+public abstract class AbsEventProcessorFactory {
+       /**
+        * 
+        * @return The Event Handler for received event before the State data model
+        *         is updated.
+        */
+       public abstract IEventProcessing getBeforeProcessor(String eventType);
+
+       /**
+        * 
+        * @return The Event Handler for received event after the State data model
+        *         is updated.
+        */
+       public abstract IEventProcessing getAfterProcessor(String eventType);
+
+       /**
+        * 
+        * @return The Event Handler after the complete read request is completed,
+        *         needed e.g. to draw the last state
+        */
+       public abstract IEventProcessing getfinishProcessor();
+
+       /**
+        * 
+        * @return The Event Handler for received event in charge to update the
+        *         state. Only one handler is expected so other factories must not
+        *         override this method.
+        */
+       public IEventProcessing getStateUpdaterProcessor(String eventType) {
+               return null;
+       }
+
+}
index 272c5725f70748da0a544d1a0b274501f1950f23..cb92caaf538aa7faf4a9ca969c14c6aa53e1b645 100644 (file)
@@ -16,7 +16,7 @@ import java.util.HashSet;
 import java.util.Set;
 
 import org.eclipse.linuxtools.lttng.TraceDebug;
-import org.eclipse.linuxtools.lttng.state.evProcessor.state.StateEventToHandlerFactory;
+import org.eclipse.linuxtools.lttng.state.evProcessor.state.StateUpdateFactory;
 
 /**
  * @author alvaro
@@ -27,7 +27,7 @@ public class EventProcessorProxy {
        // Data
        // =======================================================================
        private static EventProcessorProxy instance = null;
-       private final Set<AbsEventToHandlerResolver> processingFactories = new HashSet<AbsEventToHandlerResolver>();
+       private final Set<AbsEventProcessorFactory> processingFactories = new HashSet<AbsEventProcessorFactory>();
 
        
        // ========================================================================
@@ -35,7 +35,7 @@ public class EventProcessorProxy {
        // =======================================================================
        public EventProcessorProxy() {
                // Manual creation of State update factory
-               addEventProcessorFactory(StateEventToHandlerFactory.getInstance());
+               addEventProcessorFactory(StateUpdateFactory.getInstance());
        }
 
        // ========================================================================
@@ -44,7 +44,7 @@ public class EventProcessorProxy {
        /**
         * @return the processingFactories
         */
-       public Set<AbsEventToHandlerResolver> getProcessingFactories() {
+       public Set<AbsEventProcessorFactory> getProcessingFactories() {
                return processingFactories;
        }
 
@@ -68,7 +68,7 @@ public class EventProcessorProxy {
         * @param handlersFactory
         */
        public void addEventProcessorFactory(
-                       AbsEventToHandlerResolver handlersFactory) {
+                       AbsEventProcessorFactory handlersFactory) {
                if (handlersFactory != null) {
                        //only add the listener if not already included
                        if (!processingFactories.contains(handlersFactory)) {
@@ -86,7 +86,7 @@ public class EventProcessorProxy {
         * @param handlersFactory
         */
        public void removeEventProcessorFactory(
-                       IEventToHandlerResolver handlersFactory) {
+                       AbsEventProcessorFactory handlersFactory) {
                if (handlersFactory != null) {
                        processingFactories.remove(handlersFactory);
                } 
diff --git a/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/evProcessor/IEventProcessing.java b/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/evProcessor/IEventProcessing.java
new file mode 100644 (file)
index 0000000..d69827b
--- /dev/null
@@ -0,0 +1,29 @@
+/*******************************************************************************
+ * Copyright (c) 2009 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:
+ *   Alvaro Sanchez-Leon (alvsan09@gmail.com) - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.linuxtools.lttng.state.evProcessor;
+
+import org.eclipse.linuxtools.lttng.event.LttngEvent;
+import org.eclipse.linuxtools.lttng.state.StateStrings;
+import org.eclipse.linuxtools.lttng.state.model.LttngTraceState;
+
+/**
+ * @author alvaro
+ *
+ */
+public interface IEventProcessing {
+
+       // ========================================================================
+       // Abstract methods
+       // =======================================================================
+       public abstract boolean process(LttngEvent trcEvent, LttngTraceState traceSt);
+       public abstract StateStrings.Events getEventHandleType();
+}
index 26fbc4cfce03034ca269a7fdfac63d40b01e0f4d..bf82ff2e75c05c9dfc5aa1eb4bef8e70f1ca6219 100644 (file)
@@ -18,7 +18,7 @@ import org.eclipse.linuxtools.lttng.state.StateStrings;
 import org.eclipse.linuxtools.lttng.state.StateStrings.ExecutionMode;
 import org.eclipse.linuxtools.lttng.state.StateStrings.IRQMode;
 import org.eclipse.linuxtools.lttng.state.StateStrings.ProcessStatus;
-import org.eclipse.linuxtools.lttng.state.evProcessor.ILttngEventProcessor;
+import org.eclipse.linuxtools.lttng.state.evProcessor.IEventProcessing;
 import org.eclipse.linuxtools.lttng.state.model.LTTngCPUState;
 import org.eclipse.linuxtools.lttng.state.model.LttngBdevState;
 import org.eclipse.linuxtools.lttng.state.model.LttngExecutionState;
@@ -28,7 +28,7 @@ import org.eclipse.linuxtools.lttng.state.model.LttngTraceState;
 import org.eclipse.linuxtools.tmf.event.TmfTimestamp;
 
 public abstract class AbsStateUpdate extends AbsStateProcessing implements
-               ILttngEventProcessor {
+               IEventProcessing {
 
        // ========================================================================
        // Data
@@ -48,8 +48,7 @@ public abstract class AbsStateUpdate extends AbsStateProcessing implements
                exe_state.setEntry_Time(eventTime.getValue());
                exe_state.setChange_Time(eventTime.getValue());
                exe_state.setCum_cpu_time(0L);
-//             if (process != null)
-                       exe_state.setProc_status(process.getState().getProc_status());
+               exe_state.setProc_status(process.getState().getProc_status());
                process.pushToExecutionStack(exe_state);
        }
 
diff --git a/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/evProcessor/state/StateUpdateFactory.java b/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/evProcessor/state/StateUpdateFactory.java
new file mode 100644 (file)
index 0000000..977a672
--- /dev/null
@@ -0,0 +1,186 @@
+/*******************************************************************************
+ * Copyright (c) 2009 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:
+ *   Alvaro Sanchez-Leon (alvsan09@gmail.com) - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.linuxtools.lttng.state.evProcessor.state;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.linuxtools.lttng.state.StateStrings;
+import org.eclipse.linuxtools.lttng.state.evProcessor.AbsEventProcessorFactory;
+import org.eclipse.linuxtools.lttng.state.evProcessor.IEventProcessing;
+
+/**
+ * Builds a Map from string event name to a processing handler object, the
+ * processors implement the same interface to facilitate transparent methods
+ * call,
+ * 
+ * The map key STring is the entry point of the raw events, using a hash speeds
+ * up the resolution of the appropriate processor
+ * 
+ * @author alvaro
+ * 
+ */
+public class StateUpdateFactory extends AbsEventProcessorFactory {
+       // ========================================================================
+       // Data
+       // =======================================================================
+       private final Map<String, IEventProcessing> eventNametoProcessor = new HashMap<String, IEventProcessing>();
+       private static StateUpdateFactory instance = new StateUpdateFactory();
+       private StateUpdateHandlers instantiateHandler = new StateUpdateHandlers();
+
+       // ========================================================================
+       // Constructors
+       // =======================================================================
+       private StateUpdateFactory() {
+               //create one instance of each individual event handler and add the instance to the map
+               eventNametoProcessor.put(StateStrings.Events.LTT_EVENT_SYSCALL_ENTRY
+                               .getInName(), instantiateHandler.getSyscallEntryHandler());
+               
+               eventNametoProcessor.put(StateStrings.Events.LTT_EVENT_SYSCALL_EXIT
+                               .getInName(), instantiateHandler.getsySyscallExitHandler());
+               
+               eventNametoProcessor.put(StateStrings.Events.LTT_EVENT_TRAP_ENTRY
+                               .getInName(), instantiateHandler.getTrapEntryHandler());
+               
+               eventNametoProcessor.put(StateStrings.Events.LTT_EVENT_TRAP_EXIT
+                               .getInName(), instantiateHandler.getTrapExitHandler());
+               
+               eventNametoProcessor.put(StateStrings.Events.LTT_EVENT_PAGE_FAULT_ENTRY
+                               .getInName(), instantiateHandler.getTrapEntryHandler());
+               
+               eventNametoProcessor.put(StateStrings.Events.LTT_EVENT_PAGE_FAULT_EXIT
+                               .getInName(), instantiateHandler.getTrapExitHandler());
+
+               eventNametoProcessor.put(StateStrings.Events.LTT_EVENT_PAGE_FAULT_NOSEM_ENTRY
+                               .getInName(), instantiateHandler.getTrapEntryHandler());
+               
+               eventNametoProcessor.put(StateStrings.Events.LTT_EVENT_PAGE_FAULT_NOSEM_EXIT
+                               .getInName(), instantiateHandler.getTrapExitHandler());
+               
+               eventNametoProcessor.put(StateStrings.Events.LTT_EVENT_IRQ_ENTRY
+                               .getInName(), instantiateHandler.getIrqEntryHandler());
+               
+               eventNametoProcessor.put(StateStrings.Events.LTT_EVENT_IRQ_EXIT
+                               .getInName(), instantiateHandler.getIrqExitHandler());
+               
+               eventNametoProcessor.put(StateStrings.Events.LTT_EVENT_SOFT_IRQ_RAISE
+                               .getInName(), instantiateHandler.getSoftIrqRaiseHandler());
+               
+               eventNametoProcessor.put(StateStrings.Events.LTT_EVENT_SOFT_IRQ_ENTRY
+                               .getInName(), instantiateHandler.getSoftIrqEntryHandler());
+               
+               eventNametoProcessor.put(StateStrings.Events.LTT_EVENT_SOFT_IRQ_EXIT
+                               .getInName(), instantiateHandler.getSoftIrqExitHandler());
+               
+               eventNametoProcessor.put(StateStrings.Events.LTT_EVENT_LIST_INTERRUPT
+                               .getInName(), instantiateHandler.getEnumInterruptHandler());
+               
+               eventNametoProcessor.put(StateStrings.Events.LTT_EVENT_REQUEST_ISSUE
+                               .getInName(), instantiateHandler.getBdevRequestIssueHandler());
+               
+               eventNametoProcessor.put(StateStrings.Events.LTT_EVENT_REQUEST_COMPLETE
+                               .getInName(), instantiateHandler.getBdevRequestCompleteHandler());
+               
+               eventNametoProcessor.put(StateStrings.Events.LTT_EVENT_FUNCTION_ENTRY
+                               .getInName(), instantiateHandler.getFunctionEntryHandler());
+               
+               eventNametoProcessor.put(StateStrings.Events.LTT_EVENT_FUNCTION_EXIT
+                               .getInName(), instantiateHandler.getFunctionExitHandler());
+               
+               eventNametoProcessor.put(StateStrings.Events.LTT_EVENT_SYS_CALL_TABLE
+                               .getInName(), instantiateHandler.getDumpSyscallHandler());
+               
+               eventNametoProcessor.put(StateStrings.Events.LTT_EVENT_KPROBE_TABLE
+                               .getInName(), instantiateHandler.getDumpKprobeHandler());
+               
+               eventNametoProcessor.put(StateStrings.Events.LTT_EVENT_SOFTIRQ_VEC
+                               .getInName(), instantiateHandler.getDumpSoftIrqHandler());
+               
+               eventNametoProcessor.put(StateStrings.Events.LTT_EVENT_SCHED_SCHEDULE
+                               .getInName(), instantiateHandler.getSchedChangeHandler());
+               
+               eventNametoProcessor.put(StateStrings.Events.LTT_EVENT_PROCESS_FORK
+                               .getInName(), instantiateHandler.getProcessForkHandler());
+               
+               eventNametoProcessor.put(StateStrings.Events.LTT_EVENT_KTHREAD_CREATE
+                               .getInName(), instantiateHandler.getProcessKernelThreadHandler());
+               
+               eventNametoProcessor.put(StateStrings.Events.LTT_EVENT_PROCESS_EXIT
+                               .getInName(), instantiateHandler.getProcessExitHandler());
+               
+               eventNametoProcessor.put(StateStrings.Events.LTT_EVENT_PROCESS_FREE
+                               .getInName(), instantiateHandler.getProcessFreeHandler());
+               
+               eventNametoProcessor.put(StateStrings.Events.LTT_EVENT_EXEC
+                               .getInName(), instantiateHandler.getProcessExecHandler());
+               
+               eventNametoProcessor.put(StateStrings.Events.LTT_EVENT_THREAD_BRAND
+                               .getInName(), instantiateHandler.GetThreadBrandHandler());
+               
+               eventNametoProcessor.put(StateStrings.Events.LTT_EVENT_STATEDUMP_END
+                               .getInName(), instantiateHandler.getStateDumpEndHandler());
+               
+               eventNametoProcessor.put(StateStrings.Events.LTT_EVENT_PROCESS_STATE
+                               .getInName(), instantiateHandler.getEnumProcessStateHandler());
+
+
+       }
+
+       // ========================================================================
+       // Public methods
+       // =======================================================================
+       /**
+        * The event processors are common to all traces an multiple instances will
+        * use more memory unnecessarily
+        * 
+        * @return
+        */
+       public static AbsEventProcessorFactory getInstance() {
+               if (instance == null) {
+                       instance = new StateUpdateFactory();
+               }
+               return instance;
+       }
+
+
+       /* (non-Javadoc)
+        * @see org.eclipse.linuxtools.lttng.state.evProcessor.AbsEventProcessorFactory#getAfterProcessor(java.lang.String)
+        */
+       @Override
+       public IEventProcessing getAfterProcessor(String eventType) {
+               return null;
+       }
+
+       /* (non-Javadoc)
+        * @see org.eclipse.linuxtools.lttng.state.evProcessor.AbsEventProcessorFactory#getBeforeProcessor(java.lang.String)
+        */
+       @Override
+       public IEventProcessing getBeforeProcessor(String eventType) {
+               return null;
+       }
+       
+       /**
+        * This is the only event handler to update the State provider
+        * @return 
+        * 
+        */
+       @Override
+       public IEventProcessing getStateUpdaterProcessor(String eventType) {
+               return eventNametoProcessor.get(eventType);
+       }
+
+       @Override
+       public IEventProcessing getfinishProcessor() {
+               // No finishing processor used
+               return null;
+       }
+}
index d15b2008313e260d88e64584ecde720dd0d8cbc1..48292b86b6fa3af03d81382c577e152f4475f774 100644 (file)
@@ -25,7 +25,7 @@ import org.eclipse.linuxtools.lttng.state.StateStrings.Fields;
 import org.eclipse.linuxtools.lttng.state.StateStrings.IRQMode;
 import org.eclipse.linuxtools.lttng.state.StateStrings.ProcessStatus;
 import org.eclipse.linuxtools.lttng.state.StateStrings.ProcessType;
-import org.eclipse.linuxtools.lttng.state.evProcessor.ILttngEventProcessor;
+import org.eclipse.linuxtools.lttng.state.evProcessor.IEventProcessing;
 import org.eclipse.linuxtools.lttng.state.model.LTTngCPUState;
 import org.eclipse.linuxtools.lttng.state.model.LttngBdevState;
 import org.eclipse.linuxtools.lttng.state.model.LttngExecutionState;
@@ -45,9 +45,11 @@ import org.eclipse.linuxtools.tmf.event.TmfTimestamp;
  */
 class StateUpdateHandlers {
 
-       final ILttngEventProcessor getSyscallEntryHandler() {
+       final IEventProcessing getSyscallEntryHandler() {
                AbsStateUpdate handler = new AbsStateUpdate() {
 
+                       private Events eventType = Events.LTT_EVENT_SYSCALL_ENTRY;
+
                        // @Override
                        public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) {
 
@@ -83,13 +85,20 @@ class StateUpdateHandlers {
                                                submode, trcEvent.getTimestamp(), traceSt);
                                return false;
                        }
+
+                       // @Override
+                       public Events getEventHandleType() {
+                               return eventType;
+                       }
                };
                return handler;
        }
 
-       final ILttngEventProcessor getsySyscallExitHandler() {
+       final IEventProcessing getsySyscallExitHandler() {
                AbsStateUpdate handler = new AbsStateUpdate() {
 
+                       private Events eventType = Events.LTT_EVENT_SYSCALL_EXIT;
+
                        // @Override
                        public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) {
 
@@ -108,6 +117,11 @@ class StateUpdateHandlers {
                                return false;
 
                        }
+
+                       // @Override
+                       public Events getEventHandleType() {
+                               return eventType;
+                       }
                };
                return handler;
        }
@@ -117,9 +131,11 @@ class StateUpdateHandlers {
         * 
         * @return
         */
-       final ILttngEventProcessor getTrapEntryHandler() {
+       final IEventProcessing getTrapEntryHandler() {
                AbsStateUpdate handler = new AbsStateUpdate() {
 
+                       private Events eventType = Events.LTT_EVENT_TRAP_ENTRY;
+
                        // @Override
                        public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) {
                                Long cpu = trcEvent.getCpuId();
@@ -149,25 +165,19 @@ class StateUpdateHandlers {
                                LTTngCPUState cpust = traceSt.getCpu_states().get(cpu);
                                cpu_push_mode(cpust, StateStrings.CpuMode.LTTV_CPU_TRAP);
                                cpust.pushToTrapStack(trap); /* update trap status */
-                               
+
                                // update Trap State
-                               LttngTrapState trap_state = null;
-                               trap_state = traceSt.getTrap_states().get(trap);
-                               
-                               // If the trape_state exists, just increment it's counter, 
-                               //      otherwise, create it
-                               if ( trap_state == null ) {
-                                       trap_state = new LttngTrapState();
-                                       trap_state.incrementRunning();
-                                       traceSt.getTrap_states().put(trap, trap_state);
-                               }
-                               else {
-                                       trap_state.incrementRunning();
-                               }
-                               
+                               LttngTrapState trap_state = traceSt.getTrap_states().get(trap);
+                               trap_state.incrementRunning();
+
                                return false;
 
                        }
+
+                       // @Override
+                       public Events getEventHandleType() {
+                               return eventType;
+                       }
                };
                return handler;
        }
@@ -176,9 +186,11 @@ class StateUpdateHandlers {
         * 
         * @return
         */
-       final ILttngEventProcessor getTrapExitHandler() {
+       final IEventProcessing getTrapExitHandler() {
                AbsStateUpdate handler = new AbsStateUpdate() {
 
+                       private Events eventType = Events.LTT_EVENT_TRAP_EXIT;
+
                        // @Override
                        public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) {
 
@@ -203,6 +215,11 @@ class StateUpdateHandlers {
                                return false;
 
                        }
+
+                       // @Override
+                       public Events getEventHandleType() {
+                               return eventType;
+                       }
                };
                return handler;
        }
@@ -211,9 +228,11 @@ class StateUpdateHandlers {
         * 
         * @return
         */
-       final ILttngEventProcessor getIrqEntryHandler() {
+       final IEventProcessing getIrqEntryHandler() {
                AbsStateUpdate handler = new AbsStateUpdate() {
 
+                       private Events eventType = Events.LTT_EVENT_IRQ_ENTRY;
+
                        // @Override
                        public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) {
 
@@ -221,10 +240,7 @@ class StateUpdateHandlers {
 
                                Long irq = getAFieldLong(trcEvent, traceSt,
                                                Fields.LTT_FIELD_IRQ_ID);
-                               if (irq == null || traceSt.getIrq_states().get(irq) == null) {
-                                       if (irq != null) {
-                                               System.out.println("Invalid irq (" + irq + "), ts = " + trcEvent.getOriginalTimestamp());
-                                       }
+                               if (irq == null) {
                                        return true;
                                }
 
@@ -254,6 +270,10 @@ class StateUpdateHandlers {
                                return false;
 
                        }
+
+                       public Events getEventHandleType() {
+                               return eventType;
+                       }
                };
                return handler;
        }
@@ -262,9 +282,11 @@ class StateUpdateHandlers {
         * 
         * @return
         */
-       final ILttngEventProcessor getSoftIrqExitHandler() {
+       final IEventProcessing getSoftIrqExitHandler() {
                AbsStateUpdate handler = new AbsStateUpdate() {
 
+                       private Events eventType = Events.LTT_EVENT_SOFT_IRQ_EXIT;
+
                        // @Override
                        public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) {
 
@@ -280,9 +302,7 @@ class StateUpdateHandlers {
                                if (softirq != -1) {
                                        LttngSoftIRQState softIrqstate = traceSt
                                                        .getSoft_irq_states().get(softirq);
-                                       if (softIrqstate != null) {
-                                               softIrqstate.decrementRunning();
-                                       }
+                                       softIrqstate.decrementRunning();
                                }
 
                                /* update cpu status */
@@ -290,6 +310,11 @@ class StateUpdateHandlers {
 
                                return false;
                        }
+
+                       // @Override
+                       public Events getEventHandleType() {
+                               return eventType;
+                       }
                };
                return handler;
        }
@@ -298,9 +323,11 @@ class StateUpdateHandlers {
         * 
         * @return
         */
-       final ILttngEventProcessor getIrqExitHandler() {
+       final IEventProcessing getIrqExitHandler() {
                AbsStateUpdate handler = new AbsStateUpdate() {
 
+                       private Events eventType = Events.LTT_EVENT_IRQ_EXIT;
+
                        // @Override
                        public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) {
 
@@ -325,6 +352,11 @@ class StateUpdateHandlers {
                                return false;
 
                        }
+
+                       // @Override
+                       public Events getEventHandleType() {
+                               return eventType;
+                       }
                };
                return handler;
        }
@@ -333,7 +365,7 @@ class StateUpdateHandlers {
         * 
         * @return
         */
-       final ILttngEventProcessor getSoftIrqRaiseHandler() {
+       final IEventProcessing getSoftIrqRaiseHandler() {
                AbsStateUpdate handler = new AbsStateUpdate() {
 
                        private Events eventType = Events.LTT_EVENT_SOFT_IRQ_RAISE;
@@ -376,6 +408,11 @@ class StateUpdateHandlers {
                                return false;
 
                        }
+
+                       // @Override
+                       public Events getEventHandleType() {
+                               return eventType;
+                       }
                };
                return handler;
        }
@@ -384,9 +421,11 @@ class StateUpdateHandlers {
         * 
         * @return
         */
-       final ILttngEventProcessor getSoftIrqEntryHandler() {
+       final IEventProcessing getSoftIrqEntryHandler() {
                AbsStateUpdate handler = new AbsStateUpdate() {
 
+                       private Events eventType = Events.LTT_EVENT_SOFT_IRQ_ENTRY;
+
                        // @Override
                        public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) {
 
@@ -434,6 +473,11 @@ class StateUpdateHandlers {
                                return false;
 
                        }
+
+                       // @Override
+                       public Events getEventHandleType() {
+                               return eventType;
+                       }
                };
                return handler;
        }
@@ -443,7 +487,7 @@ class StateUpdateHandlers {
         * 
         * @return
         */
-       final ILttngEventProcessor getEnumInterruptHandler() {
+       final IEventProcessing getEnumInterruptHandler() {
                AbsStateUpdate handler = new AbsStateUpdate() {
 
                        private Events eventType = Events.LTT_EVENT_LIST_INTERRUPT;
@@ -475,6 +519,11 @@ class StateUpdateHandlers {
                                return false;
 
                        }
+
+                       // @Override
+                       public Events getEventHandleType() {
+                               return eventType;
+                       }
                };
                return handler;
        }
@@ -484,9 +533,11 @@ class StateUpdateHandlers {
         * 
         * @return
         */
-       final ILttngEventProcessor getBdevRequestIssueHandler() {
+       final IEventProcessing getBdevRequestIssueHandler() {
                AbsStateUpdate handler = new AbsStateUpdate() {
 
+                       private Events eventType = Events.LTT_EVENT_REQUEST_ISSUE;
+
                        // @Override
                        public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) {
 
@@ -531,6 +582,11 @@ class StateUpdateHandlers {
                                return false;
 
                        }
+
+                       // @Override
+                       public Events getEventHandleType() {
+                               return eventType;
+                       }
                };
                return handler;
        }
@@ -545,9 +601,11 @@ class StateUpdateHandlers {
         * 
         * @return
         */
-       final ILttngEventProcessor getBdevRequestCompleteHandler() {
+       final IEventProcessing getBdevRequestCompleteHandler() {
                AbsStateUpdate handler = new AbsStateUpdate() {
 
+                       private Events eventType = Events.LTT_EVENT_REQUEST_COMPLETE;
+
                        // @Override
                        public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) {
 
@@ -586,6 +644,11 @@ class StateUpdateHandlers {
                                return false;
 
                        }
+
+                       // @Override
+                       public Events getEventHandleType() {
+                               return eventType;
+                       }
                };
                return handler;
        }
@@ -600,9 +663,11 @@ class StateUpdateHandlers {
         * 
         * @return
         */
-       final ILttngEventProcessor getFunctionEntryHandler() {
+       final IEventProcessing getFunctionEntryHandler() {
                AbsStateUpdate handler = new AbsStateUpdate() {
 
+                       private Events eventType = Events.LTT_EVENT_FUNCTION_ENTRY;
+
                        // @Override
                        public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) {
                                Long cpu = trcEvent.getCpuId();
@@ -613,6 +678,11 @@ class StateUpdateHandlers {
                                return false;
 
                        }
+
+                       // @Override
+                       public Events getEventHandleType() {
+                               return eventType;
+                       }
                };
                return handler;
        }
@@ -621,9 +691,11 @@ class StateUpdateHandlers {
         * 
         * @return
         */
-       final ILttngEventProcessor getFunctionExitHandler() {
+       final IEventProcessing getFunctionExitHandler() {
                AbsStateUpdate handler = new AbsStateUpdate() {
 
+                       private Events eventType = Events.LTT_EVENT_FUNCTION_EXIT;
+
                        // @Override
                        public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) {
 
@@ -634,6 +706,11 @@ class StateUpdateHandlers {
                                return false;
 
                        }
+
+                       // @Override
+                       public Events getEventHandleType() {
+                               return eventType;
+                       }
                };
                return handler;
        }
@@ -648,9 +725,11 @@ class StateUpdateHandlers {
         * 
         * @return
         */
-       final ILttngEventProcessor getDumpSyscallHandler() {
+       final IEventProcessing getDumpSyscallHandler() {
                AbsStateUpdate handler = new AbsStateUpdate() {
 
+                       private Events eventType = Events.LTT_EVENT_SYS_CALL_TABLE;
+
                        // @Override
                        public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) {
                                // obtain the syscall id
@@ -668,6 +747,11 @@ class StateUpdateHandlers {
 
                                return false;
                        }
+
+                       // @Override
+                       public Events getEventHandleType() {
+                               return eventType;
+                       }
                };
                return handler;
        }
@@ -682,9 +766,11 @@ class StateUpdateHandlers {
         * 
         * @return
         */
-       final ILttngEventProcessor getDumpKprobeHandler() {
+       final IEventProcessing getDumpKprobeHandler() {
                AbsStateUpdate handler = new AbsStateUpdate() {
 
+                       private Events eventType = Events.LTT_EVENT_KPROBE_TABLE;
+
                        // @Override
                        public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) {
 
@@ -697,6 +783,11 @@ class StateUpdateHandlers {
                                return false;
 
                        }
+
+                       // @Override
+                       public Events getEventHandleType() {
+                               return eventType;
+                       }
                };
                return handler;
        }
@@ -711,9 +802,11 @@ class StateUpdateHandlers {
         * 
         * @return
         */
-       final ILttngEventProcessor getDumpSoftIrqHandler() {
+       final IEventProcessing getDumpSoftIrqHandler() {
                AbsStateUpdate handler = new AbsStateUpdate() {
 
+                       private Events eventType = Events.LTT_EVENT_SOFTIRQ_VEC;
+
                        // @Override
                        public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) {
 
@@ -734,6 +827,11 @@ class StateUpdateHandlers {
                                return false;
 
                        }
+
+                       // @Override
+                       public Events getEventHandleType() {
+                               return eventType;
+                       }
                };
                return handler;
        }
@@ -748,9 +846,11 @@ class StateUpdateHandlers {
         * 
         * @return
         */
-       final ILttngEventProcessor getSchedChangeHandler() {
+       final IEventProcessing getSchedChangeHandler() {
                AbsStateUpdate handler = new AbsStateUpdate() {
 
+                       private Events eventType = Events.LTT_EVENT_SCHED_SCHEDULE;
+
                        // @Override
                        public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) {
 
@@ -878,6 +978,11 @@ class StateUpdateHandlers {
                                return false;
 
                        }
+
+                       // @Override
+                       public Events getEventHandleType() {
+                               return eventType;
+                       }
                };
                return handler;
        }
@@ -893,9 +998,11 @@ class StateUpdateHandlers {
         * 
         * @return
         */
-       final ILttngEventProcessor getProcessForkHandler() {
+       final IEventProcessing getProcessForkHandler() {
                AbsStateUpdate handler = new AbsStateUpdate() {
 
+                       private Events eventType = Events.LTT_EVENT_PROCESS_FORK;
+
                        // @Override
                        public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) {
 
@@ -1007,6 +1114,11 @@ class StateUpdateHandlers {
                                return false;
 
                        }
+
+                       // @Override
+                       public Events getEventHandleType() {
+                               return eventType;
+                       }
                };
                return handler;
        }
@@ -1021,9 +1133,11 @@ class StateUpdateHandlers {
         * 
         * @return
         */
-       final ILttngEventProcessor getProcessKernelThreadHandler() {
+       final IEventProcessing getProcessKernelThreadHandler() {
                AbsStateUpdate handler = new AbsStateUpdate() {
 
+                       private Events eventType = Events.LTT_EVENT_KTHREAD_CREATE;
+
                        // @Override
                        public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) {
                                /*
@@ -1058,6 +1172,11 @@ class StateUpdateHandlers {
                                return false;
 
                        }
+
+                       // @Override
+                       public Events getEventHandleType() {
+                               return eventType;
+                       }
                };
                return handler;
        }
@@ -1072,9 +1191,11 @@ class StateUpdateHandlers {
         * 
         * @return
         */
-       final ILttngEventProcessor getProcessExitHandler() {
+       final IEventProcessing getProcessExitHandler() {
                AbsStateUpdate handler = new AbsStateUpdate() {
 
+                       private Events eventType = Events.LTT_EVENT_PROCESS_EXIT;
+
                        // @Override
                        public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) {
 
@@ -1095,6 +1216,11 @@ class StateUpdateHandlers {
                                return false;
 
                        }
+
+                       // @Override
+                       public Events getEventHandleType() {
+                               return eventType;
+                       }
                };
                return handler;
        }
@@ -1109,9 +1235,11 @@ class StateUpdateHandlers {
         * 
         * @return
         */
-       final ILttngEventProcessor getProcessFreeHandler() {
+       final IEventProcessing getProcessFreeHandler() {
                AbsStateUpdate handler = new AbsStateUpdate() {
 
+                       private Events eventType = Events.LTT_EVENT_PROCESS_FREE;
+
                        // @Override
                        public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) {
 
@@ -1171,6 +1299,11 @@ class StateUpdateHandlers {
                                // return false;
 
                        }
+
+                       // @Override
+                       public Events getEventHandleType() {
+                               return eventType;
+                       }
                };
                return handler;
        }
@@ -1185,9 +1318,11 @@ class StateUpdateHandlers {
         * 
         * @return
         */
-       final ILttngEventProcessor getProcessExecHandler() {
+       final IEventProcessing getProcessExecHandler() {
                AbsStateUpdate handler = new AbsStateUpdate() {
 
+                       private Events eventType = Events.LTT_EVENT_EXEC;
+
                        // @Override
                        public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) {
 
@@ -1218,6 +1353,11 @@ class StateUpdateHandlers {
                                return false;
 
                        }
+
+                       // @Override
+                       public Events getEventHandleType() {
+                               return eventType;
+                       }
                };
                return handler;
        }
@@ -1232,9 +1372,11 @@ class StateUpdateHandlers {
         * 
         * @return
         */
-       final ILttngEventProcessor GetThreadBrandHandler() {
+       final IEventProcessing GetThreadBrandHandler() {
                AbsStateUpdate handler = new AbsStateUpdate() {
 
+                       private Events eventType = Events.LTT_EVENT_THREAD_BRAND;
+
                        // @Override
                        public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) {
 
@@ -1248,6 +1390,11 @@ class StateUpdateHandlers {
                                return false;
 
                        }
+
+                       // @Override
+                       public Events getEventHandleType() {
+                               return eventType;
+                       }
                };
                return handler;
        }
@@ -1255,9 +1402,11 @@ class StateUpdateHandlers {
        /**
         * @return
         */
-       final ILttngEventProcessor getStateDumpEndHandler() {
+       final IEventProcessing getStateDumpEndHandler() {
                AbsStateUpdate handler = new AbsStateUpdate() {
 
+                       private Events eventType = Events.LTT_EVENT_STATEDUMP_END;
+
                        // @Override
                        public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) {
 
@@ -1278,6 +1427,11 @@ class StateUpdateHandlers {
 
                        }
 
+                       // @Override
+                       public Events getEventHandleType() {
+                               return eventType;
+                       }
+
                        /**
                         * Private method used to establish the first execution state in the
                         * stack for a given process
@@ -1367,9 +1521,11 @@ class StateUpdateHandlers {
         * 
         * @return
         */
-       final ILttngEventProcessor getEnumProcessStateHandler() {
+       final IEventProcessing getEnumProcessStateHandler() {
                AbsStateUpdate handler = new AbsStateUpdate() {
 
+                       private Events eventType = Events.LTT_EVENT_PROCESS_STATE;
+
                        // @Override
                        public boolean process(LttngEvent trcEvent, LttngTraceState traceSt) {
 
@@ -1536,6 +1692,11 @@ class StateUpdateHandlers {
                                return false;
 
                        }
+
+                       // @Override
+                       public Events getEventHandleType() {
+                               return eventType;
+                       }
                };
                return handler;
        }
index b00fd22a0f5ae9b077070357e13c825aafd48be4..716e22449d672d641d9915d3ae5a04f1f3b32a6f 100644 (file)
@@ -1,5 +1,5 @@
 /*******************************************************************************
-+ * Copyright (c) 2009, 2010 Ericsson
+ * Copyright (c) 2009 Ericsson
  * 
  * All rights reserved. This program and the accompanying materials are
  * made available under the terms of the Eclipse Public License v1.0 which
@@ -14,420 +14,144 @@ package org.eclipse.linuxtools.lttng.state.experiment;
 import java.util.HashMap;
 import java.util.Map;
 
-import org.eclipse.linuxtools.lttng.TraceDebug;
-import org.eclipse.linuxtools.lttng.control.LttngCoreProviderFactory;
-import org.eclipse.linuxtools.lttng.control.LttngSyntheticEventProvider;
-import org.eclipse.linuxtools.lttng.event.LttngEvent;
-import org.eclipse.linuxtools.lttng.event.LttngSyntheticEvent;
-import org.eclipse.linuxtools.lttng.event.LttngSyntheticEvent.SequenceInd;
-import org.eclipse.linuxtools.lttng.model.LTTngTreeNode;
-import org.eclipse.linuxtools.lttng.signal.ILttExperimentSelectedListener;
-import org.eclipse.linuxtools.lttng.signal.StateExperimentListener;
-import org.eclipse.linuxtools.lttng.state.trace.IStateTraceManager;
-import org.eclipse.linuxtools.tmf.event.TmfEvent;
+import org.eclipse.linuxtools.lttng.state.IStateDataRequestListener;
+import org.eclipse.linuxtools.lttng.state.StateManager;
+import org.eclipse.linuxtools.tmf.component.TmfComponent;
 import org.eclipse.linuxtools.tmf.event.TmfTimeRange;
-import org.eclipse.linuxtools.tmf.experiment.TmfExperiment;
-import org.eclipse.linuxtools.tmf.request.ITmfEventRequest;
-import org.eclipse.linuxtools.tmf.request.TmfDataRequest;
-import org.eclipse.linuxtools.tmf.request.TmfEventRequest;
-import org.eclipse.linuxtools.tmf.signal.TmfExperimentUpdatedSignal;
-import org.eclipse.linuxtools.tmf.trace.ITmfTrace;
+import org.eclipse.linuxtools.tmf.signal.TmfSignalHandler;
+import org.eclipse.linuxtools.tmf.trace.TmfExperiment;
+import org.eclipse.linuxtools.tmf.trace.TmfExperimentSelectedSignal;
 
 /**
  * @author alvaro
  * 
  */
-public class StateExperimentManager extends LTTngTreeNode implements
-               ILttExperimentSelectedListener, IStateExperimentManager {
+public class StateExperimentManager extends TmfComponent {
        
        // ========================================================================
        // Data
        // =======================================================================
-       private LTTngTreeNode fSelectedExperiment = null; // one selected experiment
-                                                                                                               // supported
-       private final StateExperimentListener fexperimentListener;
-       private boolean fwaitForCompletion = false;
-       /**
-        * Used to route incoming events to proper trace manager, during check point
-        * building
-        */
-       private final Map<ITmfTrace, IStateTraceManager> ftraceToManagerMap = new HashMap<ITmfTrace, IStateTraceManager>();
-       private LttngSyntheticEvent syntheticEvent = null;
-       private ITmfEventRequest<LttngEvent> fStateCheckPointRequest = null;
-
+       
+       private final Map<String, StateManager> managersByID = new HashMap<String, StateManager>();
+       private TmfExperiment fExperiment = null; // one experiment supported
 
        // ========================================================================
        // Constructors
        // =======================================================================
-       public StateExperimentManager(Long id, String name) {
-               super(id, null, name, null);
-               fexperimentListener = new StateExperimentListener("Experiment Manager",
-                               this);
-       }
 
+       /**
+        * package level constructor, creation from factory
+        */
+       StateExperimentManager() {
+               super();
+       }
 
        // ========================================================================
        // Methods
        // =======================================================================
 
-//     /* (non-Javadoc)
-//      * @see org.eclipse.linuxtools.lttng.state.experiment.IStateExperimentManager#readExperimentTimeWindow(org.eclipse.linuxtools.tmf.event.TmfTimeRange, java.lang.String, org.eclipse.linuxtools.lttng.state.IStateDataRequestListener)
-//      */
-//     public ILttngSyntEventRequest readExperimentTimeWindow(TmfTimeRange trange,
-//                     Object source, IRequestStatusListener listener,
-//                     ITransEventProcessor processor) {
-//
-//             ILttngSyntEventRequest request = null;
-//
-//             // validate
-//             if (fSelectedExperiment != null) {
-//                     // Get all trace manager nodes
-//                     LTTngTreeNode[] traceMgrs = fSelectedExperiment.getChildren();
-//
-//                     if (traceMgrs != null && traceMgrs.length > 0) {
-//                             IStateTraceManager traceManager;
-//                             // Trigger one request per trace
-//                             for (LTTngTreeNode traceNode : traceMgrs) {
-//                                     traceManager = (IStateTraceManager) traceNode;
-//                                     request = traceManager.executeDataRequest(trange, source,
-//                                                     listener,
-//                                                     processor);
-//                             }
-//                     }
-//             } else {
-//                     if (fSelectedExperiment == null) {
-//                             TraceDebug.debug("No experiment selected");
-//                     }
-//             }
-//
-//             return request;
-//     }
-
-//     /* (non-Javadoc)
-//      * @see org.eclipse.linuxtools.lttng.state.experiment.IStateExperimentManager#readExperiment(java.lang.String, org.eclipse.linuxtools.lttng.state.IStateDataRequestListener)
-//      */
-//     @SuppressWarnings("unchecked")
-//     public void readExperiment(Object source, IRequestStatusListener listener,
-//                     ITransEventProcessor processor) {
-//             // validate
-//             if (fSelectedExperiment != null) {
-//                     TmfExperiment<LttngEvent> experiment = (TmfExperiment<LttngEvent>) fSelectedExperiment
-//                                     .getValue();
-//                     TmfTimeRange trange = experiment.getTimeRange();
-//                     readExperimentTimeWindow(trange, source, listener, processor);
-//             } else {
-//                     TraceDebug.debug("No selected experiment available");
-//             }
-//     }
-       
-
-
-       /*
-        * (non-Javadoc)
+       /**
+        * Return the Map of unique id to Manager instance
         * 
-        * @see
-        * org.eclipse.linuxtools.lttng.state.experiment.IStateExperimentManager
-        * #experimentSelected_prep
-        * (org.eclipse.linuxtools.tmf.experiment.TmfExperiment)
+        * @return
         */
-       public void experimentSelected_prep(TmfExperiment<LttngEvent> experiment) {
-               LTTngTreeNode experimentNode = null;
-               if (experiment != null) {
-                       experimentNode = getChildByName(experiment.getName());
-                       // keep experiment if already loaded with the same value
-                       if (experimentNode != null
-                                       && experimentNode.getValue() != experiment) {
-                               // rebuild the experiment nodes from scratch
-                               removeChild(experimentNode);
-                               experimentNode = null;
-                       }
-
-                       // Make sure all traces involved have a corresponding state manager
-                       // and
-                       // state system to request its initial data
-                       if (experimentNode == null) {
-                               // Create the new experiment tree node
-                               experimentNode = new LTTngTreeNode(getNextUniqueId(), this,
-                                               experiment.getName(), experiment);
-                               // add the new experiment to this children list
-                               addChild(experimentNode);
-                       }
-                       
-                       // Make sure the traces exists in the tree
-                       ITmfTrace[] rtraces = experiment.getTraces();
-                       String traceName;
-                       LTTngTreeNode traceStateManagerNode;
-                       // StateStacksHandler
-                       for (ITmfTrace rtrace : rtraces) {
-                               traceName = rtrace.getName();
-                               traceStateManagerNode = experimentNode.getChildByName(traceName);
-                               // Node does not exist for this experiment, so needs to be
-                               // created
-                               if (traceStateManagerNode == null) {
-                                       traceStateManagerNode = StateManagerFactory.getManager(
-                                                       rtrace, experimentNode);
-                                       experimentNode.addChild(traceStateManagerNode);
-                               }
-                       }
-
-                       // Reset event provider to handle requests for the new experiment
-                       LttngSyntheticEventProvider synEventProvider = LttngCoreProviderFactory
-                                       .getEventProvider();
-                       synEventProvider.reset(experimentNode);
-
-                       // preserve the selected experiment
-                       fSelectedExperiment = experimentNode;
-               }
+       public Map<String, StateManager> getManagersByID() {
+               return managersByID;
        }
 
-       /*
-        * (non-Javadoc)
+       /**
+        * Read all available traces from the nearest checkpoint from start position
+        * to the end of a specified time range
         * 
-        * @see org.eclipse.linuxtools.lttng.signal.ILttExperimentSelectedListener#
-        * experimentSelected(java.lang.Object,
-        * org.eclipse.linuxtools.tmf.experiment.TmfExperiment)
+        * @param trange
+        * @param obs
+        * @param transactionID
+        * @param display
         */
-       public void experimentSelected(Object source,
-                       TmfExperiment<LttngEvent> experiment) {
-               // validate
-               if (experiment == null) { 
-                       TraceDebug.debug("Received expriment is null");
-                       return;
+       public void readExperimentTimeWindow(TmfTimeRange trange,
+                       String transactionID, IStateDataRequestListener listener) {
+               if (fExperiment != null) {
+                       String id = fExperiment.getExperimentId();
+                       StateManager manager = managersByID.get(id);
+                       if (manager != null) {
+                               // TODO: A loop to request data for each trace needs to be used
+                               // here when multiple traces are supported.
+                               manager.executeDataRequest(trange, transactionID, listener);
+                       }
                }
+       }
 
-               // If previous request is ongoing, cancel it before requesting a new
-               // one.
-               if (fStateCheckPointRequest != null && !fStateCheckPointRequest.isCompleted()) {
-                       fStateCheckPointRequest.cancel();
+       public void readExperiment(String transactionID,
+                       IStateDataRequestListener listener) {
+               // Need someone to listen to the updates as well as an fExperiment
+               // loaded.
+               if (listener != null && fExperiment != null) {
+                       TmfTimeRange trange = fExperiment.getTimeRange();
+                       String experimentId = fExperiment.getExperimentId();
+
+                       // FIXME: there should be an id field available at the trace level
+                       // to be fixed with the support of multiple files.
+                       // We also need to iterate over the traces in the Experiment and
+                       // execute a data Request on each of them
+                       // This is also on hold till the request can be performed at a trace
+                       // level.
+                       // ITmfTrace[] fTraces = fExperiment.getTraces();
+                       // for (int i=0; i < fTraces.length; i++) {
+                       StateManager manager = StateManagerFactory.getManager(experimentId);
+                       manager.executeDataRequest(trange, transactionID, listener);
+                       // }
                }
-
-               // trigger data request to build the state system check points
-               fStateCheckPointRequest = buildCheckPoints(experiment);
-
-//             LTTngTreeNode experimentNode = getChildByName(experiment.getName());
-//             if (experimentNode != null) {
-//                     // get the trace manager nodes
-//                     LTTngTreeNode[] traceNodes = experimentNode.getChildren();
-//                     for (LTTngTreeNode traceStateManagerNode : traceNodes) {
-//                             // The trace node needs to perform its first data request
-//                             // for this experiment with the main goal of building its
-//                             // checkpoints
-//                             if (traceStateManagerNode instanceof ILttExperimentSelectedListener) {
-//                                     // no need to provide the trace to the trace manager
-//                                     ((ILttExperimentSelectedListener) traceStateManagerNode).experimentUpdated(
-//                                                     new TmfExperimentUpdatedSignal(source, experiment, null), fwaitForCompletion);
-//                             }
-//                     }
-//             }
        }
-
+       
        /*
         * (non-Javadoc)
         * 
-        * @see org.eclipse.linuxtools.lttng.signal.ILttExperimentSelectedListener#
-        * experimentUpdated
-        * (org.eclipse.linuxtools.tmf.signal.TmfExperimentUpdatedSignal, boolean)
+        * @see
+        * org.eclipse.linuxtools.tmf.eventlog.ITmfEventLogEventListener#handleEvent
+        * (org.eclipse.linuxtools.tmf.eventlog.ITmfEventLogEvent)
         */
-       public void experimentUpdated(TmfExperimentUpdatedSignal signal, boolean wait) {
-               // NOTE: This represents the end of TMF indexing for a trace, however
-               // the node was already existing and the state system check points are
-               // already requested and built upon selection.
-               // No action for the time being
+       @TmfSignalHandler
+       public void experimentSelected(TmfExperimentSelectedSignal signal) {
+               // TmfExperiment experiment = signal.getExperiment();
+               // ITmfTrace[] traces = experiment.getTraces();
+               // for (ITmfTrace trace : traces) {
+               //                      
+               // }
+               if (signal != null) {
+                       fExperiment = signal.getExperiment();
+                       traceSelected(fExperiment);
+               }
        }
 
-
        /**
-        * @return the SelectedExperiment tree node
+        * A new Experiment selected, notification received from the framework
+        * Notify the new log selection to the state handling managers
+        * 
+        * @param experiment
         */
-       public LTTngTreeNode getSelectedExperiment() {
-               return fSelectedExperiment;
+       private void traceSelected(TmfExperiment experiment) {
+               // TODO: Re-factor when multiple traces are supported
+               // traceId, as well as when the request can be specified at the trace
+               // level
+               // For the moment it does work for only one trace per experiment.
+               String experimentId = experiment.getExperimentId();
+               StateManager manager = StateManagerFactory.getManager(experimentId);
+               // TODO: clearAllData shall not be applied to all manager calls below
+               // since that would clean all data loaded within previous iterations in
+               // the future loop. i.e. It can be applied to first manager in the loop.
+               boolean clearAllData = true;
+               manager.setTraceSelection(experiment, clearAllData);
        }
 
-       /* (non-Javadoc)
-        * @see org.eclipse.linuxtools.lttng.state.experiment.IStateExperimentManager#getExperimentTimeRange()
+       /**
+        * @return
         */
-       @SuppressWarnings("unchecked")
        public TmfTimeRange getExperimentTimeRange() {
                TmfTimeRange timeRangeResult = null;
-               if (fSelectedExperiment != null) {
-                       timeRangeResult = ((TmfExperiment<LttngEvent>) fSelectedExperiment
-                                       .getValue()).getTimeRange();
+               if (fExperiment != null) {
+                       timeRangeResult = fExperiment.getTimeRange();
                }
                return timeRangeResult;
        }
 
-       /*
-        * (non-Javadoc)
-        * 
-        * @see java.lang.Object#finalize()
-        */
-       @Override
-       protected void finalize() {
-               fexperimentListener.dispose();
-       }
-
-
-       /*
-        * (non-Javadoc)
-        * 
-        * @see
-        * org.eclipse.linuxtools.lttng.state.experiment.IStateExperimentManager
-        * #waitForComplete(boolean)
-        */
-       public void waitForCompletion(boolean wait) {
-               fwaitForCompletion = wait;
-       }
-
-       private ITmfEventRequest<LttngEvent> buildCheckPoints(TmfExperiment<LttngEvent> experiment) {
-               // validate
-               if (experiment == null) {
-                       TraceDebug.debug("Received expriment is null");
-                       return null;
-               }
-               
-               LTTngTreeNode experimentNode = getChildByName(experiment.getName());
-               if (experimentNode == null) {
-                       TraceDebug.debug("Expriment Node " + experiment.getName() + " does not exist");
-                       return null;
-               }
-               
-               // get the trace manager nodes associated to the experiment
-               LTTngTreeNode[] traceNodes = experimentNode.getChildren();
-               synchronized (ftraceToManagerMap) {
-                       ftraceToManagerMap.clear();
-               }
-               
-               for (LTTngTreeNode traceStateManagerNode : traceNodes) {
-                       IStateTraceManager traceManager;
-                       try {
-                               traceManager = (IStateTraceManager) traceStateManagerNode;
-                       } catch (ClassCastException e) {
-                               System.out.println(e.getStackTrace().toString());
-                               return null;
-                       }
-               
-                       // Clear all previously created check points as preparation to
-                       // re-build
-                       traceManager.clearCheckPoints();
-               
-                       // build the trace to manager mapping for event dispatching
-                       synchronized (ftraceToManagerMap) {
-                               ftraceToManagerMap.put(traceManager.getTrace(), traceManager);
-                       }
-               }
-               
-               // if no trace mapping
-               if (ftraceToManagerMap.size() < 1) {
-                       TraceDebug.debug("No traces associated to experiment " + experiment.getName());
-                       return null;
-               }
-               
-               // Prepare event data request to build state model
-               ITmfEventRequest<LttngEvent> request = new TmfEventRequest<LttngEvent>(
-                               LttngEvent.class, TmfTimeRange.Eternity,
-                               TmfDataRequest.ALL_DATA, 1) {
-               
-                       Long nbEvents = 0L;
-               
-                       /*
-                        * (non-Javadoc)
-                        * 
-                        * @see
-                        * org.eclipse.linuxtools.tmf.request.TmfDataRequest#handleData()
-                        */
-                       @Override
-                       public void handleData() {
-                               TmfEvent[] events = getData();
-                               if (events.length > 0) {
-                                       nbEvents++;
-               
-                                       LttngEvent event = (LttngEvent) events[0];
-                                       ITmfTrace trace = event.getParentTrace();
-                                       IStateTraceManager traceManager = ftraceToManagerMap
-                                                       .get(trace);
-                                       if (traceManager != null) {
-                                               // obtain synthetic event
-                                               LttngSyntheticEvent synEvent = updateSynEvent(event,
-                                                               traceManager);
-                                               // update state system, and save check points as needed
-                                               traceManager.handleEvent(synEvent, nbEvents);
-                                       } else {
-                                               TraceDebug
-                                                               .debug("StateTraceManager not found for trace"
-                                                                               + trace.getName());
-                                       }
-                               }
-                       }
-               
-                       /*
-                        * (non-Javadoc)
-                        * 
-                        * @see
-                        * org.eclipse.linuxtools.tmf.request.TmfDataRequest#handleFailure()
-                        */
-                       public void handleFailure() {
-                               printCompletedMessage();
-                       }
-                       
-                       /*
-                        * (non-Javadoc)
-                        * 
-                        * @see
-                        * org.eclipse.linuxtools.tmf.request.TmfDataRequest#handleCancel()
-                        */
-                       public void handleCancel() {
-                               printCompletedMessage();
-                       }
-               
-                       /*
-                        * (non-Javadoc)
-                        * 
-                        * @see
-                        * org.eclipse.linuxtools.tmf.request.TmfDataRequest#handleSuccess()
-                        */
-                       public void handleSuccess() {
-                               printCompletedMessage();
-                       }
-               
-                       /**
-                        * @param header
-                        */
-                       private void printCompletedMessage() {
-                               // super.handleCompleted();
-                               if (TraceDebug.isDEBUG()) {
-                                       TraceDebug.debug("Trace check point building completed, number of events handled: " + nbEvents
-                                                       + "\n\t\t");
-                                       for (IStateTraceManager traceMgr : ftraceToManagerMap.values()) {
-                                               TraceDebug.debug(traceMgr.toString() + "\n\t\t");
-                                       }
-                               }
-                       }
-               };
-               
-               // Execute event data request
-               experiment.sendRequest(request);
-               if (fwaitForCompletion) {
-                       try {
-                               request.waitForCompletion();
-                       } catch (InterruptedException e) {
-                               e.printStackTrace();
-                       }
-               }
-               
-               return request;
-               }
-               
-               private LttngSyntheticEvent updateSynEvent(LttngEvent e,
-                               IStateTraceManager stateTraceManager) {
-                       if (syntheticEvent == null || syntheticEvent.getBaseEvent() != e) {
-                               syntheticEvent = new LttngSyntheticEvent(e);
-                       }
-               
-                       // Trace model needed by application handlers
-                       syntheticEvent.setTraceModel(stateTraceManager.getStateModel());
-                       syntheticEvent.setSequenceInd(SequenceInd.UPDATE);
-                               
-                       return syntheticEvent;
-               }
-
-}
\ No newline at end of file
+}
index b120b0bc56d9477da2cc290ffd376db15be0c6f6..b196ae4a7bc8e5a524f74cca2e46d83e83cee1ad 100644 (file)
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2009, 2010 Ericsson
+ * Copyright (c) 2009 Ericsson
  * 
  * All rights reserved. This program and the accompanying materials are
  * made available under the terms of the Eclipse Public License v1.0 which
 
 package org.eclipse.linuxtools.lttng.state.experiment;
 
-import org.eclipse.linuxtools.lttng.TraceDebug;
-import org.eclipse.linuxtools.lttng.model.LTTngTreeNode;
-import org.eclipse.linuxtools.lttng.state.LttngStateException;
-import org.eclipse.linuxtools.lttng.state.trace.IStateTraceManager;
-import org.eclipse.linuxtools.lttng.state.trace.StateTraceManager;
-import org.eclipse.linuxtools.tmf.experiment.TmfExperiment;
-import org.eclipse.linuxtools.tmf.trace.ITmfTrace;
+import java.util.Map;
+
+import org.eclipse.linuxtools.lttng.state.StateManager;
+import org.eclipse.linuxtools.lttng.state.StateStacksHandler;
+import org.eclipse.linuxtools.lttng.state.model.LttngTraceState;
+import org.eclipse.linuxtools.lttng.state.model.StateModelFactory;
 
 /**
  * @author alvaro
@@ -29,64 +28,36 @@ public class StateManagerFactory {
        // Data
        // =======================================================================
 
-       private static IStateExperimentManager experimentManager = null;
-       /**
-        * Allows to modify the check point interval for every new instance of trace manager
-        */
-       private static Long ftraceCheckPointInterval = null;
+       private static StateExperimentManager experimentManager = null;
+       private static Map<String, StateManager> instanceBook = null;
 
-       static {
-               initCheck();
-       }
        // ========================================================================
        // Methods
        // =======================================================================
 
        /**
-        * @param traceUniqueId
-        * @param experiment
+        * Provide a stateManager instance per trace
+        * 
         * @return
         */
-       public static LTTngTreeNode getManager(ITmfTrace rtrace,
-                       LTTngTreeNode experiment) {
+       public static StateManager getManager(String traceUniqueId) {
 
-               // Validate
-               if (rtrace == null) {
-                       return null;
-               }
-
-               String traceUniqueId = rtrace.getName();
                if (traceUniqueId == null) {
                        return null;
                }
 
+               initCheck();
 
-               LTTngTreeNode managerNode = null;
-               managerNode = experiment.getChildByName(traceUniqueId);
-
-               if (managerNode != null && managerNode instanceof IStateTraceManager) {
-                       return managerNode;
+               if (instanceBook.containsKey(traceUniqueId)) {
+                       return instanceBook.get(traceUniqueId);
                }
 
-//             LttngTraceState traceModel = 
-//             StateModelFactory.getStateEntryInstance();
-               StateTraceManager manager = null;
-
-               // catch potential construction problems
-               try {
-                       manager = new StateTraceManager(experiment.getNextUniqueId(), experiment, traceUniqueId, rtrace);
+               LttngTraceState traceModel = StateModelFactory.getStateEntryInstance();
+               StateStacksHandler stateInputHandler = new StateStacksHandler(
+                               traceModel);
+               StateManager manager = new StateManager(stateInputHandler);
 
-                       // Allow the possibility to configure the trace state check point
-                       // interval at creation time
-                       if (ftraceCheckPointInterval != null) {
-                               manager.setCheckPointInterval(ftraceCheckPointInterval);
-                       }
-
-               } catch (LttngStateException e) {
-                       e.printStackTrace();
-               }
-
-               experiment.addChild(manager);
+               instanceBook.put(traceUniqueId, manager);
                return manager;
        }
 
@@ -95,7 +66,8 @@ public class StateManagerFactory {
         * 
         * @return
         */
-       public static IStateExperimentManager getExperimentManager() {
+       public static StateExperimentManager getExperimentManager() {
+               initCheck();
                return experimentManager;
        }
 
@@ -104,18 +76,10 @@ public class StateManagerFactory {
         * 
         * @param traceUniqueId
         */
-       public static void removeManager(ITmfTrace rtrace, LTTngTreeNode rexperiment) {
-               Object experimentObj = rexperiment.getValue();
-               if (rtrace != null && rexperiment != null
-                               && experimentObj instanceof TmfExperiment<?>) {
-                       LTTngTreeNode childToremove = rexperiment.getChildByName(rtrace
-                                       .getName());
-                       if (childToremove != null) {
-                               rexperiment.removeChild(childToremove);
-                       }
-               } else {
-                       TraceDebug.debug("Invalid arguments to remove manager for trace: "
-                                       + rtrace.getName());
+       public static void removeManager(String traceUniqueId) {
+               initCheck();
+               if (traceUniqueId != null && instanceBook.containsKey(traceUniqueId)) {
+                       instanceBook.remove(traceUniqueId);
                }
        }
 
@@ -124,9 +88,8 @@ public class StateManagerFactory {
         */
        private static void initCheck() {
                if (experimentManager == null) {
-                       Long id = 0L; // unique id
-                       String name = "StateExperimentManager"; // name
-                       experimentManager = new StateExperimentManager(id, name);
+                       experimentManager = new StateExperimentManager();
+                       instanceBook = experimentManager.getManagersByID();
                }
        }
 
@@ -135,22 +98,9 @@ public class StateManagerFactory {
         */
        public static void dispose() {
                if (experimentManager != null) {
+                       experimentManager.dispose();
                        experimentManager = null;
+                       instanceBook = null;
                }
        }
-
-       /**
-        * @return the traceCheckPointInterval
-        */
-       public static Long getTraceCheckPointInterval() {
-               return ftraceCheckPointInterval;
-       }
-
-       /**
-        * @param traceCheckPointInterval
-        *            the traceCheckPointInterval to set
-        */
-       public static void setTraceCheckPointInterval(Long traceCheckPointInterval) {
-               StateManagerFactory.ftraceCheckPointInterval = traceCheckPointInterval;
-       }
-}
\ No newline at end of file
+}
diff --git a/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/model/ILttngStateInputRef.java b/org.eclipse.linuxtools.lttng/src/org/eclipse/linuxtools/lttng/state/model/ILttngStateInputRef.java
new file mode 100644 (file)
index 0000000..51584f5
--- /dev/null
@@ -0,0 +1,33 @@
+/*******************************************************************************
+ * Copyright (c) 2009 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:
+ *   Alvaro Sanchez-Leon (alvsan09@gmail.com) - Initial API and implementation
+ *******************************************************************************/
+package org.eclipse.linuxtools.lttng.state.model;
+
+import org.eclipse.linuxtools.tmf.event.TmfTimeRange;
+
+/**
+ * <b><u>ILttngStateModelInput</u></b>
+ * <p>Interface providing the data needed by the State model
+ * 
+ */
+
+/**
+ * @author alvaro
+ *
+ */
+public interface ILttngStateInputRef {
+       
+       public int getNumberOfCpus();
+       public TmfTimeRange getTraceTimeWindow();
+       public String getTraceId();
+       public TmfTimeRange getExperimentTimeWindow();
+
+}
index cb1183fee9088e621c9234b3d7ce5e30a2a7bcd5..4d0ff321e55c80e8afa8ebcb8a3c1eedbfc57dd0 100644 (file)
@@ -22,7 +22,6 @@ import org.eclipse.linuxtools.lttng.state.StateStrings.ExecutionMode;
 import org.eclipse.linuxtools.lttng.state.StateStrings.ExecutionSubMode;
 import org.eclipse.linuxtools.lttng.state.StateStrings.IRQMode;
 import org.eclipse.linuxtools.lttng.state.StateStrings.ProcessStatus;
-import org.eclipse.linuxtools.lttng.state.resource.ILttngStateContext;
 import org.eclipse.linuxtools.tmf.event.TmfTimeRange;
 
 /**
@@ -66,7 +65,7 @@ public class LttngTraceState implements Cloneable {
        private int nb_events = 0;
 
        // reference to input data provider
-       ILttngStateContext fContext = null;
+       ILttngStateInputRef inputDataRef = null;
        String traceId = "";
 
        // ========================================================================
@@ -132,7 +131,7 @@ public class LttngTraceState implements Cloneable {
                        newState.irq_names = this.irq_names;
 
                        // This reference should never need to be updated, should it?
-                       newState.fContext = this.fContext;
+                       newState.inputDataRef = this.inputDataRef;
 
                        // *** We need loop on each ArrayList and HashMap, as java implement
                        // nothing that's remotely near deep copying.
@@ -206,19 +205,19 @@ public class LttngTraceState implements Cloneable {
                return newState;
        }
 
-       public void init(ILttngStateContext context)
+       public void init(ILttngStateInputRef inputReference)
                        throws LttngStateException {
-               if (context == null) {
+               if (inputReference == null) {
                        StringBuilder sb = new StringBuilder(
                                        "The input provider reference must not be null");
                        throw new LttngStateException(sb.toString());
                }
 
                // Save the input data reference
-               fContext = context;
+               inputDataRef = inputReference;
 
                // Save traceid
-               traceId = fContext.getTraceId();
+               traceId = inputDataRef.getTraceId();
 
                // max time
                max_time_state_recomputed_in_seek = 0L;
@@ -228,7 +227,7 @@ public class LttngTraceState implements Cloneable {
                
                // Obtain the total num of available CPUs and initialize the map
                // to the corresponding size
-               int numCpus = fContext.getNumberOfCpus();
+               int numCpus = inputDataRef.getNumberOfCpus();
                for (Long i = 0L; i < numCpus; i++) {
                        cpu_states.put(i, new LTTngCPUState());
                }
@@ -257,7 +256,7 @@ public class LttngTraceState implements Cloneable {
                processes.clear();
 
                nb_events = 0;
-               TmfTimeRange timeWin = fContext.getTraceTimeWindow();
+               TmfTimeRange timeWin = inputDataRef.getTraceTimeWindow();
 
                /* Put the per cpu running_process to beginning state : process 0. */
                for (Long i = 0L; i < numCpus; i++) {
@@ -327,7 +326,7 @@ public class LttngTraceState implements Cloneable {
         * @return total number of CPUs registered as read from the Trace
         */
        public int getNumberOfCPUs() {
-               return fContext.getNumberOfCpus();
+               return inputDataRef.getNumberOfCpus();
        }
 
        /**
@@ -335,8 +334,8 @@ public class LttngTraceState implements Cloneable {
         * 
         * @return
         */
-       public ILttngStateContext getContext() {
-               return fContext;
+       public ILttngStateInputRef getInputDataRef() {
+               return inputDataRef;
        }
 
        public Long getMax_time_state_recomputed_in_seek() {
index 94dba7db071b43ee84243dcf32d6383f89aca841..d1c3394a364ed9a23e2aa8286da2e13885337fa2 100644 (file)
@@ -23,16 +23,11 @@ public class LttngTrapState implements Cloneable {
        // Data
     // =======================================================================
        private Long running;
-       
+
        
     // ========================================================================
     // Constructor
     // =======================================================================
-       
-       public LttngTrapState() {
-               this.running = 0L;
-       }
-       
        public LttngTrapState(Long running) {
                this.running = running;
        }
@@ -77,10 +72,4 @@ public class LttngTrapState implements Cloneable {
                        running--;                      
                }
        }
-       
-       @Override
-       public String toString() {
-               return "running : " + running;
-       }
-       
 }
\ No newline at end of file
index 8ab180e11961abfb173931274137b56a01e8a447..81c806b22280e0f398170ba1ba71e9ac1dfb32fb 100644 (file)
@@ -12,7 +12,6 @@
 package org.eclipse.linuxtools.lttng.state.model;
 
 import org.eclipse.linuxtools.lttng.state.LttngStateException;
-import org.eclipse.linuxtools.lttng.state.resource.ILttngStateContext;
 
 /**
  * Entry point to the package
@@ -48,7 +47,7 @@ public class StateModelFactory {
         * @return
         */
        public static LttngTraceState getStateEntryInstance(
-                       ILttngStateContext stateInputRef) {
+                       ILttngStateInputRef stateInputRef) {
                LttngTraceState traceState = new LttngTraceState();
                try {
                        traceState.init(stateInputRef);
index 8fa150d0ed4079f8ae5fd2bcbd7f557551cba2cc..61612f81c6eb0c0807c77ac5164ab54ee8d15be9 100644 (file)
@@ -15,6 +15,7 @@ package org.eclipse.linuxtools.lttng.trace;
 import java.io.BufferedReader;
 import java.io.FileReader;
 import java.io.IOException;
+import java.util.Collections;
 import java.util.HashMap;
 
 import org.eclipse.linuxtools.lttng.event.LttngEvent;
@@ -25,16 +26,16 @@ import org.eclipse.linuxtools.lttng.event.LttngEventSource;
 import org.eclipse.linuxtools.lttng.event.LttngEventType;
 import org.eclipse.linuxtools.lttng.event.LttngTimestamp;
 import org.eclipse.linuxtools.lttng.jni.JniEvent;
-import org.eclipse.linuxtools.tmf.event.TmfNoSuchFieldException;
+import org.eclipse.linuxtools.tmf.event.TmfEvent;
 import org.eclipse.linuxtools.tmf.event.TmfTimeRange;
-import org.eclipse.linuxtools.tmf.trace.ITmfLocation;
+import org.eclipse.linuxtools.tmf.event.TmfTimestamp;
+import org.eclipse.linuxtools.tmf.request.ITmfRequestHandler;
 import org.eclipse.linuxtools.tmf.trace.ITmfTrace;
-import org.eclipse.linuxtools.tmf.trace.TmfCheckpoint;
-import org.eclipse.linuxtools.tmf.trace.TmfContext;
-import org.eclipse.linuxtools.tmf.trace.TmfLocation;
 import org.eclipse.linuxtools.tmf.trace.TmfTrace;
+import org.eclipse.linuxtools.tmf.trace.TmfTraceCheckpoint;
+import org.eclipse.linuxtools.tmf.trace.TmfTraceContext;
 
-public class LTTngTextTrace extends TmfTrace<LttngEvent> implements ITmfTrace {
+public class LTTngTextTrace extends TmfTrace implements ITmfTrace, ITmfRequestHandler<TmfEvent> {
        private LttngTimestamp                  eventTimestamp   = null;
     private LttngEventSource                eventSource      = null;
     private LttngEventType                  eventType        = null;
@@ -59,7 +60,7 @@ public class LTTngTextTrace extends TmfTrace<LttngEvent> implements ITmfTrace {
     }
     
     public LTTngTextTrace(String path, boolean skipIndexing) throws Exception {
-        super(path, LttngEvent.class, path, 1);
+        super(path, 1, true);
         
         tracepath = path;
         traceTypes      = new HashMap<String, LttngEventType>();
@@ -70,27 +71,27 @@ public class LTTngTextTrace extends TmfTrace<LttngEvent> implements ITmfTrace {
         eventContent          = new TextLttngEventContent(currentLttngEvent);
         eventReference        = new LttngEventReference(this.getName());
         
-        currentLttngEvent = new TextLttngEvent(this, eventTimestamp, eventSource, eventType, eventContent, eventReference);
+        currentLttngEvent = new TextLttngEvent(eventTimestamp, eventSource, eventType, eventContent, eventReference);
         eventContent.setEvent(currentLttngEvent);
         
         if ( positionToFirstEvent() == false ) {
                throw new IOException("Fail to position to the beginning of the trace");
         }
         else {
-               fIndexPageSize = 1000;
+               fCacheSize = 1000;
                
                // Skip indexing if asked
-//             if ( skipIndexing == true ) {
-                       fCheckpoints.add(new TmfCheckpoint(new LttngTimestamp(0L), new TmfLocation<Long>(0L)));
-//             }
-//             else {
-//                     indexTrace(true);
-//             }
+               if ( skipIndexing == true ) {
+                       fCheckpoints.add(new TmfTraceCheckpoint(new LttngTimestamp(0L), 0L));
+               }
+               else {
+                       indexStream();
+               }
                
                Long endTime = currentLttngEvent.getTimestamp().getValue();
                positionToFirstEvent();
                
-               getNextEvent(new TmfContext(null, 0));
+               getNextEvent(new TmfTraceContext(null, null, 0));
                Long starTime = currentLttngEvent.getTimestamp().getValue();
                positionToFirstEvent();
                
@@ -101,27 +102,59 @@ public class LTTngTextTrace extends TmfTrace<LttngEvent> implements ITmfTrace {
     }
     
     
-    public LTTngTextTrace(LTTngTextTrace oldTrace) throws Exception { 
-       this(oldTrace.getPath(), true);
-       
-       // *** VERIFY ***
-       // Is this safe?
-       fCheckpoints = oldTrace.fCheckpoints;
+    private LTTngTextTrace(LTTngTrace oldStream) throws Exception { 
+       super(null);
+       throw new Exception("Copy constructor should never be use with a LTTngTrace!");
     }
     
-       public LTTngTextTrace createTraceCopy() {
-               
-               LTTngTextTrace returnedTrace = null;
-       
-       try {
-               returnedTrace = new LTTngTextTrace(this);
-       }
-       catch (Exception e) {
-               System.out.println("ERROR : Could not create LTTngTextTrace copy (createTraceCopy).\nError is : " + e.getStackTrace());
-       }
-       
-       return returnedTrace;
-       }
+    @Override
+    public void indexStream() {
+       // Position the trace at the beginning
+        TmfTraceContext context = seekLocation(null);
+        
+               long nbEvents=1L;
+               fCheckpoints.add(new TmfTraceCheckpoint(new LttngTimestamp(0L), 0L));
+               
+               LttngTimestamp startTime = null;
+               LttngTimestamp lastTime  = new LttngTimestamp();
+               LttngTimestamp timestamp = null;
+        Long previousCharRead = 0L;
+        
+        TextLttngEvent tmpEvent = (TextLttngEvent)getNextEvent(context);
+        
+        while ( tmpEvent != null) {
+               timestamp = (LttngTimestamp)context.getTimestamp();
+               previousCharRead = nbCharRead;
+               
+               if ( startTime == null ) {
+                       startTime = new LttngTimestamp(timestamp.getValue());
+               }
+               
+               if ((++nbEvents % fCacheSize) == 0) {
+                       fCheckpoints.add(new TmfTraceCheckpoint(new LttngTimestamp(timestamp.getValue()), previousCharRead));
+               }
+               
+               tmpEvent = (TextLttngEvent)getNextEvent(context);
+        }
+        
+        if (timestamp != null) {
+                       lastTime.setValue(timestamp.getValue());
+                               
+                       setTimeRange( new TmfTimeRange(startTime, lastTime) );
+                       notifyListeners(getTimeRange());
+               }
+        
+        fNbEvents = nbEvents;
+        
+        if ( showDebug == true ) {
+               for ( int pos=0; pos < fCheckpoints.size(); pos++) {
+                       System.out.print(pos + ": " + "\t");
+                       System.out.print( fCheckpoints.get(pos).getTimestamp() + "\t" );
+                       System.out.println( fCheckpoints.get(pos).getLocation() );
+               }
+        }
+        
+    }
     
     private boolean positionToFirstEvent() {
        
@@ -150,23 +183,15 @@ public class LTTngTextTrace extends TmfTrace<LttngEvent> implements ITmfTrace {
        return isSuccessful;
     }
     
-    private void skipToPosition(TmfLocation<Long> skip) {
+    private void skipToPosition(Long skipPosition) {
        try {
-                       long skipPosition = skip.getLocation();
-                       if ( skipPosition < 0 ) {
-                               skipPosition = 0L;
-                       }
-               
                                if ( showDebug == true ) {
                                        System.out.println("skipToPosition(Long skipPosition)");
                                        System.out.println("\tSkipping to : " + skipPosition);
                                        System.out.println();
                                }
                                positionToFirstEvent();
-                               long nbSkipped = br.skip(skipPosition);
-                               if ( nbSkipped != skipPosition) {
-                                       throw new IOException("Too few characters skipped, positionning failed! (skipToPosition)");
-                               }
+                               br.skip(skipPosition);
                                
                                nbCharRead = skipPosition;
        }
@@ -175,23 +200,134 @@ public class LTTngTextTrace extends TmfTrace<LttngEvent> implements ITmfTrace {
        }
     }
     
-    @Override
-       @SuppressWarnings("unchecked")
-       public TmfContext seekLocation(ITmfLocation<?> location) {
+    public TmfTraceContext seekLocation(Object location) {
        if (location == null) {
-               location = new TmfLocation<Long>(0L);
+               location = 0L;
        }
-
-       if (!((TmfLocation<Long>) location).getLocation().equals(nbCharRead)) {
-               skipToPosition((TmfLocation<Long>) location);
+       
+       TmfTraceContext tmpTraceContext =  new TmfTraceContext(nbCharRead, (LttngTimestamp)currentLttngEvent.getTimestamp(), 0L);
+               Long previousCharRead = nbCharRead;
+        Long previousTimestamp = currentLttngEvent.getTimestamp().getValue();
+       Long tmploc = (Long)location;
+               
+               if ( showDebug == true ) {
+                       System.out.println("seekLocation(Object location)");
+               System.out.println("\ttimestamp: " + (LttngTimestamp)currentLttngEvent.getTimestamp());
+               System.out.println("\tnbCharRead:" + nbCharRead);
+               System.out.println("\tlocation:  " + location);
+               System.out.println();
        }
-
-       TmfContext tmpTraceContext =  new TmfContext(location, 0L);
+               
+               if ( tmploc < nbCharRead ) {
+                       skipToPosition(tmploc);
+               }
+               
+               if ( tmploc > nbCharRead ) {
+                       while ( tmploc > nbCharRead ) {
+                               previousCharRead = nbCharRead;
+                       previousTimestamp = currentLttngEvent.getTimestamp().getValue();
+                               getNextEvent(tmpTraceContext);
+                       }
+               }
+               
+               tmpTraceContext.setTimestamp(new LttngTimestamp(previousTimestamp));
+               tmpTraceContext.setLocation(previousCharRead);
        
        return tmpTraceContext;
     }
     
-     private LttngEvent parseMyNextEvent(TmfContext context) {
+    
+    @Override
+    public TmfTraceContext seekEvent(TmfTimestamp timestamp) {
+
+       if (timestamp == null) {
+               timestamp = getStartTime();
+       }
+        
+       int index = Collections.binarySearch(fCheckpoints, new TmfTraceCheckpoint(timestamp, 0));
+       
+        if (index < 0) {
+            index = 0;
+        }
+        
+        Object location = (index < fCheckpoints.size()) ? fCheckpoints.elementAt(index).getLocation() : null;
+        
+       if ( showDebug == true ) {
+               System.out.println("seekEvent(TmfTimestamp timestamp)");
+               System.out.println("\ttimestamp: " + timestamp.getValue());
+               System.out.println("\tindex:     " + index);
+               System.out.println("\tlocation:  " + location);
+               System.out.println();
+       }
+       
+       // *** HACK ***
+       // We only know the timestamp AFTER we read the actual event
+       // For this reason, we save the current "position" in byte (nbCharRead) and we seek back 1 event after we find our event
+        TmfTraceContext currentEventContext = seekLocation(location);
+        
+        Long previousCharRead = nbCharRead;
+        Long previousTimestamp = currentLttngEvent.getTimestamp().getValue();
+        TmfEvent event = getNextEvent(currentEventContext);
+        
+        while ( (event != null) && (event.getTimestamp().getValue() < timestamp.getValue()) ) {
+               previousCharRead = nbCharRead;
+               previousTimestamp = currentLttngEvent.getTimestamp().getValue();
+               event = getNextEvent(currentEventContext);
+        }
+        
+        if ( event != null ) {
+               skipToPosition(previousCharRead);
+               currentEventContext.setLocation(previousCharRead);
+               currentEventContext.setTimestamp(new LttngTimestamp(previousTimestamp));
+        }
+        
+        return currentEventContext;
+    }
+    
+    @Override
+    public TmfTraceContext seekEvent(long position) {
+       
+        int checkPointPos = ((int)position / fCacheSize);
+        
+        Object location;
+        location = ( checkPointPos < fCheckpoints.size()) ? fCheckpoints.elementAt(checkPointPos).getLocation() : null;
+        
+        long index = ((position / fCacheSize)*fCacheSize)-1;
+        
+        if ( index < 0) { 
+               index = 0; 
+        }
+        
+       if ( showDebug == true ) {
+               System.out.println("seekEvent(long position)");
+               System.out.println("\tposition:  " + position);
+               System.out.println("\tindex:     " + index);
+               System.out.println("\tlocation:  " + location);
+               System.out.println();
+       }
+        TmfTraceContext currentEventContext = seekLocation(location);
+        Long previousCharRead = (Long)currentEventContext.getLocation();
+        Long previousTimestamp = currentEventContext.getTimestamp().getValue();
+        
+        TmfEvent event = null;
+        while (index < position) {
+               event = getNextEvent(currentEventContext);
+               previousCharRead = nbCharRead;
+               previousTimestamp = currentLttngEvent.getTimestamp().getValue();
+               index++;
+        }
+        
+        if ( event != null ) {
+               skipToPosition(previousCharRead);
+               currentEventContext.setLocation(previousCharRead);
+               currentEventContext.setTimestamp(new LttngTimestamp(previousTimestamp));
+        }
+        
+        return currentEventContext;
+    }
+    
+    @Override
+    public TmfEvent getNextEvent(TmfTraceContext context) {
        
        // All parsing variables declared here so to be able to print them into the catch if needed
        String tmpContent = null;
@@ -236,14 +372,14 @@ public class LTTngTextTrace extends TmfTrace<LttngEvent> implements ITmfTrace {
                        
                        // *** HACK ***
                        // Evil exit case here : the two last line of the text dump does not contain "."
-                       // We should check in a better way (string comparison and such) but it make the whole process to weight a lot more
+                       // We should check in a better way (string comparaison and such) but it make the whole process to weight a lot more
                        // Conclusion : this is ugly but fast.
                        if ( tmpCurIndex < 0 ) {
                                if ( showDebug == true ) {
                                        System.out.println("END OF FILE.");
                                        System.out.println();
                                }
-                               return null;
+                               return returnedEvent;
                        }
                        
                        tracefile = tmpContent.substring(tmpPrevIndex, tmpCurIndex ).trim();
@@ -394,6 +530,9 @@ public class LTTngTextTrace extends TmfTrace<LttngEvent> implements ITmfTrace {
                        currentLttngEvent.setContent(eventContent);
                        currentLttngEvent.setType(traceTypes.get(tmpTypeKey));
                        
+                       context.setTimestamp(eventTimestamp);
+                       context.setLocation(nbCharRead);
+                       
                        returnedEvent = currentLttngEvent;
                }
                else if ( showDebug == true ) {
@@ -417,18 +556,34 @@ public class LTTngTextTrace extends TmfTrace<LttngEvent> implements ITmfTrace {
     }
     
     @Override
-    public ITmfLocation<?> getCurrentLocation() {
-       return new TmfLocation<Long>(nbCharRead);
+    public Object getCurrentLocation() {
+       return nbCharRead;
     }
     
-       @Override
-       public LttngEvent parseEvent(TmfContext context) {
-               context = seekLocation(context.getLocation());
-               return parseMyNextEvent(context);
+    @Override
+       public LttngEvent parseEvent(TmfTraceContext context) {
+               Long location = null;
+               LttngEvent returnedEvent = null;
+               
+               if ( (currentLttngEvent!= null) && (! currentLttngEvent.getTimestamp().equals(context.getTimestamp()) ) ) {
+                       seekEvent(context.getTimestamp());
+                       getNextEvent(context);
+               }
+               
+               if ( currentLttngEvent != null ) {
+                   returnedEvent = currentLttngEvent;
+               }
                
+               location = (Long)getCurrentLocation();
+       
+               context.setLocation(location);
+               context.setTimestamp(currentLttngEvent.getTimestamp());
+               context.incrIndex();
+               
+               return returnedEvent;
     }
     
-       public int getCpuNumber() {
+    public int getCpuNumber() {
        return cpuNumber;
     }
 }
@@ -437,19 +592,17 @@ public class LTTngTextTrace extends TmfTrace<LttngEvent> implements ITmfTrace {
 // Redefine event to override method we know won't work with a Text tracefile 
 class TextLttngEvent extends LttngEvent {
        
-       public TextLttngEvent(  TmfTrace<LttngEvent> parent,
-                                                       LttngTimestamp timestamp, 
+       public TextLttngEvent(  LttngTimestamp timestamp, 
                                                        LttngEventSource source, 
                                                        LttngEventType type, 
                                                        LttngEventContent content, 
                                                        LttngEventReference reference) 
        {
-               super(parent, timestamp, source, type, content, reference, null);
+               super(timestamp, source, type, content, reference, null);
        }
        
        public TextLttngEvent(TextLttngEvent oldEvent) {
                this(
-                               oldEvent.getParentTrace(),
                                (LttngTimestamp)oldEvent.getTimestamp(), 
                                (LttngEventSource)oldEvent.getSource(), 
                                (LttngEventType)oldEvent.getType(), 
@@ -504,15 +657,12 @@ class TextLttngEventContent extends LttngEventContent {
     @Override
     public LttngEventField getField(int position) {
        LttngEventField returnedField = null;
-       String label = null;
-               try {
-                       label = fParentEvent.getType().getLabel(position);
-                       returnedField = this.getField(label);
-               } 
-               catch (TmfNoSuchFieldException e) {
-                       System.out.println("Invalid field position requested : " + position + ", ignoring (getField).");
-               }
+       String label = fParentEvent.getType().getLabel(position);
+        
+        if ( label != null ) {
+            returnedField = this.getField(label);
+        }
         
         return returnedField;
     }
-}
\ No newline at end of file
+}
index a9496e603cb1c2a4e3649c6419ed3cefdd02cda0..c1b75ba8b42f8f30e59a2f55f08dd189ca5f03fa 100644 (file)
@@ -22,20 +22,16 @@ import org.eclipse.linuxtools.lttng.event.LttngEventContent;
 import org.eclipse.linuxtools.lttng.event.LttngEventReference;
 import org.eclipse.linuxtools.lttng.event.LttngEventSource;
 import org.eclipse.linuxtools.lttng.event.LttngEventType;
-import org.eclipse.linuxtools.lttng.event.LttngLocation;
 import org.eclipse.linuxtools.lttng.event.LttngTimestamp;
 import org.eclipse.linuxtools.lttng.jni.JniEvent;
 import org.eclipse.linuxtools.lttng.jni.JniMarker;
+import org.eclipse.linuxtools.lttng.jni.JniTime;
 import org.eclipse.linuxtools.lttng.jni.JniTrace;
 import org.eclipse.linuxtools.lttng.jni.JniTracefile;
-import org.eclipse.linuxtools.lttng.jni.common.JniTime;
-import org.eclipse.linuxtools.lttng.jni.exception.JniException;
-import org.eclipse.linuxtools.lttng.jni.factory.JniTraceFactory;
 import org.eclipse.linuxtools.tmf.event.TmfTimeRange;
 import org.eclipse.linuxtools.tmf.event.TmfTimestamp;
-import org.eclipse.linuxtools.tmf.trace.ITmfLocation;
-import org.eclipse.linuxtools.tmf.trace.TmfContext;
 import org.eclipse.linuxtools.tmf.trace.TmfTrace;
+import org.eclipse.linuxtools.tmf.trace.TmfTraceContext;
 
 
 class LTTngTraceException extends LttngException {
@@ -52,38 +48,25 @@ class LTTngTraceException extends LttngException {
  * LTTng trace implementation. It accesses the C trace handling library
  * (seeking, reading and parsing) through the JNI component.
  */
-public class LTTngTrace extends TmfTrace<LttngEvent> {
-       
-       public static boolean printDebug = false;
-       public static boolean uniqueEvent = false;
-       
-    private final static boolean SHOW_LTT_DEBUG_DEFAULT    = false;
-       private final static boolean IS_PARSING_NEEDED_DEFAULT = true;
-       private final static int     CHECKPOINT_PAGE_SIZE      = 1000;
+public class LTTngTrace extends TmfTrace {
+    private final static boolean SHOW_LTT_DEBUG_DEFAULT = false;
+       private final static boolean IS_PARSING_NEEDED_DEFAULT = false;
+       private final static int     CHECKPOINT_PAGE_SIZE      = 1;
     
     // Reference to our JNI trace
     private JniTrace currentJniTrace = null;
     
-    // *** 
-    //   UNHACKED :    We can no longer do that because TCF need to maintain several events at once.
-    //                                 This is very slow to do so in LTTng, this has to be temporary.
-    //                 *** HACK ***
-    //                 To save time, we will declare all component of the LttngEvent during the construction of the trace
-    //         Then, while reading the trace, we will just SET the values instead of declaring new object
-    // ***
+    // *** HACK ***
+    // To save time, we will declare all component of the LttngEvent during the construction of the trace
+    //  Then, while reading the trace, we will just SET the values instead of declaring new object
     LttngTimestamp                  eventTimestamp   = null;
     LttngEventSource                eventSource      = null;
+    LttngEventType                  eventType        = null;
     LttngEventContent               eventContent     = null;
     LttngEventReference             eventReference   = null;
-    
-    
     // The actual event
     LttngEvent                      currentLttngEvent = null;             
     
-    // The current location
-    LttngLocation                                      previousLocation  = null;
-    
-    LttngEventType                  eventType        = null;
     // Hashmap of the possible types of events (Tracefile/CPU/Marker in the JNI)
     HashMap<String, LttngEventType> traceTypes       = null;
     // This vector will be used to quickly find a marker name from a position 
@@ -125,14 +108,20 @@ public class LTTngTrace extends TmfTrace<LttngEvent> {
      * 
      */
     public LTTngTrace(String path, boolean waitForCompletion, boolean bypassIndexing) throws Exception {
-        super(path, LttngEvent.class, path, CHECKPOINT_PAGE_SIZE);
+        super(path, CHECKPOINT_PAGE_SIZE, true);
         try {
-               currentJniTrace = JniTraceFactory.getJniTrace(path, SHOW_LTT_DEBUG_DEFAULT);
+               currentJniTrace = new JniTrace(path, SHOW_LTT_DEBUG_DEFAULT);
         }
         catch (Exception e) {
             throw new LTTngTraceException(e.getMessage());
         }
         
+        // Set the start time of the trace
+        setTimeRange( new TmfTimeRange( new LttngTimestamp(currentJniTrace.getStartTime().getTime()), 
+                                                                   new LttngTimestamp(currentJniTrace.getEndTime().getTime())
+                                      )
+                    );
+        
         // Export all the event types from the JNI side 
         traceTypes      = new HashMap<String, LttngEventType>();
         traceTypeNames  = new Vector<String>();
@@ -147,114 +136,29 @@ public class LTTngTrace extends TmfTrace<LttngEvent> {
         eventReference        = new LttngEventReference(this.getName());
         
         // Create the skeleton event
-        currentLttngEvent = new LttngEvent(this, eventTimestamp, eventSource, eventType, eventContent, eventReference, null);
-        
-        // Create a new current location
-        previousLocation = new LttngLocation();
-        
+        currentLttngEvent = new LttngEvent(eventTimestamp, eventSource, eventType, eventContent, eventReference, null);
         
         // Set the currentEvent to the eventContent
         eventContent.setEvent(currentLttngEvent);
         
-//        // Bypass indexing if asked
-//        if ( bypassIndexing == false ) {
-//            indexTrace(true);
-//        }
-//        else {
-               // Even if we don't have any index, set ONE checkpoint
-//             fCheckpoints.add(new TmfCheckpoint(new LttngTimestamp(0L) , new LttngLocation() ) );
-               
-               // Set the start time of the trace
-               setTimeRange( new TmfTimeRange( new LttngTimestamp(currentJniTrace.getStartTime().getTime()), 
-                                                                       new LttngTimestamp(currentJniTrace.getEndTime().getTime())
-                                         ) );
-//        }
+        // Bypass indexing if asked
+        if ( bypassIndexing == false ) {
+            indexStream();
+        }
     }
     
     /*
      * Copy constructor is forbidden for LttngEvenmStream
      * 
+     * Events are only valid for a very limited period of time and
+     *   JNI library does not support multiple access at once (yet?).
+     * For this reason, copy constructor should NEVER be used.
      */
-    public LTTngTrace(LTTngTrace oldTrace) throws Exception { 
-       this(oldTrace.getPath(), false, true);
-       
-       // *** VERIFY ***
-       // Is this safe?
-       this.fCheckpoints = oldTrace.fCheckpoints;
-       
-       /*
-       // This would only work if the index is already done
-       this.fCheckpoints = new Vector<TmfCheckpoint>( oldTrace.fCheckpoints.size() );
-       for (int x = 0; x<oldTrace.fCheckpoints.size(); x++){
-               TmfCheckpoint tmpCheckPoint = oldTrace.fCheckpoints.get(x);
-               this.fCheckpoints.add( new TmfCheckpoint(tmpCheckPoint.getTimestamp(), tmpCheckPoint.getLocation()) );
-       }
-       */
-       
-       // Set the start time of the trace
-       setTimeRange( new TmfTimeRange( new LttngTimestamp(oldTrace.getStartTime()), 
-                                                               new LttngTimestamp(oldTrace.getEndTime()))
-                                         );
-    }
-    
-    public LTTngTrace createTraceCopy() { 
-       LTTngTrace returnedTrace = null;
-       
-       try {
-               returnedTrace = new LTTngTrace(this);
-       }
-       catch (Exception e) {
-               System.out.println("ERROR : Could not create LTTngTrace copy (createTraceCopy).\nError is : " + e.getStackTrace());
-       }
-       
-       return returnedTrace;
-    }
-    
-    @Override
-    public LTTngTrace clone() {
-       LTTngTrace clone = null;
-       try {
-               clone = (LTTngTrace) super.clone();
-                       try {
-                               clone.currentJniTrace = JniTraceFactory.getJniTrace(getPath(), SHOW_LTT_DEBUG_DEFAULT);
-                       } catch (JniException e) {
-                               e.printStackTrace();
-                       }
-            
-            // Export all the event types from the JNI side 
-                       clone.traceTypes      = new HashMap<String, LttngEventType>();
-                       clone.traceTypeNames  = new Vector<String>();
-                       clone.initialiseEventTypes(clone.currentJniTrace);
-            
-            // Verify that all those "default constructor" are safe to use
-                       clone.eventTimestamp  = new LttngTimestamp();
-                       clone.eventSource     = new LttngEventSource();
-                       clone.eventType       = new LttngEventType();
-                       clone.eventContent    = new LttngEventContent(clone.currentLttngEvent);
-                       clone.eventReference  = new LttngEventReference(this.getName());
-            
-            // Create the skeleton event
-                       clone.currentLttngEvent = new LttngEvent(this, clone.eventTimestamp, clone.eventSource, clone.eventType, clone.eventContent, clone.eventReference, null);
-            
-            // Create a new current location
-                       clone.previousLocation = new LttngLocation();
-            
-            // Set the currentEvent to the eventContent
-                       clone.eventContent.setEvent(clone.currentLttngEvent);
-            
-               // Set the start time of the trace
-               setTimeRange(new TmfTimeRange(
-                               new LttngTimestamp(clone.currentJniTrace.getStartTime().getTime()), 
-                               new LttngTimestamp(clone.currentJniTrace.getEndTime().getTime())
-                    ));
-       }
-       catch (CloneNotSupportedException e) {
-       }
-
-       return clone;
+    private LTTngTrace(LTTngTrace oldStream) throws Exception { 
+       super(null);
+       throw new Exception("Copy constructor should never be use with a LTTngTrace!");
     }
     
-    
     /*
      * Fill out the HashMap with "Type" (Tracefile/Marker)
      * 
@@ -305,417 +209,42 @@ public class LTTngTrace extends TmfTrace<LttngEvent> {
         this.traceTypeNames.add(newTypeKey);
     }
     
-//    /**
-//     * Index the current trace.
-//     * 
-//     * @param useless  This boolean is only to comply to the interface and will be ignored.
-//     */
-//    @Override
-//    public synchronized void indexTrace(boolean useless) {
-//     
-//     long nbEvents=0L;
-//     
-//     // Start time need to be null to detect none have been set 
-//        // LastTime need to exist so we can ajust it as we go
-//        LttngTimestamp startTime = null;
-//        LttngTimestamp lastTime  = new LttngTimestamp();
-//     
-//        // Position the trace at the beginning
-//        TmfContext context = seekEvent( new LttngTimestamp(0L) );
-//        
-//        // Read the first event and extract the location
-//        LttngEvent tmpEvent = (LttngEvent)getNextEvent(context);
-//        
-//        // If we read the first event, define the start time.
-//        if ( tmpEvent != null ) {
-//             startTime = new LttngTimestamp( tmpEvent.getTimestamp() );
-//             lastTime.setValue(tmpEvent.getTimestamp().getValue());
-//        }
-//        
-//        // Now, we read each event until we hit the end of the trace
-//        // We will create a new checkpoint every "getCacheSize()" event
-//        while ( tmpEvent != null) {
-//             // Update the last time each time we read a new event
-//            lastTime.setValue(tmpEvent.getTimestamp().getValue());
-//            
-//            // Save a check point if needed
-//            if ((nbEvents++ % getCacheSize()) == 0) {
-//             // *** IMPORTANT
-//             // We need to NEW each stuff we put in checkpoint
-//             //      Otherwise everything will be the same!
-//                LttngTimestamp tmpTimestamp = new LttngTimestamp( (LttngTimestamp)tmpEvent.getTimestamp() );
-//                LttngLocation  newLocation  = new LttngLocation(  (LttngTimestamp)tmpEvent.getTimestamp() );
-//                
-//                fCheckpoints.add(new TmfCheckpoint(tmpTimestamp, newLocation ) );
-//            }
-//            // Read the next event
-//            tmpEvent = (LttngEvent)getNextEvent(context);
-//        }
-//        
-//        // If we have a start time, we should have an end time as well
-//        // Issue the new range
-//        if (startTime != null) {
-//            setTimeRange( new TmfTimeRange(startTime, lastTime) );
-//            notifyListeners(getTimeRange() );
-//        }
-//        
-//        // Ajust the total number of event in the trace
-//        fNbEvents = nbEvents;
-//        //printCheckpointsVector();
-//        //printDebug = true;
-//    }
-    
-    /**
-     * Return the latest saved location.
-     * Note : Modifying the returned location may result in buggy positionning!
-     * 
-     * @return The LttngLocation as it was after the last operation.
-     * 
-     * @see org.eclipse.linuxtools.lttng.event.LttngLocation
-     */
-    @Override
-       public ITmfLocation<?> getCurrentLocation() {
-        return previousLocation;
-    }
-    
-    /**
-     * Position the trace to the event at the given location.<p>
-     * NOTE : Seeking by location is very fast compare to seeking by position 
-     *         but is still slower than "ReadNext", avoid using it for small interval.
-     * 
-     * @param location         Location of the event in the trace.
-     *                                                 If no event available at this exact location, we will position ourself to the next one.
-     * 
-     * @return The TmfContext that point to this event
-     * 
-     * @see org.eclipse.linuxtools.lttng.event.LttngLocation
-     * @see org.eclipse.linuxtools.tmf.trace.TmfContext
-     */
-    @Override
-       public synchronized TmfContext seekLocation(ITmfLocation<?> location) {
-       
-       if ( printDebug == true ) {
-               System.out.println("seekLocation(location) location -> " + location);
-       }
-       
-       // If the location in context is null, create a new one
-       LttngLocation curLocation = null;
-       if ( location == null ) {
-               curLocation = new LttngLocation();
-       }
-       else {
-               curLocation = (LttngLocation)location;
-       }
-       
-       // *** NOTE : 
-       // Update to location should (and will) be done in SeekEvent.
-       
-       // The only seek valid in LTTng is with the time, we call seekEvent(timestamp)
-       return seekEvent( curLocation.getOperationTime() );
-    }
-    
-    /**
-     * Position the trace to the event at the given time.<p>
-     * NOTE : Seeking by time is very fast compare to seeking by position 
-     *         but is still slower than "ReadNext", avoid using it for small interval.
+    /** 
+     * Return the next event in the trace.<p>
      * 
-     * @param timestamp                Time of the event in the trace. 
-     *                                                 If no event available at this exact time, we will position ourself to the next one.
+     * @param context   The actual context of the trace
      * 
-     * @return The TmfContext that point to this event
+     * @return The next event, or null if none available
      * 
-     * @see org.eclipse.linuxtools.lttng.event.LttngLocation
-     * @see org.eclipse.linuxtools.tmf.trace.TmfContext
-     */
+     * @see org.eclipse.linuxtools.lttng.event.LttngEvent
+     */ 
     @Override
-    public synchronized TmfContext seekEvent(TmfTimestamp timestamp) {
-       
-       if ( printDebug == true ) {
-               System.out.println("seekEvent(timestamp) timestamp -> " + timestamp);
-       }
-       
-       // Call JNI to seek
-       currentJniTrace.seekToTime(new JniTime(timestamp.getValue()));
+       public LttngEvent parseEvent(TmfTraceContext context) {
+               JniEvent jniEvent;
+               LttngTimestamp timestamp = null;
+               LttngEvent returnedEvent = null;
                
-       // Save the time at which we seeked
-       previousLocation.setOperationTime(timestamp.getValue());
-       // Set the operation marker as seek, to be able to detect we did "seek" this event
-       previousLocation.setLastOperationSeek();
-       
-       // *** VERIFY ***
-       // Is that too paranoid?
-       //
-       // We don't trust what upper level could do with our internal location 
-       //      so we create a new one to return instead 
-       LttngLocation curLocation = new LttngLocation(previousLocation);
-       
-       return new TmfContext( curLocation );
-    }
-    
-    /**
-     * Position the trace to the event at the given position (rank).<p>
-     * NOTE : Seeking by position is very slow in LTTng, consider seeking by timestamp.
-     * 
-     * @param position Position (or rank) of the event in the trace, starting at 0.
-     * 
-     * @return The TmfContext that point to this event
-     * 
-     * @see org.eclipse.linuxtools.lttng.event.LttngLocation
-     * @see org.eclipse.linuxtools.tmf.trace.TmfContext
-     */
-    @Override
-    public synchronized TmfContext seekEvent(long position) {
-       
-       if ( printDebug == true ) {
-               System.out.println("seekEvent(position) position -> " + position);
-       }
-       
-       TmfTimestamp timestamp = null;
-        long index = position / getCacheSize();
-        
-        // Get the timestamp of the closest check point to the given position
-        if (fCheckpoints.size() > 0) {
-            if (index >= fCheckpoints.size()) {
-                    index = fCheckpoints.size() - 1;
-            }
-            timestamp = (TmfTimestamp)fCheckpoints.elementAt((int)index).getTimestamp();
-        }
-        // If none, take the start time of the trace
-        else {
-            timestamp = getStartTime();
-        }
-        
-        // Seek to the found time
-        TmfContext tmpContext  = seekEvent(timestamp);
-        previousLocation = (LttngLocation)tmpContext.getLocation();
-        
-        // Ajust the index of the event we found at this check point position
-        Long currentPosition = index * getCacheSize();
-        
-        Long lastTimeValueRead = 0L;
-        
-        // Get the event at current position. This won't move to the next one
-        JniEvent tmpJniEvent = currentJniTrace.findNextEvent();
-        // Now that we are positionned at the checkpoint, 
-        //     we need to "readNext" (Position - CheckpointPosition) times or until trace "run out"
-        while ( (tmpJniEvent != null) && ( currentPosition < position ) ) {
-            tmpJniEvent = currentJniTrace.readNextEvent();
-            currentPosition++;
-        }
-        
-        // If we found our event, save its timestamp
-        if ( tmpJniEvent != null ) {
-               lastTimeValueRead = tmpJniEvent.getEventTime().getTime();
-        }
-        
-        // Set the operation marker as seek, to be able to detect we did "seek" this event
-        previousLocation.setLastOperationSeek();
-        // Save read event time
-        previousLocation.setOperationTime(lastTimeValueRead);
-       
-       // *** VERIFY ***
-       // Is that too paranoid?
-       //
-       // We don't trust what upper level could do with our internal location 
-       //      so we create a new one to return instead 
-       LttngLocation curLocation = new LttngLocation(previousLocation);
-        
-        return new TmfContext( curLocation );
-    }
-    
-    /**
-     * Return the event in the trace according to the given context. Read it if necessary.<p>
-     * Similar (same?) as ParseEvent except that calling GetNext twice read the next one the second time.
-     * 
-     * @param context  Current TmfContext where to get the event
-     * 
-     * @return The LttngEvent we read of null if no event are available
-     * 
-     * @see org.eclipse.linuxtools.lttng.event.LttngLocation
-     * @see org.eclipse.linuxtools.tmf.trace.TmfContext
-     */
-
-    public int nbEventsRead = 0;
-    @Override
-    public synchronized LttngEvent getNextEvent(TmfContext context) {
-       
-       if ( printDebug == true ) {
-               System.out.println("getNextEvent(context) context.getLocation() -> " + context.getLocation());
-       }
-       
-       LttngEvent      returnedEvent = null;
-       LttngLocation curLocation = null;
-       
-       // If the location in context is null, create a new one
-       if ( context.getLocation() == null ) {
-               curLocation = new LttngLocation();
-               context.setLocation(curLocation);
-       }
-       else {
-               // Otherwise, we use the one in context; it should be a valid LttngLocation
-               curLocation = (LttngLocation)context.getLocation();
-       }
-       
-       // *** HACK ***
-       // TMF assumes it is possible to read (GetNextEvent) to the next Event once ParseEvent() is called
-       // In LTTNG, there is not difference between "Parsing" and "Reading" an event.
-       //      Since parsing/reading invalidate the previous event, 
-       //              we need to make sure the sequence ParseEvent() -> GetNextEvent() will not actually move to the next event.
-       // To do so, we avoid moving for call to "GetNextEvent()" that follow call to a call to "ParseEvent()".
-       // However, calling ParseEvent() -> GetNextEvent() -> GetNextEvent() will only move next by one.
-       
-       // *** Positioning trick :
-       // GetNextEvent only read the trace if : 
-       // 1- The last operation was NOT a ParseEvent --> A read is required
-       //      OR
-       // 2- The time of the previous location is different from the current  one --> A seek + a read is required
-       if ( (curLocation.isLastOperationParse() != true) ||
-                (previousLocation.getOperationTimeValue() != curLocation.getOperationTimeValue() ) ) 
-       {
-                       if ( previousLocation.getOperationTimeValue() != curLocation.getOperationTimeValue() ) {
-                               if ( printDebug == true ) {
-                                       System.out.println("\t\tSeeking in getNextEvent. [ LastTime : " + previousLocation.getOperationTimeValue() + " CurrentTime" + curLocation.getOperationTimeValue() + " ]");
-                               }
-                               seekEvent( curLocation.getOperationTime() );
-                       }
-                       // Read the next event from the trace. The last one will NO LONGER BE VALID.
-               returnedEvent = readEvent(curLocation);
-               nbEventsRead++;
-               
-               // Set the operation marker as read to both location, to be able to detect we did "read" this event
-               previousLocation.setLastOperationReadNext();
-               curLocation.setLastOperationReadNext();
-       }
-       else {
-               // No event was read, just return the one currently loaded (the last one we read)
-               returnedEvent = currentLttngEvent;
+       synchronized (currentJniTrace) {
+           // Seek to the context's location
+               seekLocation(context.getLocation());
                
-               // *** IMPORTANT!
-               // Reset (erase) the operation marker to both location, to be able to detect we did NOT "read" this event
-               previousLocation.resetLocationState();
-               curLocation.resetLocationState();
-       }
-       
-       // If we read an event, set it's time to the locations (both previous and current)
-       if ( returnedEvent != null ) {
-               previousLocation.setOperationTime((LttngTimestamp)returnedEvent.getTimestamp());
-               curLocation.setOperationTime((LttngTimestamp)returnedEvent.getTimestamp());
+               // Read an event from the JNI and convert it into a LttngEvent
+               jniEvent = currentJniTrace.readNextEvent();
                
-               updateIndex(context, context.getRank(), returnedEvent.getTimestamp());
-               context.updateRank(1);
-       }
-       
-       return returnedEvent;
-    }
-    
-    
-    /**
-     * Return the event in the trace according to the given context. Read it if necessary.<p>
-     * Similar (same?) as GetNextEvent except that calling ParseEvent twice will return the same event
-     * 
-     * @param context  Current TmfContext where to get the event
-     * 
-     * @return The LttngEvent we read of null if no event are available
-     * 
-     * @see org.eclipse.linuxtools.lttng.event.LttngLocation
-     * @see org.eclipse.linuxtools.tmf.trace.TmfContext
-     */
-    @Override
-       public synchronized LttngEvent parseEvent(TmfContext context) {
-       
-       if ( printDebug == true ) {
-               System.out.println("parseEvent(context) context.getLocation() -> " + context.getLocation());
-       }
-       
-       LttngEvent      returnedEvent = null;
-       LttngLocation curLocation = null;
-       
-       // If the location in context is null, create a new one
-       if ( context.getLocation() == null ) {
-               curLocation = new LttngLocation();
-               context.setLocation(curLocation);
-       }
-       // Otherwise, we use the one in context; it should be a valid LttngLocation
-       else {
-               curLocation = (LttngLocation)context.getLocation();
-       }
-       
-       // *** HACK ***
-       // TMF assumes it is possible to read (GetNextEvent) to the next Event once ParseEvent() is called
-       // In LTTNG, there is not difference between "Parsing" and "Reading" an event.
-       //              So, before "Parsing" an event, we have to make sure we didn't "Read" it alreafy.
-       // Also, "Reading" invalidate the previous Event in LTTNG and seek back is very costly,
-       //              so calling twice "Parse" will return the same event, giving a way to get the "Currently loaded" event
-       
-       // *** Positionning trick :
-       // ParseEvent only read the trace if : 
-       // 1- The last operation was NOT a ParseEvent or a GetNextEvent --> A read is required
-       //      OR
-       // 2- The time of the previous location is different from the current  one --> A seek + a read is required
-       if ( ( (curLocation.isLastOperationParse() != true) && ((curLocation.isLastOperationReadNext() != true)) )  ||
-                (previousLocation.getOperationTimeValue() != curLocation.getOperationTimeValue() ) ) 
-       {
-               // Previous time != Current time : We need to reposition to the current time
-                       if (previousLocation.getOperationTimeValue() != curLocation.getOperationTimeValue() ) {
-                               if ( printDebug == true ) {
-                                       System.out.println("\t\tSeeking in getNextEvent. [ LastTime : " + previousLocation.getOperationTimeValue() + " CurrentTime" + curLocation.getOperationTimeValue() + " ]");
-                               }
-                               seekEvent( curLocation.getOperationTime() );
-                       }
-               
-                       // Read the next event from the trace. The last one will NO LONGER BE VALID.
-               returnedEvent = readEvent(curLocation);
-       }
-       else {
-               // No event was read, just return the one currently loaded (the last one we read)
-               returnedEvent = currentLttngEvent;
-       }
-       
-       // If we read an event, set it's time to the locations (both previous and current)
-       if ( returnedEvent != null ) {
-               previousLocation.setOperationTime((LttngTimestamp)returnedEvent.getTimestamp());
-               curLocation.setOperationTime((LttngTimestamp)returnedEvent.getTimestamp());
+               //currentLttngEvent = (jniEvent != null) ? convertJniEventToTmf(jniEvent, true) : null;
+               if ( jniEvent != null ) {
+                   currentLttngEvent = convertJniEventToTmf(jniEvent);
+                   returnedEvent = currentLttngEvent;
+               }
+               
+               // Save timestamp
+               timestamp = (LttngTimestamp) getCurrentLocation();
        }
-       
-       // Set the operation marker as parse to both location, to be able to detect we already "read" this event
-       previousLocation.setLastOperationParse();
-       curLocation.setLastOperationParse();
-       
-       return returnedEvent;
-    }
-    
-    /*
-     * Read the next event from the JNI and convert it as Lttng Event<p>
-     * 
-     * @param location         Current LttngLocation that to be updated with the event timestamp
-     * 
-     * @return The LttngEvent we read of null if no event are available
-     * 
-     * @see org.eclipse.linuxtools.lttng.event.LttngLocation
-     * @see org.eclipse.linuxtools.org.eclipse.linuxtools.lttng.jni.JniTrace
-     */
-    private synchronized LttngEvent readEvent(LttngLocation location) {
-       LttngEvent      returnedEvent = null;
-       JniEvent tmpEvent = null;
-       
-       // Read the next event from JNI. THIS WILL INVALIDATE THE CURRENT LTTNG EVENT.
-       tmpEvent = currentJniTrace.readNextEvent();
-               
-               if ( tmpEvent != null ) {
-                       // *** NOTE
-                       // Convert will update the currentLttngEvent
-            returnedEvent = convertJniEventToTmf(tmpEvent);
-            
-            location.setOperationTime( (LttngTimestamp)returnedEvent.getTimestamp() );
-        }
-               // *** NOTE
-               // If the read failed (likely the last event in the trace), set the LastReadTime to the JNI time
-               // That way, even if we try to read again, we will step over the bogus seek and read
-               else {
-                       location.setOperationTime(  getEndTime().getValue() + 1 );
-               }
-               
-               return returnedEvent;
+               context.setLocation(timestamp);
+               context.setTimestamp(timestamp);
+               context.incrIndex();
+               
+               return returnedEvent;
     }
     
     /**
@@ -731,7 +260,7 @@ public class LTTngTrace extends TmfTrace<LttngEvent> {
      * @see org.eclipse.linuxtools.org.eclipse.linuxtools.lttng.jni.JniEvent
      * @see org.eclipse.linuxtools.lttng.event.LttngEvent
      */
-       public synchronized LttngEvent convertJniEventToTmf(JniEvent newEvent) {
+       public LttngEvent convertJniEventToTmf(JniEvent newEvent) {
            currentLttngEvent = convertJniEventToTmf(newEvent, IS_PARSING_NEEDED_DEFAULT);
            
            return currentLttngEvent;
@@ -748,83 +277,97 @@ public class LTTngTrace extends TmfTrace<LttngEvent> {
      * @see org.eclipse.linuxtools.org.eclipse.linuxtools.lttng.jni.JniEvent
      * @see org.eclipse.linuxtools.lttng.event.LttngEvent
      */
-    public synchronized LttngEvent convertJniEventToTmf(JniEvent jniEvent, boolean isParsingNeeded) {
-       
-       if ( uniqueEvent == true ) {
-               
-               // *** 
-               //   UNHACKED :         We can no longer do that because TCF need to maintain several events at once.
-               //                                      This is very slow to do so in LTTng, this has to be temporary.
-               //              *** HACK *** 
-               //              To save time here, we only set value instead of allocating new object
-               //              This give an HUGE performance improvement
-               //              all allocation done in the LttngTrace constructor
-               // ***
-               eventTimestamp.setValue(jniEvent.getEventTime().getTime());
-               eventSource.setSourceId(jniEvent.requestEventSource());
-               
-               eventType = traceTypes.get( EventTypeKey.getEventTypeKey(jniEvent) );
-               
-               eventReference.setValue(jniEvent.getParentTracefile().getTracefilePath());
-               eventReference.setTracepath(this.getName());
-               
-               eventContent.emptyContent();
-               
-               currentLttngEvent.setType(eventType);
-               // Save the jni reference
-               currentLttngEvent.updateJniEventReference(jniEvent);
-               
-               // Parse now if was asked
-               // Warning : THIS IS SLOW
-               if (isParsingNeeded == true ) {
-                  eventContent.getFields();
-               }
-               
-               return currentLttngEvent;
+    public LttngEvent convertJniEventToTmf(JniEvent jniEvent, boolean isParsingNeeded) {
+        // *** HACK *** 
+        // To save time here, we only set value instead of allocating new object
+        // This give an HUGE performance improvement
+        // all allocation done in the LttngTrace constructor
+        
+        eventTimestamp.setValue(jniEvent.getEventTime().getTime());
+        eventSource.setSourceId(jniEvent.requestEventSource());
+        
+        eventType = traceTypes.get( EventTypeKey.getEventTypeKey(jniEvent) );
+        
+        eventReference.setValue(jniEvent.getParentTracefile().getTracefilePath());
+        eventReference.setTracepath(this.getName());
+        
+//        eventContent.setEvent(currentLttngEvent);
+//        eventContent.setType(eventType);
+        eventContent.emptyContent();
+        
+//        currentLttngEvent.setContent(eventContent);
+        currentLttngEvent.setType(eventType);
+        // Save the jni reference
+        currentLttngEvent.updateJniEventReference(jniEvent);
+        
+        // Parse now if was asked
+        // Warning : THIS IS SLOW
+        if (isParsingNeeded == true ) {
+            eventContent.getFields();
+        }
+        
+        return currentLttngEvent;
+    }
+    
+    /**
+     * Seek (move) to a certain location in the trace.<p>
+     * 
+     * WARNING : No event is read by this function, it just seek to a certain time.<br>
+     * Use "parseEvent()" or "getNextEvent()" to get the event we seeked to. 
+     * 
+     * @param location  a TmfTimestamp of a position in the trace
+     * 
+     * @return TmfTraceContext pointing the position in the trace at the seek location 
+     */
+    public TmfTraceContext seekLocation(Object location) {
+        
+       LttngTimestamp timestamp = null;
+
+       // If location is null, interpret this as a request to get back to the beginning of the trace
+        //      in that case, just change the location, the seek will happen below
+       if (location == null) {
+               location = getStartTime();
+       }
+
+       if (location instanceof TmfTimestamp) {
+               long value = ((TmfTimestamp) location).getValue();
+               if (value != currentJniTrace.getCurrentEventTimestamp().getTime()) {
+                       synchronized (currentJniTrace) {
+                               currentJniTrace.seekToTime(new JniTime(value));
+                               timestamp = (LttngTimestamp) getCurrentLocation();
+                       }
+               }
        }
        else {
-               return convertJniEventToTmfMultipleEventEvilFix(jniEvent, isParsingNeeded);
+           System.out.println("ERROR : Location not instance of TmfTimestamp");
        }
-       
+
+       // FIXME: LTTng hack - start
+       // return new TmfTraceContext(timestamp, timestamp, 0); // Original
+        return new TmfTraceContext(timestamp, timestamp, -1);  // Hacked
+       // FIXME: LTTng hack - end
     }
     
     /**
-     * This method is a temporary fix to support multiple events at once in TMF
-     *         This is expected to be slow and should be fixed in another way.
-     * See comment in convertJniEventToTmf();
+     * Location (timestamp) of our current position in the trace.<p>
      * 
-     * @param jniEvent The current JNI Event
-     * @return Current         Lttng Event fully parsed
+     * @return The time (in LttngTimestamp format) of the current event or AFTER endTime if no more event is available.
      */
-    private synchronized LttngEvent convertJniEventToTmfMultipleEventEvilFix(JniEvent jniEvent, boolean isParsingNeeded) {
-       // *** HACK ***
-       // Below : the "fix" with all the new and the full-parse
-       //              Allocating new memory is slow.
-       //              Parsing every events is very slow.
-       eventTimestamp        = new LttngTimestamp(jniEvent.getEventTime().getTime());
-        eventSource           = new LttngEventSource(jniEvent.requestEventSource());
-        eventReference        = new LttngEventReference(jniEvent.getParentTracefile().getTracefilePath(), this.getName());
-        eventType             = new LttngEventType(traceTypes.get( EventTypeKey.getEventTypeKey(jniEvent) ));
-        eventContent          = new LttngEventContent(currentLttngEvent);
-        currentLttngEvent = new LttngEvent(this, eventTimestamp, eventSource, eventType, eventContent, eventReference, null);
-        
-        // The jni reference is no longer reliable but we will keep it anyhow
-        currentLttngEvent.updateJniEventReference(jniEvent);
-        // Ensure that the content is correctly set
-        eventContent.setEvent(currentLttngEvent);
+    @Override
+       public Object getCurrentLocation() {
+        LttngTimestamp returnedLocation = null;
+        JniEvent tmpJniEvent = currentJniTrace.findNextEvent();
         
-        // Parse the event if it was needed
-        // *** WARNING ***
-        // ONLY for testing, NOT parsing events with non-unique events WILL result in segfault in the JVM
-        if ( isParsingNeeded == true ) {
-               eventContent.getFields();
+        if ( tmpJniEvent != null  ) {
+            returnedLocation = new LttngTimestamp(tmpJniEvent.getEventTime().getTime());
         }
-       
-        return currentLttngEvent;
+        else {
+            returnedLocation = new LttngTimestamp( getEndTime().getValue() + 1 );
+        }
+        
+        return returnedLocation;
     }
     
-    
-    
     /**
      * Reference to the current LttngTrace we are reading from.<p>
      * 
@@ -901,27 +444,7 @@ public class LTTngTrace extends TmfTrace<LttngEvent> {
        }
     }
     
-    /**
-     * Print the content of the checkpoint vector.<p>
-     * 
-     * This is intended for debug purpose only.
-     */
-    public void printCheckpointsVector() {
-       System.out.println("StartTime : " + getTimeRange().getStartTime().getValue());
-       System.out.println("EndTime   : " + getTimeRange().getEndTime().getValue());
-       
-        for ( int pos=0; pos < fCheckpoints.size(); pos++) {
-            System.out.print(pos + ": " + "\t");
-            System.out.print( fCheckpoints.get(pos).getTimestamp() + "\t" );
-            System.out.println( fCheckpoints.get(pos).getLocation() );
-        }
-    }
     
-    /**
-     * Return a String identifying this trace.
-     * 
-     * @return String that identify this trace 
-     */
     @Override
        public String toString() {
        String returnedData="";
@@ -957,4 +480,4 @@ class EventTypeKey {
         return key;
     }
     
-}
\ No newline at end of file
+}
This page took 0.118367 seconds and 5 git commands to generate.