tmf : add a mipmap section in the developer guide
[deliverable/tracecompass.git] / org.eclipse.linuxtools.tmf.core / src / org / eclipse / linuxtools / tmf / core / timestamp / TmfTimestamp.java
CommitLineData
8c8bf09f 1/*******************************************************************************
e73a4ba5 2 * Copyright (c) 2009, 2013 Ericsson, École Polytechnique de Montréal
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
e73a4ba5 14 * Geneviève Bastien - Added copy constructor with new value
8c8bf09f
ASL
15 *******************************************************************************/
16
3bd46eef 17package org.eclipse.linuxtools.tmf.core.timestamp;
8c8bf09f 18
8c8bf09f 19/**
b9e37ffd 20 * A generic timestamp implementation. The timestamp is represented by the
d96e9054
FC
21 * tuple { value, scale, precision }. By default, timestamps are scaled in
22 * seconds.
f8177ba2 23 *
b9e37ffd 24 * @author Francois Chouinard
3bd46eef
AM
25 * @version 1.1
26 * @since 2.0
8c8bf09f 27 */
4593bd5b 28public class TmfTimestamp implements ITmfTimestamp {
8c8bf09f 29
5179fc01 30 // ------------------------------------------------------------------------
8c8bf09f 31 // Constants
5179fc01 32 // ------------------------------------------------------------------------
8c8bf09f 33
d7dbf09a
FC
34 /**
35 * The beginning of time
36 */
085d898f 37 public static final ITmfTimestamp BIG_BANG =
d7dbf09a
FC
38 new TmfTimestamp(Long.MIN_VALUE, Integer.MAX_VALUE, 0);
39
40 /**
41 * The end of time
42 */
085d898f 43 public static final ITmfTimestamp BIG_CRUNCH =
d7dbf09a 44 new TmfTimestamp(Long.MAX_VALUE, Integer.MAX_VALUE, 0);
085d898f 45
f8177ba2
FC
46 /**
47 * A more practical definition of "beginning of time"
f8177ba2
FC
48 */
49 public static final ITmfTimestamp PROJECT_IS_FUNDED = BIG_BANG;
50
51 /**
52 * A more practical definition of "end of time"
f8177ba2 53 */
d96e9054 54 public static final ITmfTimestamp PROJECT_IS_CANNED = BIG_CRUNCH;
f8177ba2 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 /**
d96e9054 67 * The timestamp raw value (mantissa)
d7dbf09a 68 */
4593bd5b 69 private final long fValue;
d7dbf09a
FC
70
71 /**
72 * The timestamp scale (magnitude)
73 */
4593bd5b 74 private final int fScale;
d7dbf09a
FC
75
76 /**
77 * The value precision (tolerance)
78 */
4593bd5b 79 private final 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 136 }
e73a4ba5
GB
137
138 /**
139 * Copies a timestamp but with a new time value
140 *
141 * @param timestamp
142 * The timestamp to copy
143 * @param newvalue
144 * The value the new timestamp will have
145 * @since 3.0
146 */
147 public TmfTimestamp(ITmfTimestamp timestamp, long newvalue) {
148 if (timestamp == null) {
149 throw new IllegalArgumentException();
150 }
151 fValue = newvalue;
152 fScale = timestamp.getScale();
153 fPrecision = timestamp.getPrecision();
154 }
8c8bf09f 155
5179fc01
FC
156 // ------------------------------------------------------------------------
157 // ITmfTimestamp
158 // ------------------------------------------------------------------------
8c8bf09f 159
d7dbf09a 160 @Override
8c8bf09f
ASL
161 public long getValue() {
162 return fValue;
163 }
164
d7dbf09a 165 @Override
5179fc01 166 public int getScale() {
8c8bf09f
ASL
167 return fScale;
168 }
169
d7dbf09a 170 @Override
5179fc01 171 public int getPrecision() {
8c8bf09f
ASL
172 return fPrecision;
173 }
174
5179fc01
FC
175 private static final long scalingFactors[] = new long[] {
176 1L,
177 10L,
178 100L,
179 1000L,
180 10000L,
181 100000L,
182 1000000L,
183 10000000L,
184 100000000L,
185 1000000000L,
186 10000000000L,
187 100000000000L,
188 1000000000000L,
189 10000000000000L,
190 100000000000000L,
191 1000000000000000L,
192 10000000000000000L,
193 100000000000000000L,
194 1000000000000000000L,
195 };
4ab33d2b 196
d7dbf09a 197 @Override
0316808c 198 public ITmfTimestamp normalize(final long offset, final int scale) {
8c8bf09f 199
5179fc01
FC
200 long value = fValue;
201 int precision = fPrecision;
8c8bf09f 202
5179fc01 203 // Handle the trivial case
b9e37ffd 204 if (fScale == scale && offset == 0) {
4593bd5b 205 return this;
b9e37ffd 206 }
f8177ba2
FC
207
208 // In case of big bang and big crunch just return this (no need to normalize)
e461c849
BH
209 if (this.equals(BIG_BANG) || this.equals(BIG_CRUNCH)) {
210 return this;
211 }
5179fc01
FC
212
213 // First, scale the timestamp
214 if (fScale != scale) {
085d898f 215 final int scaleDiff = Math.abs(fScale - scale);
b9e37ffd 216 if (scaleDiff >= scalingFactors.length) {
3b38ea61 217 throw new ArithmeticException("Scaling exception"); //$NON-NLS-1$
b9e37ffd 218 }
5179fc01 219
085d898f 220 final long scalingFactor = scalingFactors[scaleDiff];
5179fc01
FC
221 if (scale < fScale) {
222 value *= scalingFactor;
223 precision *= scalingFactor;
8c8bf09f 224 } else {
5179fc01
FC
225 value /= scalingFactor;
226 precision /= scalingFactor;
8c8bf09f
ASL
227 }
228 }
229
5179fc01 230 // Then, apply the offset
b9e37ffd 231 if (offset < 0) {
5179fc01 232 value = (value < Long.MIN_VALUE - offset) ? Long.MIN_VALUE : value + offset;
b9e37ffd 233 } else {
5179fc01 234 value = (value > Long.MAX_VALUE - offset) ? Long.MAX_VALUE : value + offset;
b9e37ffd 235 }
023761c4 236
5179fc01 237 return new TmfTimestamp(value, scale, precision);
8c8bf09f
ASL
238 }
239
d7dbf09a 240 @Override
085d898f 241 public int compareTo(final ITmfTimestamp ts, final boolean withinPrecision) {
023761c4 242
5179fc01 243 // Check the corner cases (we can't use equals() because it uses compareTo()...)
b9e37ffd
FC
244 if (ts == null) {
245 return 1;
246 }
247 if (this == ts || (fValue == ts.getValue() && fScale == ts.getScale())) {
5179fc01 248 return 0;
b9e37ffd
FC
249 }
250 if ((fValue == BIG_BANG.getValue() && fScale == BIG_BANG.getScale()) || (ts.getValue() == BIG_CRUNCH.getValue() && ts.getScale() == BIG_CRUNCH.getScale())) {
5179fc01 251 return -1;
b9e37ffd
FC
252 }
253 if ((fValue == BIG_CRUNCH.getValue() && fScale == BIG_CRUNCH.getScale()) || (ts.getValue() == BIG_BANG.getValue() && ts.getScale() == BIG_BANG.getScale())) {
5179fc01 254 return 1;
b9e37ffd 255 }
085d898f 256
5179fc01 257 try {
085d898f
FC
258 final ITmfTimestamp nts = ts.normalize(0, fScale);
259 final long delta = fValue - nts.getValue();
b9e37ffd 260 if ((delta == 0) || (withinPrecision && (Math.abs(delta) <= (fPrecision + nts.getPrecision())))) {
5179fc01 261 return 0;
b9e37ffd 262 }
5179fc01
FC
263 return (delta > 0) ? 1 : -1;
264 }
085d898f 265 catch (final ArithmeticException e) {
5179fc01
FC
266 // Scaling error. We can figure it out nonetheless.
267
268 // First, look at the sign of the mantissa
085d898f 269 final long value = ts.getValue();
b9e37ffd 270 if (fValue == 0 && value == 0) {
5179fc01 271 return 0;
b9e37ffd
FC
272 }
273 if (fValue < 0 && value >= 0) {
5179fc01 274 return -1;
b9e37ffd
FC
275 }
276 if (fValue >= 0 && value < 0) {
5179fc01 277 return 1;
b9e37ffd 278 }
5179fc01
FC
279
280 // Otherwise, just compare the scales
085d898f
FC
281 final int scale = ts.getScale();
282 return (fScale > scale) ? (fValue >= 0) ? 1 : -1 : (fValue >= 0) ? -1 : 1;
5179fc01 283 }
8c8bf09f
ASL
284 }
285
5179fc01 286 @Override
085d898f
FC
287 public ITmfTimestamp getDelta(final ITmfTimestamp ts) {
288 final ITmfTimestamp nts = ts.normalize(0, fScale);
289 final long value = fValue - nts.getValue();
a9ee1687 290 return new TmfTimestampDelta(value, fScale, fPrecision + nts.getPrecision());
73005152
BH
291 }
292
1de55ea2
AM
293 @Override
294 public boolean intersects(TmfTimeRange range) {
295 if (this.compareTo(range.getStartTime()) >= 0 &&
296 this.compareTo(range.getEndTime()) <= 0) {
297 return true;
298 }
299 return false;
300 }
301
5179fc01
FC
302 // ------------------------------------------------------------------------
303 // Comparable
304 // ------------------------------------------------------------------------
023761c4 305
5179fc01 306 @Override
085d898f 307 public int compareTo(final ITmfTimestamp ts) {
4df4581d 308 return compareTo(ts, false);
5179fc01 309 }
f3a4c7f4 310
5179fc01 311 // ------------------------------------------------------------------------
cbd4ad82 312 // Object
5179fc01 313 // ------------------------------------------------------------------------
28b94d61 314
8c8bf09f 315 @Override
cbd4ad82 316 public int hashCode() {
5179fc01
FC
317 final int prime = 31;
318 int result = 1;
319 result = prime * result + (int) (fValue ^ (fValue >>> 32));
320 result = prime * result + fScale;
321 result = prime * result + fPrecision;
cbd4ad82
FC
322 return result;
323 }
324
5179fc01 325 @Override
085d898f 326 public boolean equals(final Object other) {
b9e37ffd 327 if (this == other) {
5179fc01 328 return true;
b9e37ffd
FC
329 }
330 if (other == null) {
5179fc01 331 return false;
b9e37ffd
FC
332 }
333 if (!(other instanceof TmfTimestamp)) {
5179fc01 334 return false;
b9e37ffd 335 }
085d898f 336 final TmfTimestamp ts = (TmfTimestamp) other;
5179fc01 337 return compareTo(ts, false) == 0;
8c8bf09f
ASL
338 }
339
1f506a43
FC
340 @Override
341 public String toString() {
f8177ba2
FC
342 return toString(TmfTimestampFormat.getDefaulTimeFormat());
343 }
344
f8177ba2
FC
345 /**
346 * @since 2.0
347 */
348 @Override
349 public String toString(final TmfTimestampFormat format) {
350 try {
351 ITmfTimestamp ts = normalize(0, ITmfTimestamp.NANOSECOND_SCALE);
352 return format.format(ts.getValue());
353 }
354 catch (ArithmeticException e) {
355 return format.format(0);
356 }
ff4ed569
FC
357 }
358
023761c4 359}
This page took 0.071023 seconds and 5 git commands to generate.