LTTng: CPU usage analysis from the LTTng kernel trace
[deliverable/tracecompass.git] / org.eclipse.linuxtools.tmf.core / src / org / eclipse / linuxtools / tmf / core / ctfadaptor / CtfIterator.java
index a97fca8b55ae9fa45e38444bd0d6fa57d9df1301..d5cece59e2814227468e0d948c257543a5c5d188 100644 (file)
 /*******************************************************************************
- * Copyright (c) 2012 Ericsson
+ * Copyright (c) 2012, 2014 Ericsson, École Polytechnique de Montréal
  *
  * All rights reserved. This program and the accompanying materials are made
  * available under the terms of the Eclipse Public License v1.0 which
  * accompanies this distribution, and is available at
  * http://www.eclipse.org/legal/epl-v10.html
  *
- * Contributors: Matthew Khouzam - Initial API and implementation
+ * Contributors:
+ *   Matthew Khouzam - Initial API and implementation
+ *   Florian Wininger - Performance improvements
  *******************************************************************************/
+
 package org.eclipse.linuxtools.tmf.core.ctfadaptor;
 
+import org.eclipse.linuxtools.ctf.core.trace.CTFReaderException;
 import org.eclipse.linuxtools.ctf.core.trace.CTFTraceReader;
 import org.eclipse.linuxtools.ctf.core.trace.StreamInputReader;
+import org.eclipse.linuxtools.internal.tmf.core.Activator;
 import org.eclipse.linuxtools.tmf.core.trace.ITmfContext;
-import org.eclipse.linuxtools.tmf.core.trace.ITmfLocation;
+import org.eclipse.linuxtools.tmf.core.trace.location.ITmfLocation;
 
 /**
  * The CTF trace reader iterator.
  *
- * It doesn't reserve a file handle, so many iterators can be used without worries
- * of I/O errors or resource exhaustion.
+ * It doesn't reserve a file handle, so many iterators can be used without
+ * worries of I/O errors or resource exhaustion.
  *
- * @version 1.0
  * @author Matthew Khouzam
  */
-public class CtfIterator extends CTFTraceReader implements ITmfContext,
-        Comparable<CtfIterator> {
+public class CtfIterator extends CTFTraceReader
+        implements ITmfContext, Comparable<CtfIterator> {
 
-    private final CtfTmfTrace ctfTmfTrace;
+    /** An invalid location */
+    public static final CtfLocation NULL_LOCATION = new CtfLocation(CtfLocation.INVALID_LOCATION);
 
-    /**
-     * An invalid location
-     */
-    final public static CtfLocation NULL_LOCATION = new CtfLocation(CtfLocation.INVALID_LOCATION);
+    private final CtfTmfTrace fTrace;
 
-    private CtfLocation curLocation;
-    private long curRank;
+    private CtfLocation fCurLocation;
+    private long fCurRank;
+
+    private CtfLocation fPreviousLocation;
+    private CtfTmfEvent fPreviousEvent;
+
+    // ------------------------------------------------------------------------
+    // Constructors
+    // ------------------------------------------------------------------------
 
     /**
      * Create a new CTF trace iterator, which initially points at the first
      * event in the trace.
      *
      * @param trace
-     *            the trace to iterate over
+     *            The trace to iterate over
+     * @throws CTFReaderException
+     *             If the iterator couldn't not be instantiated, probably due to
+     *             a read error.
      */
-    public CtfIterator(final CtfTmfTrace trace) {
+    public CtfIterator(CtfTmfTrace trace) throws CTFReaderException {
         super(trace.getCTFTrace());
-        this.ctfTmfTrace = trace;
-        if (this.hasMoreEvents()) {
-            this.curLocation = new CtfLocation(trace.getStartTime());
-            this.curRank = 0;
+        fTrace = trace;
+        if (hasMoreEvents()) {
+            fCurLocation = new CtfLocation(trace.getStartTime());
+            fCurRank = 0;
         } else {
             setUnknownLocation();
         }
     }
 
-    private void setUnknownLocation() {
-        this.curLocation = NULL_LOCATION;
-        this.curRank = UNKNOWN_RANK;
-    }
-
     /**
-     * Constructor for CtfIterator.
+     * Create a new CTF trace iterator, which will initially point to the given
+     * location/rank.
      *
      * @param trace
-     *            CtfTmfTrace the trace
+     *            The trace to iterate over
      * @param ctfLocationData
-     *            long the timestamp in ns of the trace for positioning
+     *            The initial timestamp the iterator will be pointing to
      * @param rank
-     *            long the index of the trace for positioning
+     *            The initial rank
+     * @throws CTFReaderException
+     *             If the iterator couldn't not be instantiated, probably due to
+     *             a read error.
      * @since 2.0
      */
-    public CtfIterator(final CtfTmfTrace trace,
-            final CtfLocationData ctfLocationData, final long rank) {
+    public CtfIterator(CtfTmfTrace trace, CtfLocationInfo ctfLocationData, long rank)
+            throws CTFReaderException {
         super(trace.getCTFTrace());
 
-        this.ctfTmfTrace = trace;
+        this.fTrace = trace;
         if (this.hasMoreEvents()) {
-            this.curLocation = new CtfLocation(ctfLocationData);
+            this.fCurLocation = new CtfLocation(ctfLocationData);
             if (this.getCurrentEvent().getTimestamp().getValue() != ctfLocationData.getTimestamp()) {
                 this.seek(ctfLocationData);
-                this.curRank = rank;
+                this.fCurRank = rank;
             }
         } else {
             setUnknownLocation();
         }
+    }
 
+    private void setUnknownLocation() {
+        fCurLocation = NULL_LOCATION;
+        fCurRank = UNKNOWN_RANK;
     }
 
+    // ------------------------------------------------------------------------
+    // Accessors
+    // ------------------------------------------------------------------------
+
     /**
-     * Method getCtfTmfTrace. gets a CtfTmfTrace
-     * @return CtfTmfTrace
+     * Return this iterator's trace.
+     *
+     * @return CtfTmfTrace The iterator's trace
      */
     public CtfTmfTrace getCtfTmfTrace() {
-        return ctfTmfTrace;
+        return fTrace;
     }
 
     /**
-     * Method getCurrentEvent. gets the current event
-     * @return CtfTmfEvent
+     * Return the current event pointed to by the iterator.
+     *
+     * @return CtfTmfEvent The current event
      */
-    public CtfTmfEvent getCurrentEvent() {
-        final StreamInputReader top = super.prio.peek();
+    public synchronized CtfTmfEvent getCurrentEvent() {
+        final StreamInputReader top = super.getPrio().peek();
         if (top != null) {
-            return new CtfTmfEvent(top.getCurrentEvent(), top.getFilename(),
-                    ctfTmfTrace);
+            if (!fCurLocation.equals(fPreviousLocation)) {
+                fPreviousLocation = fCurLocation;
+                fPreviousEvent = CtfTmfEventFactory.createEvent(top.getCurrentEvent(),
+                        top.getFilename(), fTrace);
+            }
+            return fPreviousEvent;
         }
         return null;
     }
 
-    /* (non-Javadoc)
-     * @see org.eclipse.linuxtools.ctf.core.trace.CTFTraceReader#seek(long)
-     */
-    @Override
-    public boolean seek(long timestamp) {
-        return seek(new CtfLocationData(timestamp, 0));
-    }
-
     /**
      * Seek this iterator to a given location.
      *
      * @param ctfLocationData
      *            The LocationData representing the position to seek to
-     * @return boolean
+     * @return boolean True if the seek was successful, false if there was an
+     *         error seeking.
      * @since 2.0
      */
-    public boolean seek(final CtfLocationData ctfLocationData) {
+    public synchronized boolean seek(CtfLocationInfo ctfLocationData) {
         boolean ret = false;
 
+        /* Avoid the cost of seeking at the current location. */
+        if (fCurLocation.getLocationInfo().equals(ctfLocationData)) {
+            return super.hasMoreEvents();
+        }
+
         /* Adjust the timestamp depending on the trace's offset */
         long currTimestamp = ctfLocationData.getTimestamp();
         final long offsetTimestamp = this.getCtfTmfTrace().getCTFTrace().timestampNanoToCycles(currTimestamp);
-        if (offsetTimestamp < 0) {
-            ret = super.seek(0L);
-        } else {
-            ret = super.seek(offsetTimestamp);
+        try {
+            if (offsetTimestamp < 0) {
+                ret = super.seek(0L);
+            } else {
+                ret = super.seek(offsetTimestamp);
+            }
+        } catch (CTFReaderException e) {
+            Activator.logError(e.getMessage(), e);
+            return false;
         }
-
         /*
          * Check if there is already one or more events for that timestamp, and
          * assign the location index correctly
          */
         long index = 0;
-        if (this.getCurrentEvent() != null) {
-            currTimestamp = this.getCurrentEvent().getTimestamp().getValue();
+        final CtfTmfEvent currentEvent = this.getCurrentEvent();
+        if (currentEvent != null) {
+            currTimestamp = currentEvent.getTimestamp().getValue();
 
             for (long i = 0; i < ctfLocationData.getIndex(); i++) {
-                if (currTimestamp == this.getCurrentEvent().getTimestamp().getValue()) {
+                if (currTimestamp == currentEvent.getTimestamp().getValue()) {
                     index++;
                 } else {
                     index = 0;
@@ -154,157 +182,123 @@ public class CtfIterator extends CTFTraceReader implements ITmfContext,
                 this.advance();
             }
         } else {
-            ret= false;
+            ret = false;
         }
         /* Seek the current location accordingly */
         if (ret) {
-            curLocation = new CtfLocation(new CtfLocationData(getCurrentEvent().getTimestamp().getValue(), index));
+            fCurLocation = new CtfLocation(new CtfLocationInfo(getCurrentEvent().getTimestamp().getValue(), index));
         } else {
-            curLocation = NULL_LOCATION;
+            fCurLocation = NULL_LOCATION;
         }
+
         return ret;
     }
 
-    /**
-     * Method getRank.
-     * @return long
-     * @see org.eclipse.linuxtools.tmf.core.trace.ITmfContext#getRank()
-     */
-    @Override
-    public long getRank() {
-        return curRank;
-    }
+    // ------------------------------------------------------------------------
+    // CTFTraceReader
+    // ------------------------------------------------------------------------
 
-    /**
-     * Method setRank.
-     * @param rank long
-     * @see org.eclipse.linuxtools.tmf.core.trace.ITmfContext#setRank(long)
-     */
     @Override
-    public void setRank(final long rank) {
-        curRank = rank;
+    public boolean seek(long timestamp) {
+        return seek(new CtfLocationInfo(timestamp, 0));
     }
 
-    /*
-     * (non-Javadoc)
-     *
-     * @see org.eclipse.linuxtools.tmf.core.trace.TmfContext#clone()
-     */
     @Override
-    public CtfIterator clone() {
-        CtfIterator clone = null;
-        clone = new CtfIterator(ctfTmfTrace, this.getLocation().getLocationInfo(), curRank);
-        return clone;
-    }
+    public synchronized boolean advance() {
+        long index = fCurLocation.getLocationInfo().getIndex();
+        long timestamp = fCurLocation.getLocationInfo().getTimestamp();
+        boolean ret = false;
+        try {
+            ret = super.advance();
+        } catch (CTFReaderException e) {
+            Activator.logError(e.getMessage(), e);
+        }
 
-    /**
-     * Method dispose.
-     * @see org.eclipse.linuxtools.tmf.core.trace.ITmfContext#dispose()
-     */
-    @Override
-    public void dispose() {
-        super.dispose();
+        if (ret) {
+            final long timestampValue = getCurrentEvent().getTimestamp().getValue();
+            if (timestamp == timestampValue) {
+                fCurLocation = new CtfLocation(timestampValue, index + 1);
+            } else {
+                fCurLocation = new CtfLocation(timestampValue, 0L);
+            }
+        } else {
+            fCurLocation = NULL_LOCATION;
+        }
+        return ret;
     }
 
-    /**
-     * Method setLocation.
-     * @param location ITmfLocation<?>
-     */
+    // ------------------------------------------------------------------------
+    // ITmfContext
+    // ------------------------------------------------------------------------
+
     @Override
-    public void setLocation(final ITmfLocation location) {
-        // FIXME alex: isn't there a cleaner way than a cast here?
-        this.curLocation = (CtfLocation) location;
-        seek(((CtfLocation) location).getLocationInfo());
+    public long getRank() {
+        return fCurRank;
     }
 
-    /**
-     * Method getLocation.
-     * @return CtfLocation
-     * @see org.eclipse.linuxtools.tmf.core.trace.ITmfContext#getLocation()
-     */
     @Override
-    public CtfLocation getLocation() {
-        return curLocation;
+    public void setRank(long rank) {
+        fCurRank = rank;
     }
 
-    /**
-     * Method increaseRank.
-     * @see org.eclipse.linuxtools.tmf.core.trace.ITmfContext#increaseRank()
-     */
     @Override
     public void increaseRank() {
         /* Only increase the rank if it's valid */
-        if(hasValidRank()) {
-            curRank++;
+        if (hasValidRank()) {
+            fCurRank++;
         }
     }
 
-    /**
-     * Method hasValidRank, if the iterator is valid
-     * @return boolean
-     * @see org.eclipse.linuxtools.tmf.core.trace.ITmfContext#hasValidRank()
-     */
     @Override
     public boolean hasValidRank() {
         return (getRank() >= 0);
     }
 
     /**
-     * Method advance go to the next event
-     * @return boolean successful or not
+     * @since 3.0
      */
     @Override
-    public boolean advance() {
-        long index = curLocation.getLocationInfo().getIndex();
-        long timestamp = curLocation.getLocationInfo().getTimestamp();
-        boolean ret = super.advance();
+    public void setLocation(ITmfLocation location) {
+        // FIXME alex: isn't there a cleaner way than a cast here?
+        fCurLocation = (CtfLocation) location;
+        seek(((CtfLocation) location).getLocationInfo());
+    }
 
-        if (ret) {
-            final long timestampValue = getCurrentEvent().getTimestamp().getValue();
-            if (timestamp == timestampValue) {
-                curLocation = new CtfLocation(timestampValue, index + 1);
-            } else {
-                curLocation = new CtfLocation(timestampValue, 0L);
-            }
-        } else {
-            curLocation = NULL_LOCATION;
-        }
-        return ret;
+    @Override
+    public CtfLocation getLocation() {
+        return fCurLocation;
     }
 
-    /**
-     * Method compareTo.
-     * @param o CtfIterator
-     * @return int -1, 0, 1
-     */
+    // ------------------------------------------------------------------------
+    // Comparable
+    // ------------------------------------------------------------------------
+
     @Override
     public int compareTo(final CtfIterator o) {
-        if (this.getRank() < o.getRank()) {
+        if (getRank() < o.getRank()) {
             return -1;
-        } else if (this.getRank() > o.getRank()) {
+        } else if (getRank() > o.getRank()) {
             return 1;
         }
         return 0;
     }
 
-    /* (non-Javadoc)
-     * @see java.lang.Object#hashCode()
-     */
+    // ------------------------------------------------------------------------
+    // Object
+    // ------------------------------------------------------------------------
+
     @Override
     public int hashCode() {
         final int prime = 31;
         int result = super.hashCode();
         result = (prime * result)
-                + ((ctfTmfTrace == null) ? 0 : ctfTmfTrace.hashCode());
+                + ((fTrace == null) ? 0 : fTrace.hashCode());
         result = (prime * result)
-                + ((curLocation == null) ? 0 : curLocation.hashCode());
-        result = (prime * result) + (int) (curRank ^ (curRank >>> 32));
+                + ((fCurLocation == null) ? 0 : fCurLocation.hashCode());
+        result = (prime * result) + (int) (fCurRank ^ (fCurRank >>> 32));
         return result;
     }
 
-    /* (non-Javadoc)
-     * @see java.lang.Object#equals(java.lang.Object)
-     */
     @Override
     public boolean equals(Object obj) {
         if (this == obj) {
@@ -317,21 +311,21 @@ public class CtfIterator extends CTFTraceReader implements ITmfContext,
             return false;
         }
         CtfIterator other = (CtfIterator) obj;
-        if (ctfTmfTrace == null) {
-            if (other.ctfTmfTrace != null) {
+        if (fTrace == null) {
+            if (other.fTrace != null) {
                 return false;
             }
-        } else if (!ctfTmfTrace.equals(other.ctfTmfTrace)) {
+        } else if (!fTrace.equals(other.fTrace)) {
             return false;
         }
-        if (curLocation == null) {
-            if (other.curLocation != null) {
+        if (fCurLocation == null) {
+            if (other.fCurLocation != null) {
                 return false;
             }
-        } else if (!curLocation.equals(other.curLocation)) {
+        } else if (!fCurLocation.equals(other.fCurLocation)) {
             return false;
         }
-        if (curRank != other.curRank) {
+        if (fCurRank != other.fCurRank) {
             return false;
         }
         return true;
This page took 0.040139 seconds and 5 git commands to generate.