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