"Fixed" the failing test...
[deliverable/tracecompass.git] / org.eclipse.linuxtools.tmf / src / org / eclipse / linuxtools / tmf / event / TmfTimestamp.java
CommitLineData
8c8bf09f 1/*******************************************************************************
cbd4ad82 2 * Copyright (c) 2009, 2010 Ericsson
8c8bf09f
ASL
3 *
4 * All rights reserved. This program and the accompanying materials are
5 * made available under the terms of the Eclipse Public License v1.0 which
6 * accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
8 *
9 * Contributors:
1f506a43 10 * Francois Chouinard - Initial API and implementation
8c8bf09f
ASL
11 *******************************************************************************/
12
13package org.eclipse.linuxtools.tmf.event;
14
ff4ed569 15
8c8bf09f
ASL
16/**
17 * <b><u>TmfTimestamp</u></b>
18 * <p>
19 * The fundamental time reference in the TMF.
20 * <p>
21 * It provides a generic timestamp implementation in its most basic form:
22 * <ul>
cbd4ad82
FC
23 * <li>timestamp = [value] * 10**[scale] +/- [precision]
24 * </ul>
25 * Where:
26 * <ul>
27 * <li>[value] is an unstructured integer value
28 * <li>[scale] is the magnitude of the value wrt some application-specific
29 * base unit (e.g. the second)
30 * <li>[precision] indicates the error on the value (useful for comparing
1f506a43 31 * timestamps in different scales). Default: 0.
8c8bf09f 32 * </ul>
cbd4ad82
FC
33 * In short:
34 * <ul>
35 * </ul>
28b94d61 36 * To allow synchronization of timestamps from different reference clocks,
cbd4ad82
FC
37 * there is a possibility to "adjust" the timestamp by changing its scale
38 * (traces of different time scale) and/or by adding an offset to its value
39 * (clock drift between traces).
8c8bf09f 40 * <p>
28b94d61
FC
41 * Notice that the adjusted timestamp value could be negative e.g. for events
42 * that occurred before t0 wrt the reference clock.
8c8bf09f 43 */
ff4ed569 44public class TmfTimestamp implements Cloneable {
98029bc9 45
cbd4ad82 46 // ------------------------------------------------------------------------
8c8bf09f 47 // Attributes
cbd4ad82 48 // ------------------------------------------------------------------------
8c8bf09f 49
cbd4ad82 50 protected long fValue; // The timestamp raw value
28b94d61
FC
51 protected byte fScale; // The time scale
52 protected long fPrecision; // The value precision (tolerance)
8c8bf09f 53
cbd4ad82 54 // ------------------------------------------------------------------------
8c8bf09f 55 // Constants
cbd4ad82 56 // ------------------------------------------------------------------------
8c8bf09f
ASL
57
58 // The beginning and end of time
146a887c 59 public static final TmfTimestamp BigBang = new TmfTimestamp(Long.MIN_VALUE, Byte.MAX_VALUE, 0);
8c8bf09f 60 public static final TmfTimestamp BigCrunch = new TmfTimestamp(Long.MAX_VALUE, Byte.MAX_VALUE, 0);
e31e01e8 61 public static final TmfTimestamp Zero = new TmfTimestamp(0, (byte) 0, 0);
8c8bf09f 62
cbd4ad82 63 // ------------------------------------------------------------------------
8c8bf09f 64 // Constructors
cbd4ad82 65 // ------------------------------------------------------------------------
8c8bf09f
ASL
66
67 /**
28b94d61 68 * Default constructor
8c8bf09f
ASL
69 */
70 public TmfTimestamp() {
71 this(0, (byte) 0, 0);
72 }
73
1f506a43 74 /**
28b94d61 75 * Simple constructor with value only
1f506a43
FC
76 */
77 public TmfTimestamp(long value) {
78 this(value, (byte) 0, 0);
79 }
80
8c8bf09f 81 /**
28b94d61 82 * Simple constructor with value and scale
8c8bf09f 83 *
1f506a43
FC
84 * @param value
85 * @param scale
8c8bf09f
ASL
86 */
87 public TmfTimestamp(long value, byte scale) {
88 this(value, scale, 0);
89 }
90
91 /**
28b94d61 92 * Constructor with value, scale and precision
8c8bf09f 93 *
1f506a43
FC
94 * @param value
95 * @param scale
96 * @param precision
8c8bf09f
ASL
97 */
98 public TmfTimestamp(long value, byte scale, long precision) {
99 fValue = value;
100 fScale = scale;
101 fPrecision = Math.abs(precision);
102 }
103
104 /**
28b94d61 105 * Copy constructor
8c8bf09f 106 *
1f506a43 107 * @param other
8c8bf09f
ASL
108 */
109 public TmfTimestamp(TmfTimestamp other) {
cbd4ad82
FC
110 if (other == null)
111 throw new IllegalArgumentException();
28b94d61
FC
112 fValue = other.fValue;
113 fScale = other.fScale;
114 fPrecision = other.fPrecision;
8c8bf09f
ASL
115 }
116
cbd4ad82 117 // ------------------------------------------------------------------------
8c8bf09f 118 // Accessors
cbd4ad82 119 // ------------------------------------------------------------------------
8c8bf09f
ASL
120
121 /**
28b94d61 122 * @return the timestamp value
8c8bf09f
ASL
123 */
124 public long getValue() {
125 return fValue;
126 }
127
128 /**
28b94d61 129 * @return the timestamp scale
8c8bf09f
ASL
130 */
131 public byte getScale() {
132 return fScale;
133 }
134
135 /**
28b94d61 136 * @return the timestamp value precision
8c8bf09f
ASL
137 */
138 public long getPrecision() {
139 return fPrecision;
140 }
141
cbd4ad82 142 // ------------------------------------------------------------------------
8c8bf09f 143 // Operators
cbd4ad82 144 // ------------------------------------------------------------------------
4ab33d2b 145
8c8bf09f
ASL
146 /**
147 * Return a shifted and scaled timestamp.
148 *
149 * Limitation: The scaling is limited to MAX_SCALING orders of magnitude.
150 * The main reason is that the 64 bits value starts to lose any significance
151 * meaning beyond that scale difference and it's not even worth the trouble
152 * to switch to BigDecimal arithmetics.
153 *
cbd4ad82
FC
154 * @param offset the shift value (in the same scale as newScale)
155 * @param newScale the new timestamp scale
156 * @return the synchronized timestamp in the new scale
157 * @throws ArithmeticException
8c8bf09f 158 */
cbd4ad82 159 public TmfTimestamp synchronize(long offset, byte newScale) throws ArithmeticException {
8c8bf09f 160
cbd4ad82
FC
161 /*
162 * A java <code>long</code> has a maximum of 19 significant digits.
163 * (-9,223,372,036,854,775,808 .. +9,223,372,036,854,775,807)
164 *
165 * It is therefore useless to try to synchronize 2 timestamps whose
166 * difference in scale exceeds that value.
167 */
168 int MAX_SCALING = 19;
1f506a43 169
cbd4ad82 170 long newValue = fValue;
8c8bf09f
ASL
171 long newPrecision = fPrecision;
172
173 // Determine the scaling factor
174 if (fScale != newScale) {
175 int scaleDiff = Math.abs(fScale - newScale);
176 // Let's try to be realistic...
177 if (scaleDiff > MAX_SCALING) {
178 throw new ArithmeticException("Scaling exception");
179 }
1f506a43 180 // Not pretty...
8c8bf09f 181 long scalingFactor = 1;
1f506a43 182 for (int i = 0; i < scaleDiff; i++) {
8c8bf09f
ASL
183 scalingFactor *= 10;
184 }
185 if (newScale < fScale) {
186 newValue *= scalingFactor;
187 newPrecision *= scalingFactor;
188 } else {
189 newValue /= scalingFactor;
190 newPrecision /= scalingFactor;
191 }
192 }
193
194 return new TmfTimestamp(newValue + offset, newScale, newPrecision);
195 }
196
197 /**
198 * Compute the adjustment, in the reference scale, needed to synchronize
1f506a43 199 * this timestamp with a reference timestamp.
8c8bf09f 200 *
cbd4ad82
FC
201 * @param reference the reference timestamp to synchronize with
202 * @param scale the scale of the adjustment
28b94d61 203 * @return the adjustment term in the reference time scale
cbd4ad82 204 * @throws ArithmeticException
8c8bf09f 205 */
cbd4ad82
FC
206 public long getAdjustment(TmfTimestamp reference, byte scale) throws ArithmeticException {
207 TmfTimestamp ts1 = synchronize(0, scale);
208 TmfTimestamp ts2 = reference.synchronize(0, scale);
209 return ts2.fValue - ts1.fValue;
8c8bf09f
ASL
210 }
211
212 /**
213 * Compare with another timestamp
214 *
cbd4ad82
FC
215 * @param other the other timestamp
216 * @param withinPrecision indicates if precision is to be take into consideration
217 * @return -1: this timestamp is lower (i.e. anterior)
28b94d61 218 * 0: timestamps are equal (within precision if requested)
cbd4ad82 219 * 1: this timestamp is higher (i.e. posterior)
8c8bf09f
ASL
220 */
221 public int compareTo(final TmfTimestamp other, boolean withinPrecision) {
222
62d1696a 223 // If values have the same time scale, perform the comparison
8c8bf09f
ASL
224 if (fScale == other.fScale) {
225 if (withinPrecision) {
226 if ((fValue + fPrecision) < (other.fValue - other.fPrecision))
227 return -1;
228 if ((fValue - fPrecision) > (other.fValue + other.fPrecision))
229 return 1;
230 return 0;
231 }
cbd4ad82 232 return (fValue == other.fValue) ? 0 : (fValue < other.fValue) ? -1 : 1;
8c8bf09f
ASL
233 }
234
235 // If values have different time scales, adjust to the finest one and
236 // then compare. If the scaling difference is too large, revert to
237 // some heuristics. Hopefully, nobody will try to compare galactic and
62d1696a 238 // quantic clock events...
8c8bf09f
ASL
239 byte newScale = (fScale < other.fScale) ? fScale : other.fScale;
240 try {
241 TmfTimestamp ts1 = this.synchronize(0, newScale);
242 TmfTimestamp ts2 = other.synchronize(0, newScale);
243 return ts1.compareTo(ts2, withinPrecision);
244 } catch (ArithmeticException e) {
4ab33d2b 245 if ((fValue == 0) || (other.fValue == 0)) {
1f506a43
FC
246 return (fValue == other.fValue) ? 0
247 : (fValue < other.fValue) ? -1 : 1;
4ab33d2b
AO
248 }
249 if ((fValue > 0) && (other.fValue > 0)) {
250 return (fScale < other.fScale) ? -1 : 1;
251 }
252 if ((fValue < 0) && (other.fValue < 0)) {
253 return (fScale > other.fScale) ? -1 : 1;
254 }
255 return (fValue < 0) ? -1 : 1;
8c8bf09f
ASL
256 }
257 }
258
cbd4ad82
FC
259 // ------------------------------------------------------------------------
260 // Object
261 // ------------------------------------------------------------------------
28b94d61 262
8c8bf09f 263 @Override
cbd4ad82
FC
264 public int hashCode() {
265 int result = 17;
266 result = 37 * result + (int) (fValue ^ (fValue >>> 32));
267 result = 37 * result + fScale;
268 result = 37 * result + (int) (fPrecision ^ (fPrecision >>> 32));
269 return result;
270 }
271
272 @Override
8c8bf09f 273 public boolean equals(Object other) {
cbd4ad82
FC
274 if (!(other instanceof TmfTimestamp))
275 return false;
276 TmfTimestamp o = (TmfTimestamp) other;
277 return compareTo(o, false) == 0;
8c8bf09f
ASL
278 }
279
1f506a43
FC
280 @Override
281 public String toString() {
28b94d61 282 return "[TmfTimestamp(" + fValue + "," + fScale + "," + fPrecision + ")]";
1f506a43
FC
283 }
284
ff4ed569
FC
285 @Override
286 public TmfTimestamp clone() {
287 TmfTimestamp clone = null;
288 try {
289 clone = (TmfTimestamp) super.clone();
290 clone.fValue = fValue;
291 clone.fScale = fScale;
292 clone.fPrecision = fPrecision;
293 } catch (CloneNotSupportedException e) {
294 }
295 return clone;
296 }
297
8c8bf09f 298}
This page took 0.040862 seconds and 5 git commands to generate.