tmf: Speed up TmfTraceUtils#getPreviousEventMatching
authorMatthew Khouzam <matthew.khouzam@ericsson.com>
Tue, 28 Jun 2016 20:16:43 +0000 (16:16 -0400)
committerAlexandre Montplaisir <alexmonthy@efficios.com>
Thu, 30 Jun 2016 23:52:01 +0000 (19:52 -0400)
This patch makes the reverse search look back by the cache
size of the trace, then iterating on the chunk in reverse
order to find a match. This allows returning as soon as
we find a matching event.

Change-Id: Iaed2c2326d5a4939688df7ba6d13696811d1c165
Signed-off-by: Matthew Khouzam <matthew.khouzam@ericsson.com>
Signed-off-by: Alexandre Montplaisir <alexmonthy@efficios.com>
Reviewed-on: https://git.eclipse.org/r/76164
Reviewed-by: Hudson CI
Reviewed-by: Patrick Tasse <patrick.tasse@gmail.com>
tmf/org.eclipse.tracecompass.tmf.core/src/org/eclipse/tracecompass/tmf/core/trace/TmfTraceUtils.java

index cc47c59e7c353060cf73fd750cab95fb029670f5..b32bc6487b60ae960ee0b7bf14a376b3533c94bf 100644 (file)
@@ -20,6 +20,7 @@ import java.io.FileInputStream;
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Optional;
 import java.util.function.Predicate;
 
 import org.eclipse.jdt.annotation.NonNull;
@@ -33,6 +34,7 @@ import org.eclipse.tracecompass.tmf.core.event.aspect.ITmfEventAspect;
 import org.eclipse.tracecompass.tmf.core.request.TmfEventRequest;
 
 import com.google.common.collect.Iterables;
+import com.google.common.collect.Lists;
 
 /**
  * Utility methods for ITmfTrace's.
@@ -226,30 +228,37 @@ public final class TmfTraceUtils {
      */
     public static @Nullable ITmfEvent getPreviousEventMatching(ITmfTrace trace, long startRank, Predicate<ITmfEvent> predicate) {
         /*
-         * Slightly less straightforward since we unfortunately cannot iterate
-         * backwards on events. Do a series of forward-queries.
+         * 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
+         * the found events in reverse order until we find a match.
          */
-        final int targetStep = 100;
+        int step = trace.getCacheSize();
 
         /*
          * If we are close to the beginning of the trace, make sure we only look
          * for the events before the startRank.
          */
-        int step = (startRank < targetStep ? (int) startRank : targetStep);
+        if (startRank < step) {
+            step = (int) startRank;
+        }
 
         long currentRank = startRank;
         try {
             while (currentRank > 0) {
                 currentRank = Math.max(currentRank - step, 0);
 
-                EventMatchingRequest req = new EventMatchingRequest(currentRank, step, predicate, true);
+                List<ITmfEvent> list = new ArrayList<>(step);
+                ArrayFillingRequest req = new ArrayFillingRequest(currentRank, step, list);
                 trace.sendRequest(req);
                 req.waitForCompletion();
 
-                ITmfEvent event = req.getFoundEvent();
-                if (event != null) {
-                    /* We found an actual event, return it! */
-                    return event;
+                Optional<ITmfEvent> matchingEvent = Lists.reverse(list).stream()
+                    .filter(predicate)
+                    .findFirst();
+
+                if (matchingEvent.isPresent()) {
+                    /* We found an event matching, return it! */
+                    return matchingEvent.get();
                 }
                 /* Keep searching, next loop */
 
@@ -332,4 +341,25 @@ public final class TmfTraceUtils {
             }
         }
     }
+
+    /**
+     * Event request that simply puts all returned events into a list passed in
+     * parameter.
+     */
+    private static class ArrayFillingRequest extends TmfEventRequest {
+
+        private final List<ITmfEvent> fList;
+
+        public ArrayFillingRequest(long startRank, int limit, List<ITmfEvent> listToFill) {
+            super(ITmfEvent.class, startRank, limit, ExecutionType.FOREGROUND);
+            fList = listToFill;
+        }
+
+        @Override
+        public void handleData(ITmfEvent event) {
+            super.handleData(event);
+            fList.add(event);
+        }
+
+    }
 }
This page took 0.026043 seconds and 5 git commands to generate.