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