tmf: Fix wrong interval returns in the history backend
authorAlexandre Montplaisir <alexmonthy@voxpopuli.im>
Sat, 28 Apr 2012 09:11:57 +0000 (05:11 -0400)
committerAlexandre Montplaisir <alexmonthy@voxpopuli.im>
Sat, 28 Apr 2012 09:20:35 +0000 (05:20 -0400)
Since intervals are sorted (by end time) in their nodes,
the algorithm to pick the correct interval during a query
would first find the "starting point", where the intervals
can begin intersecting the target time.

Then, it would iterate over the remainder of the list, but only
comparing the *start* times, since we know that at this point,
the end times should all fit in.

Turns out this is not the case! It's possible for a node's end
time to be greater than its last intervals' end times. So if a
query was done in this "empty space", the node could wrongly
return an interval whose start time fits, but not its end time!

If every other condition is respected, now we additionally check
the end time too. This avoids a potential infinite loop during
range queries.

Also updated the tests accordingly.

Signed-off-by: Alexandre Montplaisir <alexmonthy@voxpopuli.im>
org.eclipse.linuxtools.lttng2.kernel.core.tests/src/org/eclipse/linuxtools/lttng2/kernel/core/tests/stateprovider/StateSystemFullHistoryTest.java
org.eclipse.linuxtools.tmf.core/src/org/eclipse/linuxtools/tmf/core/statesystem/backend/historytree/HTNode.java

index 7ea49253867474367f0a1701693c8e0e7d97de5a..dcc51bbc14ec40acc658bb93e2a5d32a25e68e9f 100644 (file)
@@ -204,11 +204,31 @@ public class StateSystemFullHistoryTest {
         assertEquals(1331668248427681372L, intervals.get(205).getEndTime());
     }
 
+    /**
+     * Range query, but with a t2 far off the end of the trace.
+     * The result should still be valid.
+     */
+    @Test
+    public void testRangeQuery2() throws TimeRangeException,
+            AttributeNotFoundException {
+
+        List<ITmfStateInterval> intervals;
+        
+        int quark = shs.getQuarkAbsolute("CPUs", "0", "IRQ_stack");
+        long ts1 = shs.getHistoryBackend().getStartTime(); /* start of the trace */
+        long ts2 = CtfTestFiles.startTime + 20L * CtfTestFiles.NANOSECS_PER_SEC; /* invalid, but ignored */
+
+        intervals = shs.queryHistoryRange(quark, ts1, ts2);
+
+        /* Nb of IRQs on CPU 0 during the whole trace */
+        assertEquals(1653, intervals.size());
+    }
+
     /**
      * Test a range query with a resolution
      */
     @Test
-    public void testRangeQuery2() throws AttributeNotFoundException,
+    public void testRangeQuery3() throws AttributeNotFoundException,
             TimeRangeException, StateValueTypeException {
 
         long time1 = interestingTimestamp1;
@@ -276,17 +296,6 @@ public class StateSystemFullHistoryTest {
     public void testRangeQueryInvalidTime2() throws TimeRangeException,
             AttributeNotFoundException {
 
-        int quark = shs.getQuarkAbsolute("CPUs", "0", "Current_thread");
-        long ts1 = CtfTestFiles.startTime + 1L * CtfTestFiles.NANOSECS_PER_SEC; /* valid */
-        long ts2 = CtfTestFiles.startTime + 20L * CtfTestFiles.NANOSECS_PER_SEC; /* invalid */
-
-        shs.queryHistoryRange(quark, ts1, ts2);
-    }
-
-    @Test(expected = TimeRangeException.class)
-    public void testRangeQueryInvalidTime3() throws TimeRangeException,
-            AttributeNotFoundException {
-
         int quark = shs.getQuarkAbsolute("CPUs", "0", "Current_thread");
         long ts1 = CtfTestFiles.startTime - 1L * CtfTestFiles.NANOSECS_PER_SEC; /* invalid */
         long ts2 = CtfTestFiles.startTime + 20L * CtfTestFiles.NANOSECS_PER_SEC; /* invalid */
index 60147dbfcb859a7e1111b88c830b011a35ee9a34..7e16a37d362b4c988b6c144feb019afe9bf24d80 100644 (file)
@@ -329,6 +329,7 @@ abstract class HTNode {
     HTInterval getRelevantInterval(int key, long t) throws TimeRangeException {
         assert (this.isDone);
         int startIndex;
+        HTInterval curInterval;
 
         if (intervals.size() == 0) {
             return null;
@@ -337,10 +338,11 @@ abstract class HTNode {
         startIndex = getStartIndexFor(t);
 
         for (int i = startIndex; i < intervals.size(); i++) {
-            if (intervals.get(i).getAttribute() == key) {
-                if (intervals.get(i).getStartTime() <= t) {
-                    return intervals.get(i);
-                }
+            curInterval = intervals.get(i);
+            if (curInterval.getAttribute() == key
+                    && curInterval.getStartTime() <= t
+                    && curInterval.getEndTime() >= t) {
+                return curInterval;
             }
         }
         /* We didn't find the relevant information in this node */
This page took 0.028389 seconds and 5 git commands to generate.