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;
import org.eclipse.linuxtools.tmf.event.TmfNoSuchFieldException;
import org.eclipse.linuxtools.tmf.event.TmfTimestamp;
-import junit.framework.TestCase;
-
/**
* <b><u>TmfEventContentTest</u></b>
* <p>
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();
}
}
+ // ------------------------------------------------------------------------
+ // 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
// ------------------------------------------------------------------------
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));
+ }
+
}
*
* Contributors:
* Francois Chouinard - Initial API and implementation
+ * Thomas Gatterweh - Updated scaling / synchronization
*******************************************************************************/
package org.eclipse.linuxtools.tmf.event;
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 <code>long</code> 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
// ------------------------------------------------------------------------
*/
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;
}
}
- 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.
*/
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;
}
// ------------------------------------------------------------------------
return clone;
}
-}
\ No newline at end of file
+}