From: Francois Chouinard Date: Wed, 13 Oct 2010 17:46:58 +0000 (+0000) Subject: 2010-10-13 Francois Chouinard Fix for Bug326823 X-Git-Url: http://drtracing.org/?a=commitdiff_plain;h=023761c4b0f2716b0222582dd1883380eadca095;p=deliverable%2Ftracecompass.git 2010-10-13 Francois Chouinard Fix for Bug326823 * src/org/eclipse/linuxtools/tmf/event/TmfEventContent.java: Added setEvent() * src/org/eclipse/linuxtools/tmf/event/TmfTimeRange.java: Added getIntersection() * src/org/eclipse/linuxtools/tmf/event/TmfTimestamp.java: Improved timestamp comparison * src/org/eclipse/linuxtools/tmf/tests/event/TmfEventContentTest.java: Added unit test for setEvent() * src/org/eclipse/linuxtools/tmf/tests/event/TmfTimeRangeTest.java: Adde unit test for getIntersection() --- diff --git a/org.eclipse.linuxtools.tmf.tests/ChangeLog b/org.eclipse.linuxtools.tmf.tests/ChangeLog index ef27554249..8bde3ae08d 100644 --- a/org.eclipse.linuxtools.tmf.tests/ChangeLog +++ b/org.eclipse.linuxtools.tmf.tests/ChangeLog @@ -1,3 +1,8 @@ +2010-10-13 Francois Chouinard + + * src/org/eclipse/linuxtools/tmf/tests/event/TmfEventContentTest.java: Added unit test for setEvent() + * src/org/eclipse/linuxtools/tmf/tests/event/TmfTimeRangeTest.java: Adde unit test for getIntersection() + 2010-09-09 Francois Chouinard * src/org/eclipse/linuxtools/tmf/tests/experiment/TmfExperimentTest.java: Added a few checks diff --git a/org.eclipse.linuxtools.tmf.tests/src/org/eclipse/linuxtools/tmf/tests/event/TmfEventContentTest.java b/org.eclipse.linuxtools.tmf.tests/src/org/eclipse/linuxtools/tmf/tests/event/TmfEventContentTest.java index da1de6294c..70cf546c54 100644 --- a/org.eclipse.linuxtools.tmf.tests/src/org/eclipse/linuxtools/tmf/tests/event/TmfEventContentTest.java +++ b/org.eclipse.linuxtools.tmf.tests/src/org/eclipse/linuxtools/tmf/tests/event/TmfEventContentTest.java @@ -12,6 +12,8 @@ package org.eclipse.linuxtools.tmf.tests.event; +import junit.framework.TestCase; + import org.eclipse.linuxtools.tmf.event.TmfEvent; import org.eclipse.linuxtools.tmf.event.TmfEventContent; import org.eclipse.linuxtools.tmf.event.TmfEventContentStub; @@ -22,8 +24,6 @@ import org.eclipse.linuxtools.tmf.event.TmfEventTypeStub; import org.eclipse.linuxtools.tmf.event.TmfNoSuchFieldException; import org.eclipse.linuxtools.tmf.event.TmfTimestamp; -import junit.framework.TestCase; - /** * TmfEventContentTest *

@@ -61,7 +61,7 @@ public class TmfEventContentTest extends TestCase { public TmfEventContentTest(String name) { super(name); fTimestamp = new TmfTimestamp(); - fEventSource = new TmfEventSource(); + fEventSource = new TmfEventSource(new Object()); fEventType = new TmfEventType(); fEventTypeStub = new TmfEventTypeStub(); fReference = new TmfEventReference(); @@ -112,6 +112,23 @@ public class TmfEventContentTest extends TestCase { } } + // ------------------------------------------------------------------------ + // setEvent + // ------------------------------------------------------------------------ + + public void testSetEvent() { + TmfEvent event = new TmfEvent(fTimestamp, fEventSource, fEventType, fReference); + TmfEventContent content1 = new TmfEventContent(event, fRawContent0); + event.setContent(content1); + TmfEventContent content2 = new TmfEventContent(null, fRawContent1); + + content2.setEvent(event); + + assertEquals("setEvent", event, content2.getEvent()); +// assertEquals("setEvent", content2, event.getContent()); +// assertEquals("setEvent", null, content1.getEvent()); + } + // ------------------------------------------------------------------------ // equals // ------------------------------------------------------------------------ diff --git a/org.eclipse.linuxtools.tmf.tests/src/org/eclipse/linuxtools/tmf/tests/event/TmfTimeRangeTest.java b/org.eclipse.linuxtools.tmf.tests/src/org/eclipse/linuxtools/tmf/tests/event/TmfTimeRangeTest.java index 4efb0335c3..ea99827e05 100644 --- a/org.eclipse.linuxtools.tmf.tests/src/org/eclipse/linuxtools/tmf/tests/event/TmfTimeRangeTest.java +++ b/org.eclipse.linuxtools.tmf.tests/src/org/eclipse/linuxtools/tmf/tests/event/TmfTimeRangeTest.java @@ -219,4 +219,64 @@ public class TmfTimeRangeTest extends TestCase { assertFalse("contains (high value)", range.contains(new TmfTimestamp(12351))); } + // ------------------------------------------------------------------------ + // getIntersection + // ------------------------------------------------------------------------ + + public void testGetIntersection() throws Exception { + + TmfTimestamp ts1a = new TmfTimestamp(1000); + TmfTimestamp ts1b = new TmfTimestamp(2000); + TmfTimeRange range1 = new TmfTimeRange(ts1a, ts1b); + + TmfTimestamp ts2a = new TmfTimestamp(2000); + TmfTimestamp ts2b = new TmfTimestamp(3000); + TmfTimeRange range2 = new TmfTimeRange(ts2a, ts2b); + + TmfTimestamp ts3a = new TmfTimestamp(3000); + TmfTimestamp ts3b = new TmfTimestamp(4000); + TmfTimeRange range3 = new TmfTimeRange(ts3a, ts3b); + + TmfTimestamp ts4a = new TmfTimestamp(1500); + TmfTimestamp ts4b = new TmfTimestamp(2500); + TmfTimeRange range4 = new TmfTimeRange(ts4a, ts4b); + + TmfTimestamp ts5a = new TmfTimestamp(1500); + TmfTimestamp ts5b = new TmfTimestamp(2000); + TmfTimeRange range5 = new TmfTimeRange(ts5a, ts5b); + + TmfTimestamp ts6a = new TmfTimestamp(2000); + TmfTimestamp ts6b = new TmfTimestamp(2500); + TmfTimeRange range6 = new TmfTimeRange(ts6a, ts6b); + + TmfTimestamp ts7a = new TmfTimestamp(1500); + TmfTimestamp ts7b = new TmfTimestamp(3500); + TmfTimeRange range7 = new TmfTimeRange(ts7a, ts7b); + + TmfTimestamp ts8a = new TmfTimestamp(2250); + TmfTimestamp ts8b = new TmfTimestamp(2750); + TmfTimeRange range8 = new TmfTimeRange(ts8a, ts8b); + + assertEquals("getIntersection (below - not contiguous)", null, range1.getIntersection(range3)); + assertEquals("getIntersection (above - not contiguous)", null, range3.getIntersection(range1)); + + assertEquals("getIntersection (below - contiguous)", new TmfTimeRange(ts1b, ts1b), range1.getIntersection(range2)); + assertEquals("getIntersection (above - contiguous)", new TmfTimeRange(ts3a, ts3a), range3.getIntersection(range2)); + + assertEquals("getIntersection (below - overlap)", new TmfTimeRange(ts2a, ts4b), range2.getIntersection(range4)); + assertEquals("getIntersection (above - overlap)", new TmfTimeRange(ts2a, ts4b), range4.getIntersection(range2)); + + assertEquals("getIntersection (within - overlap1)", range6, range2.getIntersection(range6)); + assertEquals("getIntersection (within - overlap2)", range6, range6.getIntersection(range2)); + + assertEquals("getIntersection (within - overlap3)", range5, range1.getIntersection(range5)); + assertEquals("getIntersection (within - overlap4)", range5, range5.getIntersection(range1)); + + assertEquals("getIntersection (within - overlap5)", range8, range2.getIntersection(range8)); + assertEquals("getIntersection (within - overlap6)", range8, range8.getIntersection(range2)); + + assertEquals("getIntersection (accross1)", range2, range2.getIntersection(range7)); + assertEquals("getIntersection (accross2)", range2, range7.getIntersection(range2)); + } + } diff --git a/org.eclipse.linuxtools.tmf/ChangeLog b/org.eclipse.linuxtools.tmf/ChangeLog index 884a10d9b1..695b791770 100644 --- a/org.eclipse.linuxtools.tmf/ChangeLog +++ b/org.eclipse.linuxtools.tmf/ChangeLog @@ -1,3 +1,9 @@ +2010-10-13 Francois Chouinard + + * src/org/eclipse/linuxtools/tmf/event/TmfEventContent.java: Added setEvent() + * src/org/eclipse/linuxtools/tmf/event/TmfTimeRange.java: Added getIntersection() + * src/org/eclipse/linuxtools/tmf/event/TmfTimestamp.java: Improved timestamp comparison + 2010-09-17 Francois Chouinard * src/org/eclipse/linuxtools/tmf/component/TmfDataProvider.java: Adjusted to new handleData() API diff --git a/org.eclipse.linuxtools.tmf/src/org/eclipse/linuxtools/tmf/event/TmfEventContent.java b/org.eclipse.linuxtools.tmf/src/org/eclipse/linuxtools/tmf/event/TmfEventContent.java index 662ad85fb8..50a0b09d6d 100644 --- a/org.eclipse.linuxtools.tmf/src/org/eclipse/linuxtools/tmf/event/TmfEventContent.java +++ b/org.eclipse.linuxtools.tmf/src/org/eclipse/linuxtools/tmf/event/TmfEventContent.java @@ -124,6 +124,13 @@ public class TmfEventContent { // Operators // ------------------------------------------------------------------------ + /** + * @param event + */ + public void setEvent(TmfEvent event) { + fParentEvent = event; + } + /** * Parse the content into fields. By default, a single field (the raw * content) is returned. diff --git a/org.eclipse.linuxtools.tmf/src/org/eclipse/linuxtools/tmf/event/TmfTimeRange.java b/org.eclipse.linuxtools.tmf/src/org/eclipse/linuxtools/tmf/event/TmfTimeRange.java index a5a51f4bab..9f76b22e3a 100644 --- a/org.eclipse.linuxtools.tmf/src/org/eclipse/linuxtools/tmf/event/TmfTimeRange.java +++ b/org.eclipse.linuxtools.tmf/src/org/eclipse/linuxtools/tmf/event/TmfTimeRange.java @@ -99,6 +99,23 @@ public class TmfTimeRange { return (fStartTime.compareTo(ts, true) <= 0) && (fEndTime.compareTo(ts, true) >= 0); } + /** + * Get intersection of two time ranges + * + * @param other + * the other time range + * @return the intersection time range, or null if no intersection exists + */ + public TmfTimeRange getIntersection(TmfTimeRange other) + { + if (fStartTime.compareTo(other.fEndTime, true) > 0 || fEndTime.compareTo(other.fStartTime, true) < 0) + return null; // no intersection + + return new TmfTimeRange( + fStartTime.compareTo(other.fStartTime, true) < 0 ? other.fStartTime : fStartTime, + fEndTime.compareTo(other.fEndTime, true) > 0 ? other.fEndTime : fEndTime); + } + /** * Check if the time range is within the time range * diff --git a/org.eclipse.linuxtools.tmf/src/org/eclipse/linuxtools/tmf/event/TmfTimestamp.java b/org.eclipse.linuxtools.tmf/src/org/eclipse/linuxtools/tmf/event/TmfTimestamp.java index d3a0b76dce..a9407ed113 100644 --- a/org.eclipse.linuxtools.tmf/src/org/eclipse/linuxtools/tmf/event/TmfTimestamp.java +++ b/org.eclipse.linuxtools.tmf/src/org/eclipse/linuxtools/tmf/event/TmfTimestamp.java @@ -8,6 +8,7 @@ * * Contributors: * Francois Chouinard - Initial API and implementation + * Thomas Gatterweh - Updated scaling / synchronization *******************************************************************************/ package org.eclipse.linuxtools.tmf.event; @@ -60,15 +61,6 @@ public class TmfTimestamp implements Cloneable { public static final TmfTimestamp BigCrunch = new TmfTimestamp(Long.MAX_VALUE, Byte.MAX_VALUE, 0); public static final TmfTimestamp Zero = new TmfTimestamp(0, (byte) 0, 0); - /* - * A java long has a maximum of 19 significant digits. - * (-9,223,372,036,854,775,808 .. +9,223,372,036,854,775,807) - * - * It is therefore useless to try to synchronize 2 timestamps whose - * difference in scale exceeds that value. - */ - private int MAX_SCALING = 19; - // ------------------------------------------------------------------------ // Constructors // ------------------------------------------------------------------------ @@ -167,21 +159,22 @@ public class TmfTimestamp implements Cloneable { */ public TmfTimestamp synchronize(long offset, byte newScale) throws ArithmeticException { - long newValue = fValue; + long newValue = fValue; long newPrecision = fPrecision; + // Handle the easy case + if (fScale == newScale && offset == 0) + return this; + // Determine the scaling factor if (fScale != newScale) { int scaleDiff = Math.abs(fScale - newScale); // Let's try to be realistic... - if (scaleDiff > MAX_SCALING) { + if (scaleDiff >= scalingFactors.length) { throw new ArithmeticException("Scaling exception"); } - // Not pretty... - long scalingFactor = 1; - for (int i = 0; i < scaleDiff; i++) { - scalingFactor *= 10; - } + // Adjust the timestamp + long scalingFactor = scalingFactors[scaleDiff]; if (newScale < fScale) { newValue *= scalingFactor; newPrecision *= scalingFactor; @@ -191,9 +184,64 @@ public class TmfTimestamp implements Cloneable { } } - return new TmfTimestamp(newValue + offset, newScale, newPrecision); + if (offset < 0) { + newValue = (newValue < Long.MIN_VALUE - offset) ? Long.MIN_VALUE : newValue + offset; + } else { + newValue = (newValue > Long.MAX_VALUE - offset) ? Long.MAX_VALUE : newValue + offset; + } + + return new TmfTimestamp(newValue, newScale, newPrecision); } + private static final long scalingFactors[] = new long[] { + 1L, + 10L, + 100L, + 1000L, + 10000L, + 100000L, + 1000000L, + 10000000L, + 100000000L, + 1000000000L, + 10000000000L, + 100000000000L, + 1000000000000L, + 10000000000000L, + 100000000000000L, + 1000000000000000L, + 10000000000000000L, + 100000000000000000L, + 1000000000000000000L, + }; + + private static final long scalingLimits[] = new long[] { + Long.MAX_VALUE / 1L, + Long.MAX_VALUE / 10L, + Long.MAX_VALUE / 100L, + Long.MAX_VALUE / 1000L, + Long.MAX_VALUE / 10000L, + Long.MAX_VALUE / 100000L, + Long.MAX_VALUE / 1000000L, + Long.MAX_VALUE / 10000000L, + Long.MAX_VALUE / 100000000L, + Long.MAX_VALUE / 1000000000L, + Long.MAX_VALUE / 10000000000L, + Long.MAX_VALUE / 100000000000L, + Long.MAX_VALUE / 1000000000000L, + Long.MAX_VALUE / 10000000000000L, + Long.MAX_VALUE / 100000000000000L, + Long.MAX_VALUE / 1000000000000000L, + Long.MAX_VALUE / 10000000000000000L, + Long.MAX_VALUE / 100000000000000000L, + Long.MAX_VALUE / 1000000000000000000L, + }; + + public static long getScalingFactor(byte scale) + { + return scalingFactors[scale]; + } + /** * Compute the adjustment, in the reference scale, needed to synchronize * this timestamp with a reference timestamp. @@ -220,48 +268,69 @@ public class TmfTimestamp implements Cloneable { */ public int compareTo(final TmfTimestamp other, boolean withinPrecision) { - // If values have the same time scale, perform the comparison - if (fScale == other.fScale) { - if (withinPrecision) { - if ((fValue + fPrecision) < (other.fValue - other.fPrecision)) - return -1; - if ((fValue - fPrecision) > (other.fValue + other.fPrecision)) - return 1; - return 0; - } - return (fValue == other.fValue) ? 0 : (fValue < other.fValue) ? -1 : 1; - } + // If values have the same time scale, perform the comparison + if (fScale == other.fScale) { + if (withinPrecision) + return compareWithinPrecision(this.fValue, this.fPrecision, other.fValue, other.fPrecision); + else + return compareNoPrecision(this.fValue, other.fValue); + } - // If values have different time scales, adjust to the finest one and - // then compare. If the scaling difference is too large, revert to - // some heuristics. Hopefully, nobody will try to compare galactic and - // quantic clock events... - if (Math.abs(fScale - other.fScale) > MAX_SCALING) { - return simpleCompare(other); - } + // If values have different time scales, adjust to the finest one and + // then compare. If the scaling difference is too large, revert to + // some heuristics. Hopefully, nobody will try to compare galactic and + // quantic clock events... + int scaleDiff = Math.abs(fScale - other.fScale); + long factor, limit; + if (scaleDiff < scalingFactors.length) { + factor = scalingFactors[scaleDiff]; + limit = scalingLimits[scaleDiff]; + } else { + factor = 0; + limit = 0; // !!! 0 can always be scaled!!! + } - byte newScale = (fScale < other.fScale) ? fScale : other.fScale; - try { - TmfTimestamp ts1 = this.synchronize(0, newScale); - TmfTimestamp ts2 = other.synchronize(0, newScale); - return ts1.compareTo(ts2, withinPrecision); - } catch (ArithmeticException e) { - return simpleCompare(other); - } + if (fScale < other.fScale) { + // this has finer scale, so other should be scaled + if (withinPrecision) + if (other.fValue > limit || other.fValue < -limit + || other.fPrecision > limit + || other.fPrecision < -limit) + return other.fValue > 0 ? -1 : +1; // other exceeds scaling limit + else + return compareWithinPrecision(this.fValue, this.fPrecision, + other.fValue * factor, other.fPrecision * factor); + else if (other.fValue > limit || other.fValue < -limit) + return other.fValue > 0 ? -1 : +1; // other exceeds scaling limit + else + return compareNoPrecision(this.fValue, other.fValue * factor); + } else { + // other has finer scale, so this should be scaled + if (withinPrecision) + if (this.fValue > limit || this.fValue < -limit + || this.fPrecision > limit || this.fPrecision < -limit) + return this.fValue > 0 ? +1 : -1; // we exceed scaling limit + else + return compareWithinPrecision(this.fValue * factor, + this.fPrecision * factor, other.fValue, + other.fPrecision); + else if (this.fValue > limit || this.fValue < -limit) + return this.fValue > 0 ? +1 : -1; // we exceed scaling limit + else + return compareNoPrecision(this.fValue * factor, other.fValue); + } } - private int simpleCompare(final TmfTimestamp other) { - if ((fValue == 0) || (other.fValue == 0)) { - return (fValue == other.fValue) ? 0 - : (fValue < other.fValue) ? -1 : 1; - } - if ((fValue > 0) && (other.fValue > 0)) { - return (fScale < other.fScale) ? -1 : 1; - } - if ((fValue < 0) && (other.fValue < 0)) { - return (fScale > other.fScale) ? -1 : 1; - } - return (fValue < 0) ? -1 : 1; + private static int compareNoPrecision(long thisValue, long otherValue) { + return (thisValue == otherValue) ? 0 : (thisValue < otherValue) ? -1 : 1; + } + + private static int compareWithinPrecision(long thisValue, long thisPrecision, long otherValue, long otherPrecision) { + if ((thisValue + thisPrecision) < (otherValue - otherPrecision)) + return -1; + if ((thisValue - thisPrecision) > (otherValue + otherPrecision)) + return 1; + return 0; } // ------------------------------------------------------------------------ @@ -303,4 +372,4 @@ public class TmfTimestamp implements Cloneable { return clone; } -} \ No newline at end of file +}