Add Iterator support to TMF traces
authorFrancois Chouinard <fchouinard@gmail.com>
Wed, 9 Jan 2013 17:02:02 +0000 (12:02 -0500)
committerFrancois Chouinard <fchouinard@gmail.com>
Wed, 9 Jan 2013 22:07:57 +0000 (17:07 -0500)
Change-Id: I11d1e8c33fa5f3a39ff842807a2934cf04d8fcfe
Signed-off-by: Francois Chouinard <fchouinard@gmail.com>
Reviewed-on: https://git.eclipse.org/r/9559
Tested-by: Hudson CI
org.eclipse.linuxtools.tmf.core.tests/src/org/eclipse/linuxtools/tmf/core/tests/trace/TmfTraceTest.java
org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/internal/tmf/core/statesystem/HistoryBuilder.java
org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/component/ITmfDataProvider.java
org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/component/ITmfEventProvider.java
org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/component/TmfDataProvider.java
org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/ITmfTrace.java
org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/TmfTrace.java
org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/TmfTraceIterator.java [new file with mode: 0644]

index a007785bfd6e61796576f23b9a8920d20c8b1f53..c148c2469f057223dacab3f90e41805e157a710d 100644 (file)
@@ -18,6 +18,7 @@ import java.io.IOException;
 import java.net.URISyntaxException;
 import java.net.URL;
 import java.util.Collection;
+import java.util.Iterator;
 import java.util.Vector;
 
 import junit.framework.TestCase;
@@ -1216,6 +1217,124 @@ public class TmfTraceTest extends TestCase {
         assertNull("Event", event);
     }
 
+    // ------------------------------------------------------------------------
+    // Iterate over trace
+    // ------------------------------------------------------------------------
+
+    public void testIterateOverAllEvents() {
+        final Vector<ITmfEvent> requestedEvents = new Vector<ITmfEvent>();
+
+        final ITmfEventProvider[] providers = TmfProviderManager.getProviders(TmfEvent.class, TmfTraceStub.class);
+        final ITmfTrace trace = (ITmfTrace) providers[0];
+        final Iterator<ITmfEvent> it = trace.iterator();
+        while (it.hasNext()) {
+            requestedEvents.add(it.next());
+        }
+
+        // Validate results
+        assertEquals("nbEvents", NB_EVENTS, requestedEvents.size());
+        for (int i = 0; i < NB_EVENTS; i++) {
+            assertEquals("Distinct events", i + 1, requestedEvents.get(i).getTimestamp().getValue());
+        }
+    }
+
+    public void testIterateOverNbEvents() {
+        final Vector<ITmfEvent> requestedEvents = new Vector<ITmfEvent>();
+        final int nbRequestedEvents = 100;
+
+        final ITmfEventProvider[] providers = TmfProviderManager.getProviders(TmfEvent.class, TmfTraceStub.class);
+        final ITmfTrace trace = (ITmfTrace) providers[0];
+        final Iterator<ITmfEvent> it = trace.iterator();
+        int nbEventsToRead = nbRequestedEvents;
+        while (it.hasNext() && nbEventsToRead-- > 0) {
+            requestedEvents.add(it.next());
+        }
+
+        // Validate results
+        assertEquals("nbEvents", nbRequestedEvents, requestedEvents.size());
+        for (int i = 0; i < nbRequestedEvents; i++) {
+            assertEquals("Distinct events", i + 1, requestedEvents.get(i).getTimestamp().getValue());
+        }
+    }
+
+    public void testIterateOverNbEventsByRank() {
+        final Vector<ITmfEvent> requestedEvents = new Vector<ITmfEvent>();
+        final int startEventRank = 100;
+        final int nbRequestedEvents = 100;
+
+        final ITmfEventProvider[] providers = TmfProviderManager.getProviders(TmfEvent.class, TmfTraceStub.class);
+        final ITmfTrace trace = (ITmfTrace) providers[0];
+        final Iterator<ITmfEvent> it = trace.iterator(startEventRank);
+        int nbEventsToRead = nbRequestedEvents;
+        while (it.hasNext() && nbEventsToRead-- > 0) {
+            requestedEvents.add(it.next());
+        }
+
+        // Validate results
+        assertEquals("nbEvents", nbRequestedEvents, requestedEvents.size());
+        for (int i = 0; i < nbRequestedEvents; i++) {
+            assertEquals("Distinct events", startEventRank + i + 1, requestedEvents.get(i).getTimestamp().getValue());
+        }
+    }
+
+    public void testIterateOverNbEventsByTimestamp() {
+        final Vector<ITmfEvent> requestedEvents = new Vector<ITmfEvent>();
+        final ITmfTimestamp startEventTimestamp = new TmfTimestamp(100, SCALE);
+        final int nbRequestedEvents = 100;
+
+        final ITmfEventProvider[] providers = TmfProviderManager.getProviders(TmfEvent.class, TmfTraceStub.class);
+        final ITmfTrace trace = (ITmfTrace) providers[0];
+        final Iterator<ITmfEvent> it = trace.iterator(startEventTimestamp);
+        int nbEventsToRead = nbRequestedEvents;
+        while (it.hasNext() && nbEventsToRead-- > 0) {
+            requestedEvents.add(it.next());
+        }
+
+        // Validate results
+        assertEquals("nbEvents", nbRequestedEvents, requestedEvents.size());
+        for (int i = 0; i < nbRequestedEvents; i++) {
+            assertEquals("Distinct events", startEventTimestamp.getValue() + i, requestedEvents.get(i).getTimestamp().getValue());
+        }
+    }
+
+    public void testIterateOverEventsMixed() {
+        final Vector<ITmfEvent> requestedEvents1 = new Vector<ITmfEvent>();
+        final Vector<ITmfEvent> requestedEvents2 = new Vector<ITmfEvent>();
+        final int nbRequestedEvents = 100;
+
+        final ITmfEventProvider[] providers = TmfProviderManager.getProviders(TmfEvent.class, TmfTraceStub.class);
+        final ITmfTrace trace = (ITmfTrace) providers[0];
+
+        final Iterator<ITmfEvent> it1 = trace.iterator();
+        final Iterator<ITmfEvent> it2 = trace.iterator();
+
+        int nbEventsToRead = nbRequestedEvents;
+        while (it1.hasNext() && nbEventsToRead-- > 0) {
+            requestedEvents1.add(it1.next());
+            if (nbEventsToRead % 2 == 0) {
+                requestedEvents2.add(it2.next());
+            }
+        }
+
+        // Intermediate validation
+        assertEquals("nbEvents", nbRequestedEvents, requestedEvents1.size());
+        assertEquals("nbEvents", nbRequestedEvents / 2, requestedEvents2.size());
+
+        // Finish the job
+        nbEventsToRead = nbRequestedEvents / 2;
+        while (it2.hasNext() && nbEventsToRead-- > 0) {
+            requestedEvents2.add(it2.next());
+        }
+
+        // Final validation
+        assertEquals("nbEvents", nbRequestedEvents, requestedEvents1.size());
+        assertEquals("nbEvents", nbRequestedEvents, requestedEvents2.size());
+        for (int i = 0; i < nbRequestedEvents; i++) {
+            assertEquals("Distinct events", i + 1, requestedEvents1.get(i).getTimestamp().getValue());
+            assertEquals("Distinct events", i + 1, requestedEvents2.get(i).getTimestamp().getValue());
+        }
+    }
+
     // ------------------------------------------------------------------------
     // processRequest
     // ------------------------------------------------------------------------
index ffa595aad2f9ced24fcfe399b4c89636cf64064c..89d707af5ecc5ac3cc45e18d0b9442a2c037dea0 100644 (file)
@@ -274,4 +274,4 @@ class StateSystemBuildRequest extends TmfEventRequest {
         super.handleFailure();
         builder.close(true);
     }
-}
\ No newline at end of file
+}
index 59c636a4892e83216be210cc6fde5524246a66da..2ba969e1641ae588878fa1dd2073b88a66528acb 100644 (file)
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2009, 2010 Ericsson
+ * Copyright (c) 2009, 2010, 2012 Ericsson
  *
  * All rights reserved. This program and the accompanying materials are
  * made available under the terms of the Eclipse Public License v1.0 which
@@ -21,7 +21,7 @@ import org.eclipse.linuxtools.tmf.core.trace.ITmfContext;
  * capability of handling data requests.
  *
  * @author Francois Chouinard
- * @version 1.0
+ * @version 2.0
  * @since 2.0
  *
  * @see TmfDataProvider
@@ -60,4 +60,5 @@ public interface ITmfDataProvider extends ITmfComponent {
      * @return the event referred to by context
      */
     public ITmfEvent getNext(ITmfContext context);
+
 }
index a7e2769f001024d9d5eb3b6dfa73cfe81078f814..d7024ee2d59a88b8b20e67d676c51eb977b06a54 100644 (file)
@@ -21,7 +21,7 @@ import org.eclipse.linuxtools.tmf.core.trace.ITmfContext;
  * capability of handling event requests.
  *
  * @author Francois Chouinard
- * @version 1.0
+ * @version 2.0
  * @since 2.0
  *
  * @see TmfDataProvider
index 86cd58e54aa74bdc5d55ceb29ceb8ae9e7614755..48dedf07bb4f86fa6b7911b6e963546f197bd0cf 100644 (file)
@@ -213,6 +213,9 @@ public abstract class TmfDataProvider extends TmfComponent implements ITmfEventP
     /* (non-Javadoc)
      * @see org.eclipse.linuxtools.tmf.core.component.ITmfEventProvider#fireRequest()
      */
+    /**
+     * @since 2.0
+     */
     @Override
     public void fireRequest() {
         synchronized (fLock) {
@@ -340,7 +343,10 @@ public abstract class TmfDataProvider extends TmfComponent implements ITmfEventP
      *
      * @param request The request
      * @param indexing Should we index the chunks
+<<<<<<< Upstream, based on master
      *
+=======
+>>>>>>> f5b88da Refactor TmfRequest
      * @since 2.0
      */
     protected void queueBackgroundRequest(final ITmfRequest request, final boolean indexing) {
@@ -375,7 +381,10 @@ public abstract class TmfDataProvider extends TmfComponent implements ITmfEventP
      * @param event the event to check
      * @param nbRead the number of events read so far
      * @return true if completion criteria is met
+<<<<<<< Upstream, based on master
      *
+=======
+>>>>>>> f5b88da Refactor TmfRequest
      * @since 2.0
      */
     public boolean isCompleted(ITmfRequest request, ITmfEvent event, int nbRead) {
index 340cfdf9489dec353110ac9db7b8f1ef9705c52b..0af9a3a0a192784e7d7c75d7b72488f6acee9180 100644 (file)
@@ -9,11 +9,15 @@
  * Contributors:
  *   Francois Chouinard - Initial API and implementation
  *   Francois Chouinard - Updated as per TMF Trace Model 1.0
+ *   Alexandre Montplaisir - Added State Systems support
+ *   Patrick Tasse - Added coincidental cohesion APIs
+ *   Francois Chouinard - Added Iterator support
  *******************************************************************************/
 
 package org.eclipse.linuxtools.tmf.core.trace;
 
 import java.util.Collection;
+import java.util.Iterator;
 
 import org.eclipse.core.resources.IProject;
 import org.eclipse.core.resources.IResource;
@@ -56,6 +60,13 @@ import org.eclipse.linuxtools.tmf.core.statistics.ITmfStatistics;
  *     event = trace.getNext(context);
  * }
  * </pre>
+ * <b>Example 1b</b>: Process a whole trace using an iterator
+ * <pre>
+ * Iterator&lt;ITmfEvent&gt; it = trace.iterator();
+ * while (it.hasNext()) {
+ *     processEvent(it.next());
+ * }
+ * </pre>
  * <b>Example 2</b>: Process 50 events starting from the 1000th event
  * <pre>
  * int nbEventsRead = 0;
@@ -103,8 +114,8 @@ import org.eclipse.linuxtools.tmf.core.statistics.ITmfStatistics;
  * }
  * </pre>
  *
- * @version 1.0
  * @author Francois Chouinard
+ * @version 2.0
  *
  * @see ITmfContext
  * @see ITmfEvent
@@ -308,6 +319,56 @@ public interface ITmfTrace extends ITmfDataProvider {
      */
     public ITmfContext seekEvent(double ratio);
 
+    // ------------------------------------------------------------------------
+    // Iterator support
+    // ------------------------------------------------------------------------
+
+    /**
+     * Returns an iterator suitable to read a trace from the start
+     *
+     * @return a trace iterator
+     */
+    public Iterator<ITmfEvent> iterator();
+
+    /**
+     * Returns an iterator suitable to read a trace from the requested location
+     *
+     * @param location the first event location in the trace
+     * @return a trace iterator
+     */
+    public Iterator<ITmfEvent> iterator(ITmfLocation location);
+
+    /**
+     * Returns an iterator suitable to read a trace from the requested rank
+     *
+     * @param rank the first event rank
+     * @return a trace iterator
+     */
+    public Iterator<ITmfEvent> iterator(long rank);
+
+    /**
+     * Returns an iterator suitable to read a trace from the requested timestamp
+     *
+     * @param timestamp the first event timestamp
+     * @return a trace iterator
+     */
+    public Iterator<ITmfEvent> iterator(ITmfTimestamp timestamp);
+
+    /**
+     * Returns an iterator suitable to read a trace from the requested 'ratio'
+     *
+     * @param ratio  the first event 'ratio' (see seekEvent(double))
+     * @return a trace iterator
+     */
+    public Iterator<ITmfEvent> iterator(double ratio);
+
+    // ------------------------------------------------------------------------
+    // Coincidental cohesion APIs: current time and range are TMF UI concepts
+    // and have nothing to do with this core API. It can probably be argued
+    // that this is also pathological coupling.
+    // TODO: Stop hacking, start designing.
+    // ------------------------------------------------------------------------
+
     /**
      * Returns the initial range offset
      *
index 51007e1f4d4221ad76a4dfd723c74f8f9cea61ea..81991d645c5c54466c2a5b4b916f165cbb618cfa 100644 (file)
@@ -16,6 +16,7 @@ package org.eclipse.linuxtools.tmf.core.trace;
 import java.io.File;
 import java.util.Collection;
 import java.util.HashMap;
+import java.util.Iterator;
 import java.util.Map;
 
 import org.eclipse.core.resources.IResource;
@@ -628,6 +629,65 @@ public abstract class TmfTrace extends TmfEventProvider implements ITmfTrace {
         return context;
     }
 
+    // ------------------------------------------------------------------------
+    // ITmfTrace - Iterator operations
+    // ------------------------------------------------------------------------
+
+    /* (non-Javadoc)
+     * @see org.eclipse.linuxtools.tmf.core.trace.ITmfTrace#iterator()
+     */
+    /**
+     * @since 2.0
+     */
+    @Override
+    public Iterator<ITmfEvent> iterator() {
+        return new TmfTraceIterator(this);
+    }
+
+    /* (non-Javadoc)
+     * @see org.eclipse.linuxtools.tmf.core.trace.ITmfTrace#iterator(org.eclipse.linuxtools.tmf.core.trace.ITmfLocation)
+     */
+    /**
+     * @since 2.0
+     */
+    @Override
+    public Iterator<ITmfEvent> iterator(ITmfLocation location) {
+        return new TmfTraceIterator(this, location);
+    }
+
+    /* (non-Javadoc)
+     * @see org.eclipse.linuxtools.tmf.core.trace.ITmfTrace#iterator(long)
+     */
+    /**
+     * @since 2.0
+     */
+    @Override
+    public Iterator<ITmfEvent> iterator(long rank) {
+        return new TmfTraceIterator(this, rank);
+    }
+
+    /* (non-Javadoc)
+     * @see org.eclipse.linuxtools.tmf.core.trace.ITmfTrace#iterator(org.eclipse.linuxtools.tmf.core.event.ITmfTimestamp)
+     */
+    /**
+     * @since 2.0
+     */
+    @Override
+    public Iterator<ITmfEvent> iterator(ITmfTimestamp timestamp) {
+        return new TmfTraceIterator(this, timestamp);
+    }
+
+    /* (non-Javadoc)
+     * @see org.eclipse.linuxtools.tmf.core.trace.ITmfTrace#iterator(double)
+     */
+    /**
+     * @since 2.0
+     */
+    @Override
+    public Iterator<ITmfEvent> iterator(double ratio) {
+        return new TmfTraceIterator(this, ratio);
+    }
+
     // ------------------------------------------------------------------------
     // ITmfTrace - Read operations (returning an actual event)
     // ------------------------------------------------------------------------
diff --git a/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/TmfTraceIterator.java b/org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/trace/TmfTraceIterator.java
new file mode 100644 (file)
index 0000000..c0bc99b
--- /dev/null
@@ -0,0 +1,148 @@
+/*******************************************************************************
+ * Copyright (c) 2012 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:
+ *   Francois Chouinard - Initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.linuxtools.tmf.core.trace;
+
+import java.util.Iterator;
+
+import org.eclipse.linuxtools.tmf.core.event.ITmfEvent;
+import org.eclipse.linuxtools.tmf.core.event.ITmfTimestamp;
+
+/**
+ * A simple class to iterate over a TMF trace and return ITmfEvent:s. Its main
+ * purpose is to encapsulate the ITmfContext.
+ *
+ * @author Francois Chouinard
+ * @version 1.0
+ * @since 2.0
+ */
+public class TmfTraceIterator implements Iterator<ITmfEvent> {
+
+    // ------------------------------------------------------------------------
+    // Attributes
+    // ------------------------------------------------------------------------
+
+    private ITmfTrace   fTrace;     // The trace to iterate over
+    private ITmfContext fContext;   // The trace reading context
+    private ITmfEvent   fNextEvent; // The buffered next event
+
+    // ------------------------------------------------------------------------
+    // Constructors
+    // ------------------------------------------------------------------------
+
+    /**
+     * The standard constructor. Returns an iterator pointing to the start of
+     * the trace.
+     *
+     * @param trace the trace to iterate over
+     */
+    public TmfTraceIterator(ITmfTrace trace) {
+        this(trace, 0);
+    }
+
+    /**
+     * The rank constructor. Returns an iterator pointing to the event
+     * at the requested rank.
+     *
+     * @param trace the trace to iterate over
+     * @param rank the starting event rank
+     */
+    public TmfTraceIterator(ITmfTrace trace, long rank) {
+        fTrace = trace;
+        fContext = fTrace.seekEvent(rank);
+    }
+
+    /**
+     * The timestamp constructor. Returns an iterator pointing to the event
+     * at the requested timestamp.
+     *
+     * @param trace the trace to iterate over
+     * @param timestamp the starting event timestamp
+     */
+    public TmfTraceIterator(ITmfTrace trace, ITmfTimestamp timestamp) {
+        fTrace = trace;
+        fContext = fTrace.seekEvent(timestamp);
+    }
+
+    /**
+     * The location constructor. Returns an iterator pointing to the event
+     * at the requested location.
+     *
+     * @param trace the trace to iterate over
+     * @param location the starting event location
+     */
+    public TmfTraceIterator(ITmfTrace trace, ITmfLocation location) {
+        fTrace = trace;
+        fContext = fTrace.seekEvent(location);
+    }
+
+    /**
+     * The ratio constructor. Returns an iterator pointing to the event
+     * at the requested ratio.
+     *
+     * @param trace the trace to iterate over
+     * @param ratio the starting event ratio
+     */
+    public TmfTraceIterator(ITmfTrace trace, double ratio) {
+        fTrace = trace;
+        fContext = fTrace.seekEvent(ratio);
+    }
+
+    /**
+     * Copy constructor
+     *
+     * @param other the other iterator
+     */
+    public TmfTraceIterator(TmfTraceIterator other) {
+        fTrace = other.fTrace;
+        fContext = other.fContext.clone();
+    }
+
+    // ------------------------------------------------------------------------
+    // Iterator
+    // ------------------------------------------------------------------------
+
+    /* (non-Javadoc)
+     * @see java.util.Iterator#hasNext()
+     */
+    @Override
+    public boolean hasNext() {
+        if (fNextEvent == null) {
+            fNextEvent = fTrace.getNext(fContext);
+        }
+        return fNextEvent != null;
+    }
+
+    /* (non-Javadoc)
+     * @see java.util.Iterator#next()
+     */
+    @Override
+    public ITmfEvent next() {
+        ITmfEvent event;
+        if (fNextEvent != null) {
+            event = fNextEvent;
+            fNextEvent = null;
+        } else {
+            event = fTrace.getNext(fContext);
+        }
+        return event;
+    }
+
+    /* (non-Javadoc)
+     * @see java.util.Iterator#remove()
+     */
+    @Override
+    public void remove() {
+        throw new UnsupportedOperationException();
+    }
+
+}
This page took 0.031996 seconds and 5 git commands to generate.