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