tmf: Add possibilty to cancel search event requests
authorAlexandre Montplaisir <alexmonthy@efficios.com>
Wed, 29 Jun 2016 02:38:27 +0000 (22:38 -0400)
committerAlexandre Montplaisir <alexmonthy@efficios.com>
Fri, 8 Jul 2016 01:35:35 +0000 (21:35 -0400)
By passing an optional monitor (that will probably come from an
Eclipse job anyway), we can allow the potentially long requests
to be cancelled.

Change-Id: Id8e7d8abf670edd333fc393cfd8d3c1465662a1c
Signed-off-by: Alexandre Montplaisir <alexmonthy@efficios.com>
Reviewed-on: https://git.eclipse.org/r/76227
Reviewed-by: Hudson CI
Reviewed-by: Matthew Khouzam <matthew.khouzam@ericsson.com>
Tested-by: Matthew Khouzam <matthew.khouzam@ericsson.com>
ctf/org.eclipse.tracecompass.tmf.ctf.core.tests/src/org/eclipse/tracecompass/tmf/ctf/core/tests/trace/TmfTraceUtilsSearchingTest.java
tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/trace/TmfTraceUtils.java

index 66e6d31f67d859548b347c88b53bde75d76411a5..841316dfe9639eb3e2354ac211a180c47f84e166 100644 (file)
@@ -16,6 +16,8 @@ import static org.junit.Assert.assertNotEquals;
 
 import java.util.function.Predicate;
 
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.NullProgressMonitor;
 import org.eclipse.jdt.annotation.NonNull;
 import org.eclipse.tracecompass.testtraces.ctf.CtfTestTrace;
 import org.eclipse.tracecompass.tmf.core.event.ITmfEvent;
@@ -62,6 +64,10 @@ public class TmfTraceUtilsSearchingTest {
         }
     }
 
+    // ------------------------------------------------------------------------
+    // Forwards searches
+    // ------------------------------------------------------------------------
+
     /**
      * Test the {@link TmfTraceUtils#getNextEventMatching} method.
      */
@@ -72,7 +78,26 @@ public class TmfTraceUtilsSearchingTest {
 
         Predicate<@NonNull ITmfEvent> predicate = event -> event.getName().equals("sched_switch");
 
-        ITmfEvent actualEvent = TmfTraceUtils.getNextEventMatching(trace, START_RANK, predicate);
+        ITmfEvent actualEvent = TmfTraceUtils.getNextEventMatching(trace, START_RANK, predicate, null);
+
+        ITmfContext ctx = trace.seekEvent(508L); // following sched_switch event
+        ITmfEvent expectedEvent = trace.getNext(ctx);
+
+        assertEquals(expectedEvent, actualEvent);
+    }
+
+    /**
+     * Test that the presence of progress monitor does not affect the results.
+     */
+    @Test
+    public void testNextMatchingEventProgressMonitor() {
+        ITmfTrace trace = fTrace;
+        assertNotNull(trace);
+
+        Predicate<@NonNull ITmfEvent> predicate = event -> event.getName().equals("sched_switch");
+
+        IProgressMonitor monitor = new NullProgressMonitor();
+        ITmfEvent actualEvent = TmfTraceUtils.getNextEventMatching(trace, START_RANK, predicate, monitor);
 
         ITmfContext ctx = trace.seekEvent(508L); // following sched_switch event
         ITmfEvent expectedEvent = trace.getNext(ctx);
@@ -91,7 +116,7 @@ public class TmfTraceUtilsSearchingTest {
 
         Predicate<@NonNull ITmfEvent> predicate = event -> event.getName().equals("non-existent-event");
 
-        ITmfEvent actualEvent = TmfTraceUtils.getNextEventMatching(trace, START_RANK, predicate);
+        ITmfEvent actualEvent = TmfTraceUtils.getNextEventMatching(trace, START_RANK, predicate, null);
         assertNull(actualEvent);
     }
 
@@ -106,12 +131,34 @@ public class TmfTraceUtilsSearchingTest {
         assertNotNull(trace);
 
         Predicate<@NonNull ITmfEvent> predicate = event -> event.getName().equals("softirq_raise");
-        ITmfEvent foundEvent = TmfTraceUtils.getNextEventMatching(trace, START_RANK, predicate);
+        ITmfEvent foundEvent = TmfTraceUtils.getNextEventMatching(trace, START_RANK, predicate, null);
 
         assertNotNull(foundEvent);
         assertNotEquals(fStartEvent, foundEvent);
     }
 
+    /**
+     * Test with a progress monitor that cancels the job.
+     */
+    @Test
+    public void testNextMatchingEventCancelled() {
+        ITmfTrace trace = fTrace;
+        assertNotNull(trace);
+
+        Predicate<@NonNull ITmfEvent> predicate = event -> event.getName().equals("sched_switch");
+
+        IProgressMonitor monitor = new NullProgressMonitor();
+        monitor.setCanceled(true);
+        ITmfEvent actualEvent = TmfTraceUtils.getNextEventMatching(trace, START_RANK, predicate, monitor);
+
+        /* No event should be returend */
+        assertNull(actualEvent);
+    }
+
+    // ------------------------------------------------------------------------
+    // Backwards searches
+    // ------------------------------------------------------------------------
+
     /**
      * Test the {@link TmfTraceUtils#getPreviousEventMatching} method.
      */
@@ -122,7 +169,26 @@ public class TmfTraceUtilsSearchingTest {
 
         Predicate<@NonNull ITmfEvent> predicate = event -> event.getName().equals("sched_switch");
 
-        ITmfEvent actualEvent = TmfTraceUtils.getPreviousEventMatching(trace, START_RANK, predicate);
+        ITmfEvent actualEvent = TmfTraceUtils.getPreviousEventMatching(trace, START_RANK, predicate, null);
+
+        ITmfContext ctx = trace.seekEvent(455L); // previous sched_switch event
+        ITmfEvent expectedEvent = trace.getNext(ctx);
+
+        assertEquals(expectedEvent, actualEvent);
+    }
+
+    /**
+     * Test that the presence of progress monitor does not affect the results.
+     */
+    @Test
+    public void testPreviousMatchingEventProgressMonitor() {
+        ITmfTrace trace = fTrace;
+        assertNotNull(trace);
+
+        Predicate<@NonNull ITmfEvent> predicate = event -> event.getName().equals("sched_switch");
+
+        IProgressMonitor monitor = new NullProgressMonitor();
+        ITmfEvent actualEvent = TmfTraceUtils.getPreviousEventMatching(trace, START_RANK, predicate, monitor);
 
         ITmfContext ctx = trace.seekEvent(455L); // previous sched_switch event
         ITmfEvent expectedEvent = trace.getNext(ctx);
@@ -141,7 +207,7 @@ public class TmfTraceUtilsSearchingTest {
 
         Predicate<@NonNull ITmfEvent> predicate = event -> event.getName().equals("non-existent-event");
 
-        ITmfEvent actualEvent = TmfTraceUtils.getPreviousEventMatching(trace, START_RANK, predicate);
+        ITmfEvent actualEvent = TmfTraceUtils.getPreviousEventMatching(trace, START_RANK, predicate, null);
         assertNull(actualEvent);
     }
 
@@ -156,7 +222,7 @@ public class TmfTraceUtilsSearchingTest {
         assertNotNull(trace);
 
         Predicate<@NonNull ITmfEvent> predicate = event -> event.getName().equals("softirq_raise");
-        ITmfEvent foundEvent = TmfTraceUtils.getPreviousEventMatching(trace, START_RANK, predicate);
+        ITmfEvent foundEvent = TmfTraceUtils.getPreviousEventMatching(trace, START_RANK, predicate, null);
 
         assertNotNull(foundEvent);
         assertNotEquals(fStartEvent, foundEvent);
@@ -172,7 +238,7 @@ public class TmfTraceUtilsSearchingTest {
         assertNotNull(trace);
 
         Predicate<@NonNull ITmfEvent> predicate = event -> event.getName().equals("sys_write");
-        ITmfEvent actualEvent = TmfTraceUtils.getPreviousEventMatching(trace, START_RANK, predicate);
+        ITmfEvent actualEvent = TmfTraceUtils.getPreviousEventMatching(trace, START_RANK, predicate, null);
 
         ITmfContext ctx = trace.seekEvent(387L); // previous sched_switch event
         ITmfEvent expectedEvent = trace.getNext(ctx);
@@ -196,12 +262,30 @@ public class TmfTraceUtilsSearchingTest {
 
         /* There is a sys_mmap at rank 6, it should not be matched! */
         Predicate<@NonNull ITmfEvent> predicate = event -> event.getName().equals("sys_mmap");
-        ITmfEvent foundEvent = TmfTraceUtils.getPreviousEventMatching(trace, startRank, predicate);
+        ITmfEvent foundEvent = TmfTraceUtils.getPreviousEventMatching(trace, startRank, predicate, null);
         assertNull(foundEvent);
 
         /* Do not match the event itself either, or any later "exit_syscall" */
         predicate = event -> event.getName().equals("exit_syscall");
-        foundEvent = TmfTraceUtils.getPreviousEventMatching(trace, startRank, predicate);
+        foundEvent = TmfTraceUtils.getPreviousEventMatching(trace, startRank, predicate, null);
         assertNull(foundEvent);
     }
+
+    /**
+     * Test with a progress monitor that cancels the job.
+     */
+    @Test
+    public void testPreviousMatchingEventCancelled() {
+        ITmfTrace trace = fTrace;
+        assertNotNull(trace);
+
+        Predicate<@NonNull ITmfEvent> predicate = event -> event.getName().equals("sched_switch");
+
+        IProgressMonitor monitor = new NullProgressMonitor();
+        monitor.setCanceled(true);
+        ITmfEvent actualEvent = TmfTraceUtils.getPreviousEventMatching(trace, START_RANK, predicate, monitor);
+
+        /* No event should be returend */
+        assertNull(actualEvent);
+    }
 }
index b32bc6487b60ae960ee0b7bf14a376b3533c94bf..64b08c135ca1a755e48c6c401ffc00188f3bc8c8 100644 (file)
@@ -23,6 +23,7 @@ import java.util.List;
 import java.util.Optional;
 import java.util.function.Predicate;
 
+import org.eclipse.core.runtime.IProgressMonitor;
 import org.eclipse.jdt.annotation.NonNull;
 import org.eclipse.jdt.annotation.NonNullByDefault;
 import org.eclipse.jdt.annotation.Nullable;
@@ -195,15 +196,28 @@ public final class TmfTraceUtils {
      *            <code>0</code> to search from the start of the trace.
      * @param predicate
      *            The predicate to test events against
+     * @param monitor
+     *            Optional progress monitor that can be used to cancel the
+     *            operation
      * @return The first event matching the predicate, or null if the end of the
      *         trace was reached and no event was found
      * @since 2.1
      */
-    public static @Nullable ITmfEvent getNextEventMatching(ITmfTrace trace, long startRank, Predicate<ITmfEvent> predicate) {
+    public static @Nullable ITmfEvent getNextEventMatching(ITmfTrace trace, long startRank,
+            Predicate<ITmfEvent> predicate, @Nullable IProgressMonitor monitor) {
         /* rank + 1 because we do not want to include the start event itself in the search */
         EventMatchingRequest req = new EventMatchingRequest(startRank + 1, predicate, false);
         trace.sendRequest(req);
         try {
+            /* Check periodically if the job was cancelled */
+            req.waitForStart();
+            while (req.isRunning()) {
+                Thread.sleep(200);
+                if (monitor != null && monitor.isCanceled()) {
+                    req.cancel();
+                    return null;
+                }
+            }
             req.waitForCompletion();
         } catch (InterruptedException e) {
             return null;
@@ -222,11 +236,14 @@ public final class TmfTraceUtils {
      *            The rank of the event at which to start searching backwards.
      * @param predicate
      *            The predicate to test events against
+     * @param monitor Optional progress monitor that can be used to cancel the
+     *            operation
      * @return The first event found matching the predicate, or null if the
      *         beginning of the trace was reached and no event was found
      * @since 2.1
      */
-    public static @Nullable ITmfEvent getPreviousEventMatching(ITmfTrace trace, long startRank, Predicate<ITmfEvent> predicate) {
+    public static @Nullable ITmfEvent getPreviousEventMatching(ITmfTrace trace, long startRank,
+            Predicate<ITmfEvent> predicate, @Nullable IProgressMonitor monitor) {
         /*
          * We are going to do a series of queries matching the trace's cache
          * size in length (which should minimize on-disk seeks), then iterate on
@@ -250,6 +267,16 @@ public final class TmfTraceUtils {
                 List<ITmfEvent> list = new ArrayList<>(step);
                 ArrayFillingRequest req = new ArrayFillingRequest(currentRank, step, list);
                 trace.sendRequest(req);
+
+                /* Check periodically if the job was cancelled */
+                req.waitForStart();
+                while (req.isRunning()) {
+                    Thread.sleep(200);
+                    if (monitor != null && monitor.isCanceled()) {
+                        req.cancel();
+                        return null;
+                    }
+                }
                 req.waitForCompletion();
 
                 Optional<ITmfEvent> matchingEvent = Lists.reverse(list).stream()
This page took 0.0299 seconds and 5 git commands to generate.