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