Merge branch 'master' into lttng-kepler
[deliverable/tracecompass.git] / org.eclipse.linuxtools.tmf.core / src / org / eclipse / linuxtools / tmf / core / event / TmfTimestamp.java
1 /*******************************************************************************
2 * Copyright (c) 2009, 2010, 2012 Ericsson
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:
10 * Francois Chouinard - Initial API and implementation
11 * Thomas Gatterweh - Updated scaling / synchronization
12 * Francois Chouinard - Refactoring to align with TMF Event Model 1.0
13 *******************************************************************************/
14
15 package org.eclipse.linuxtools.tmf.core.event;
16
17
18 /**
19 * A generic timestamp implementation. The timestamp is represented by the
20 * tuple { value, scale, precision }.
21 *
22 * @version 1.0
23 * @author Francois Chouinard
24 */
25 public class TmfTimestamp implements ITmfTimestamp, Cloneable {
26
27 // ------------------------------------------------------------------------
28 // Constants
29 // ------------------------------------------------------------------------
30
31 /**
32 * The beginning of time
33 */
34 public static final ITmfTimestamp BIG_BANG =
35 new TmfTimestamp(Long.MIN_VALUE, Integer.MAX_VALUE, 0);
36
37 /**
38 * The end of time
39 */
40 public static final ITmfTimestamp BIG_CRUNCH =
41 new TmfTimestamp(Long.MAX_VALUE, Integer.MAX_VALUE, 0);
42
43 /**
44 * Zero
45 */
46 public static final ITmfTimestamp ZERO =
47 new TmfTimestamp(0, 0, 0);
48
49 // ------------------------------------------------------------------------
50 // Attributes
51 // ------------------------------------------------------------------------
52
53 /**
54 * The timestamp raw value (mantissa)
55 */
56 private long fValue;
57
58 /**
59 * The timestamp scale (magnitude)
60 */
61 private int fScale;
62
63 /**
64 * The value precision (tolerance)
65 */
66 private int fPrecision;
67
68 // ------------------------------------------------------------------------
69 // Constructors
70 // ------------------------------------------------------------------------
71
72 /**
73 * Default constructor
74 */
75 public TmfTimestamp() {
76 this(0, 0, 0);
77 }
78
79 /**
80 * Simple constructor (scale = precision = 0)
81 *
82 * @param value the timestamp value
83 */
84 public TmfTimestamp(final long value) {
85 this(value, 0, 0);
86 }
87
88 /**
89 * Simple constructor (precision = 0)
90 *
91 * @param value the timestamp value
92 * @param scale the timestamp scale
93 */
94 public TmfTimestamp(final long value, final int scale) {
95 this(value, scale, 0);
96 }
97
98 /**
99 * Full constructor
100 *
101 * @param value the timestamp value
102 * @param scale the timestamp scale
103 * @param precision the timestamp precision
104 */
105 public TmfTimestamp(final long value, final int scale, final int precision) {
106 fValue = value;
107 fScale = scale;
108 fPrecision = Math.abs(precision);
109 }
110
111 /**
112 * Copy constructor
113 *
114 * @param timestamp the timestamp to copy
115 */
116 public TmfTimestamp(final ITmfTimestamp timestamp) {
117 if (timestamp == null) {
118 throw new IllegalArgumentException();
119 }
120 fValue = timestamp.getValue();
121 fScale = timestamp.getScale();
122 fPrecision = timestamp.getPrecision();
123 }
124
125 // ------------------------------------------------------------------------
126 // Setters
127 // ------------------------------------------------------------------------
128
129 protected void setValue(long value, int scale, int precision) {
130 fValue = value;
131 fScale = scale;
132 fPrecision = precision;
133 }
134
135 // ------------------------------------------------------------------------
136 // ITmfTimestamp
137 // ------------------------------------------------------------------------
138
139 /* (non-Javadoc)
140 * @see org.eclipse.linuxtools.tmf.core.event.ITmfTimestamp#getValue()
141 */
142 @Override
143 public long getValue() {
144 return fValue;
145 }
146
147 /* (non-Javadoc)
148 * @see org.eclipse.linuxtools.tmf.core.event.ITmfTimestamp#getScale()
149 */
150 @Override
151 public int getScale() {
152 return fScale;
153 }
154
155 /* (non-Javadoc)
156 * @see org.eclipse.linuxtools.tmf.core.event.ITmfTimestamp#getPrecision()
157 */
158 @Override
159 public int getPrecision() {
160 return fPrecision;
161 }
162
163 private static final long scalingFactors[] = new long[] {
164 1L,
165 10L,
166 100L,
167 1000L,
168 10000L,
169 100000L,
170 1000000L,
171 10000000L,
172 100000000L,
173 1000000000L,
174 10000000000L,
175 100000000000L,
176 1000000000000L,
177 10000000000000L,
178 100000000000000L,
179 1000000000000000L,
180 10000000000000000L,
181 100000000000000000L,
182 1000000000000000000L,
183 };
184
185 /* (non-Javadoc)
186 * @see org.eclipse.linuxtools.tmf.core.event.ITmfTimestamp#normalize(long, int)
187 */
188 @Override
189 public ITmfTimestamp normalize(final long offset, final int scale) {
190
191 long value = fValue;
192 int precision = fPrecision;
193
194 // Handle the trivial case
195 if (fScale == scale && offset == 0) {
196 return new TmfTimestamp(this);
197 }
198
199 // In case of big bang and big crunch just return this (no need to normalize)
200 if (this.equals(BIG_BANG) || this.equals(BIG_CRUNCH)) {
201 return this;
202 }
203
204 // First, scale the timestamp
205 if (fScale != scale) {
206 final int scaleDiff = Math.abs(fScale - scale);
207 if (scaleDiff >= scalingFactors.length) {
208 throw new ArithmeticException("Scaling exception"); //$NON-NLS-1$
209 }
210
211 final long scalingFactor = scalingFactors[scaleDiff];
212 if (scale < fScale) {
213 value *= scalingFactor;
214 precision *= scalingFactor;
215 } else {
216 value /= scalingFactor;
217 precision /= scalingFactor;
218 }
219 }
220
221 // Then, apply the offset
222 if (offset < 0) {
223 value = (value < Long.MIN_VALUE - offset) ? Long.MIN_VALUE : value + offset;
224 } else {
225 value = (value > Long.MAX_VALUE - offset) ? Long.MAX_VALUE : value + offset;
226 }
227
228 return new TmfTimestamp(value, scale, precision);
229 }
230
231 /* (non-Javadoc)
232 * @see org.eclipse.linuxtools.tmf.core.event.ITmfTimestamp#compareTo(org.eclipse.linuxtools.tmf.core.event.ITmfTimestamp, boolean)
233 */
234 @Override
235 public int compareTo(final ITmfTimestamp ts, final boolean withinPrecision) {
236
237 // Check the corner cases (we can't use equals() because it uses compareTo()...)
238 if (ts == null) {
239 return 1;
240 }
241 if (this == ts || (fValue == ts.getValue() && fScale == ts.getScale())) {
242 return 0;
243 }
244 if ((fValue == BIG_BANG.getValue() && fScale == BIG_BANG.getScale()) || (ts.getValue() == BIG_CRUNCH.getValue() && ts.getScale() == BIG_CRUNCH.getScale())) {
245 return -1;
246 }
247 if ((fValue == BIG_CRUNCH.getValue() && fScale == BIG_CRUNCH.getScale()) || (ts.getValue() == BIG_BANG.getValue() && ts.getScale() == BIG_BANG.getScale())) {
248 return 1;
249 }
250
251 try {
252 final ITmfTimestamp nts = ts.normalize(0, fScale);
253 final long delta = fValue - nts.getValue();
254 if ((delta == 0) || (withinPrecision && (Math.abs(delta) <= (fPrecision + nts.getPrecision())))) {
255 return 0;
256 }
257 return (delta > 0) ? 1 : -1;
258 }
259 catch (final ArithmeticException e) {
260 // Scaling error. We can figure it out nonetheless.
261
262 // First, look at the sign of the mantissa
263 final long value = ts.getValue();
264 if (fValue == 0 && value == 0) {
265 return 0;
266 }
267 if (fValue < 0 && value >= 0) {
268 return -1;
269 }
270 if (fValue >= 0 && value < 0) {
271 return 1;
272 }
273
274 // Otherwise, just compare the scales
275 final int scale = ts.getScale();
276 return (fScale > scale) ? (fValue >= 0) ? 1 : -1 : (fValue >= 0) ? -1 : 1;
277 }
278 }
279
280 /* (non-Javadoc)
281 * @see org.eclipse.linuxtools.tmf.core.event.ITmfTimestamp#getDelta(org.eclipse.linuxtools.tmf.core.event.ITmfTimestamp)
282 */
283 @Override
284 public ITmfTimestamp getDelta(final ITmfTimestamp ts) {
285 final ITmfTimestamp nts = ts.normalize(0, fScale);
286 final long value = fValue - nts.getValue();
287 return new TmfTimestamp(value, fScale, fPrecision + nts.getPrecision());
288 }
289
290 // ------------------------------------------------------------------------
291 // Cloneable
292 // ------------------------------------------------------------------------
293
294 /* (non-Javadoc)
295 * @see java.lang.Object#clone()
296 */
297 @Override
298 public TmfTimestamp clone() {
299 TmfTimestamp clone = null;
300 try {
301 clone = (TmfTimestamp) super.clone();
302 clone.fValue = fValue;
303 clone.fScale = fScale;
304 clone.fPrecision = fPrecision;
305 } catch (final CloneNotSupportedException e) {
306 }
307 return clone;
308 }
309
310 // ------------------------------------------------------------------------
311 // Comparable
312 // ------------------------------------------------------------------------
313
314 /* (non-Javadoc)
315 * @see org.eclipse.linuxtools.tmf.core.event.ITmfTimestamp#compareTo(org.eclipse.linuxtools.tmf.core.event.ITmfTimestamp)
316 */
317 @Override
318 public int compareTo(final ITmfTimestamp ts) {
319 return compareTo(ts, false);
320 }
321
322 // ------------------------------------------------------------------------
323 // Object
324 // ------------------------------------------------------------------------
325
326 /* (non-Javadoc)
327 * @see java.lang.Object#hashCode()
328 */
329 @Override
330 public int hashCode() {
331 final int prime = 31;
332 int result = 1;
333 result = prime * result + (int) (fValue ^ (fValue >>> 32));
334 result = prime * result + fScale;
335 result = prime * result + fPrecision;
336 return result;
337 }
338
339 /* (non-Javadoc)
340 * @see java.lang.Object#equals(java.lang.Object)
341 */
342 @Override
343 public boolean equals(final Object other) {
344 if (this == other) {
345 return true;
346 }
347 if (other == null) {
348 return false;
349 }
350 if (!(other instanceof TmfTimestamp)) {
351 return false;
352 }
353 final TmfTimestamp ts = (TmfTimestamp) other;
354 return compareTo(ts, false) == 0;
355 }
356
357 /* (non-Javadoc)
358 * @see java.lang.Object#toString()
359 */
360 @Override
361 @SuppressWarnings("nls")
362 public String toString() {
363 return "TmfTimestamp [fValue=" + fValue + ", fScale=" + fScale + ", fPrecision=" + fPrecision + "]";
364 }
365
366 }
This page took 0.038644 seconds and 5 git commands to generate.