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