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