tmf.all: use ITmfTimestamp#toNanos when possible
[deliverable/tracecompass.git] / tmf / org.eclipse.tracecompass.tmf.core / src / org / eclipse / tracecompass / tmf / core / timestamp / TmfTimestamp.java
CommitLineData
8c8bf09f 1/*******************************************************************************
065cc19b 2 * Copyright (c) 2009, 2014 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:
065cc19b 10 * Francois Chouinard - Initial API and implementation, refactoring and updates
d5efe032 11 * Thomas Gatterweh - Updated scaling / synchronization
065cc19b
AM
12 * Geneviève Bastien - Added copy constructor with new value
13 * Alexandre Montplaisir - Removed concept of precision
8c8bf09f
ASL
14 *******************************************************************************/
15
2bdf0193 16package org.eclipse.tracecompass.tmf.core.timestamp;
8c8bf09f 17
032ecd45
MAL
18import java.nio.ByteBuffer;
19
cbf0057c
GB
20import org.eclipse.jdt.annotation.NonNull;
21
8c8bf09f 22/**
b9e37ffd 23 * A generic timestamp implementation. The timestamp is represented by the
d96e9054
FC
24 * tuple { value, scale, precision }. By default, timestamps are scaled in
25 * seconds.
f8177ba2 26 *
b9e37ffd 27 * @author Francois Chouinard
8c8bf09f 28 */
4593bd5b 29public class TmfTimestamp implements ITmfTimestamp {
8c8bf09f 30
5179fc01 31 // ------------------------------------------------------------------------
8c8bf09f 32 // Constants
5179fc01 33 // ------------------------------------------------------------------------
8c8bf09f 34
d7dbf09a
FC
35 /**
36 * The beginning of time
37 */
cbf0057c 38 public static final @NonNull ITmfTimestamp BIG_BANG =
065cc19b 39 new TmfTimestamp(Long.MIN_VALUE, Integer.MAX_VALUE);
d7dbf09a
FC
40
41 /**
42 * The end of time
43 */
cbf0057c 44 public static final @NonNull ITmfTimestamp BIG_CRUNCH =
065cc19b 45 new TmfTimestamp(Long.MAX_VALUE, Integer.MAX_VALUE);
085d898f 46
d7dbf09a
FC
47 /**
48 * Zero
49 */
cbf0057c 50 public static final @NonNull ITmfTimestamp ZERO =
065cc19b 51 new TmfTimestamp(0, 0);
5179fc01
FC
52
53 // ------------------------------------------------------------------------
54 // Attributes
55 // ------------------------------------------------------------------------
8c8bf09f 56
d7dbf09a 57 /**
d96e9054 58 * The timestamp raw value (mantissa)
d7dbf09a 59 */
4593bd5b 60 private final long fValue;
d7dbf09a
FC
61
62 /**
63 * The timestamp scale (magnitude)
64 */
4593bd5b 65 private final int fScale;
d7dbf09a 66
5179fc01 67 // ------------------------------------------------------------------------
8c8bf09f 68 // Constructors
5179fc01 69 // ------------------------------------------------------------------------
8c8bf09f
ASL
70
71 /**
28b94d61 72 * Default constructor
8c8bf09f
ASL
73 */
74 public TmfTimestamp() {
065cc19b 75 this(0, ITmfTimestamp.SECOND_SCALE);
8c8bf09f
ASL
76 }
77
1f506a43 78 /**
065cc19b 79 * Simple constructor (scale = 0)
5179fc01 80 *
065cc19b
AM
81 * @param value
82 * the timestamp value
1f506a43 83 */
085d898f 84 public TmfTimestamp(final long value) {
065cc19b 85 this(value, ITmfTimestamp.SECOND_SCALE);
8c8bf09f
ASL
86 }
87
88 /**
5179fc01 89 * Full constructor
f8177ba2 90 *
065cc19b
AM
91 * @param value
92 * the timestamp value
93 * @param scale
94 * the timestamp scale
8c8bf09f 95 */
065cc19b 96 public TmfTimestamp(final long value, final int scale) {
8c8bf09f
ASL
97 fValue = value;
98 fScale = scale;
8c8bf09f
ASL
99 }
100
101 /**
28b94d61 102 * Copy constructor
f8177ba2 103 *
065cc19b
AM
104 * @param timestamp
105 * the timestamp to copy
8c8bf09f 106 */
085d898f 107 public TmfTimestamp(final ITmfTimestamp timestamp) {
b9e37ffd 108 if (timestamp == null) {
5179fc01 109 throw new IllegalArgumentException();
b9e37ffd 110 }
4df4581d 111 fValue = timestamp.getValue();
112 fScale = timestamp.getScale();
8c8bf09f 113 }
e73a4ba5
GB
114
115 /**
116 * Copies a timestamp but with a new time value
117 *
118 * @param timestamp
119 * The timestamp to copy
120 * @param newvalue
121 * The value the new timestamp will have
e73a4ba5
GB
122 */
123 public TmfTimestamp(ITmfTimestamp timestamp, long newvalue) {
124 if (timestamp == null) {
125 throw new IllegalArgumentException();
126 }
127 fValue = newvalue;
128 fScale = timestamp.getScale();
e73a4ba5 129 }
8c8bf09f 130
5179fc01
FC
131 // ------------------------------------------------------------------------
132 // ITmfTimestamp
133 // ------------------------------------------------------------------------
8c8bf09f 134
032ecd45
MAL
135 /**
136 * Construct the timestamp from the ByteBuffer.
137 *
138 * @param bufferIn
139 * the buffer to read from
032ecd45
MAL
140 */
141 public TmfTimestamp(ByteBuffer bufferIn) {
065cc19b 142 this(bufferIn.getLong(), bufferIn.getInt());
032ecd45
MAL
143 }
144
d7dbf09a 145 @Override
8c8bf09f
ASL
146 public long getValue() {
147 return fValue;
148 }
149
d7dbf09a 150 @Override
5179fc01 151 public int getScale() {
8c8bf09f
ASL
152 return fScale;
153 }
154
5179fc01
FC
155 private static final long scalingFactors[] = new long[] {
156 1L,
157 10L,
158 100L,
159 1000L,
160 10000L,
161 100000L,
162 1000000L,
163 10000000L,
164 100000000L,
165 1000000000L,
166 10000000000L,
167 100000000000L,
168 1000000000000L,
169 10000000000000L,
170 100000000000000L,
171 1000000000000000L,
172 10000000000000000L,
173 100000000000000000L,
174 1000000000000000000L,
175 };
4ab33d2b 176
d7dbf09a 177 @Override
0316808c 178 public ITmfTimestamp normalize(final long offset, final int scale) {
8c8bf09f 179
5179fc01 180 long value = fValue;
8c8bf09f 181
5179fc01 182 // Handle the trivial case
b9e37ffd 183 if (fScale == scale && offset == 0) {
4593bd5b 184 return this;
b9e37ffd 185 }
f8177ba2
FC
186
187 // In case of big bang and big crunch just return this (no need to normalize)
e461c849
BH
188 if (this.equals(BIG_BANG) || this.equals(BIG_CRUNCH)) {
189 return this;
190 }
5179fc01
FC
191
192 // First, scale the timestamp
193 if (fScale != scale) {
085d898f 194 final int scaleDiff = Math.abs(fScale - scale);
b9e37ffd 195 if (scaleDiff >= scalingFactors.length) {
3b38ea61 196 throw new ArithmeticException("Scaling exception"); //$NON-NLS-1$
b9e37ffd 197 }
5179fc01 198
085d898f 199 final long scalingFactor = scalingFactors[scaleDiff];
5179fc01
FC
200 if (scale < fScale) {
201 value *= scalingFactor;
8c8bf09f 202 } else {
5179fc01 203 value /= scalingFactor;
8c8bf09f
ASL
204 }
205 }
206
5179fc01 207 // Then, apply the offset
b9e37ffd 208 if (offset < 0) {
5179fc01 209 value = (value < Long.MIN_VALUE - offset) ? Long.MIN_VALUE : value + offset;
b9e37ffd 210 } else {
5179fc01 211 value = (value > Long.MAX_VALUE - offset) ? Long.MAX_VALUE : value + offset;
b9e37ffd 212 }
023761c4 213
065cc19b 214 return new TmfTimestamp(value, scale);
8c8bf09f
ASL
215 }
216
d7dbf09a 217 @Override
065cc19b
AM
218 public ITmfTimestamp getDelta(final ITmfTimestamp ts) {
219 final ITmfTimestamp nts = ts.normalize(0, fScale);
220 final long value = fValue - nts.getValue();
221 return new TmfTimestampDelta(value, fScale);
222 }
223
224 @Override
225 public boolean intersects(TmfTimeRange range) {
226 if (this.compareTo(range.getStartTime()) >= 0 &&
227 this.compareTo(range.getEndTime()) <= 0) {
228 return true;
229 }
230 return false;
231 }
232
233 // ------------------------------------------------------------------------
234 // Comparable
235 // ------------------------------------------------------------------------
023761c4 236
065cc19b
AM
237 @Override
238 public int compareTo(final ITmfTimestamp ts) {
5179fc01 239 // Check the corner cases (we can't use equals() because it uses compareTo()...)
b9e37ffd
FC
240 if (ts == null) {
241 return 1;
242 }
243 if (this == ts || (fValue == ts.getValue() && fScale == ts.getScale())) {
5179fc01 244 return 0;
b9e37ffd
FC
245 }
246 if ((fValue == BIG_BANG.getValue() && fScale == BIG_BANG.getScale()) || (ts.getValue() == BIG_CRUNCH.getValue() && ts.getScale() == BIG_CRUNCH.getScale())) {
5179fc01 247 return -1;
b9e37ffd
FC
248 }
249 if ((fValue == BIG_CRUNCH.getValue() && fScale == BIG_CRUNCH.getScale()) || (ts.getValue() == BIG_BANG.getValue() && ts.getScale() == BIG_BANG.getScale())) {
5179fc01 250 return 1;
b9e37ffd 251 }
085d898f 252
5179fc01 253 try {
085d898f
FC
254 final ITmfTimestamp nts = ts.normalize(0, fScale);
255 final long delta = fValue - nts.getValue();
065cc19b 256 return Long.compare(delta, 0);
5179fc01 257 }
085d898f 258 catch (final ArithmeticException e) {
5179fc01
FC
259 // Scaling error. We can figure it out nonetheless.
260
261 // First, look at the sign of the mantissa
085d898f 262 final long value = ts.getValue();
b9e37ffd 263 if (fValue == 0 && value == 0) {
5179fc01 264 return 0;
b9e37ffd
FC
265 }
266 if (fValue < 0 && value >= 0) {
5179fc01 267 return -1;
b9e37ffd
FC
268 }
269 if (fValue >= 0 && value < 0) {
5179fc01 270 return 1;
b9e37ffd 271 }
5179fc01
FC
272
273 // Otherwise, just compare the scales
085d898f
FC
274 final int scale = ts.getScale();
275 return (fScale > scale) ? (fValue >= 0) ? 1 : -1 : (fValue >= 0) ? -1 : 1;
5179fc01 276 }
8c8bf09f
ASL
277 }
278
5179fc01 279 // ------------------------------------------------------------------------
cbd4ad82 280 // Object
5179fc01 281 // ------------------------------------------------------------------------
28b94d61 282
8c8bf09f 283 @Override
cbd4ad82 284 public int hashCode() {
5179fc01
FC
285 final int prime = 31;
286 int result = 1;
287 result = prime * result + (int) (fValue ^ (fValue >>> 32));
288 result = prime * result + fScale;
cbd4ad82
FC
289 return result;
290 }
291
5179fc01 292 @Override
085d898f 293 public boolean equals(final Object other) {
b9e37ffd 294 if (this == other) {
5179fc01 295 return true;
b9e37ffd
FC
296 }
297 if (other == null) {
5179fc01 298 return false;
b9e37ffd 299 }
065cc19b 300 if (!(other instanceof ITmfTimestamp)) {
5179fc01 301 return false;
b9e37ffd 302 }
065cc19b
AM
303 /* We allow comparing with other types of *I*TmfTimestamp though */
304 final ITmfTimestamp ts = (ITmfTimestamp) other;
305 return (compareTo(ts) == 0);
8c8bf09f
ASL
306 }
307
1f506a43
FC
308 @Override
309 public String toString() {
f8177ba2
FC
310 return toString(TmfTimestampFormat.getDefaulTimeFormat());
311 }
312
f8177ba2
FC
313 @Override
314 public String toString(final TmfTimestampFormat format) {
315 try {
16801c72 316 return format.format(toNanos());
f8177ba2
FC
317 }
318 catch (ArithmeticException e) {
319 return format.format(0);
320 }
ff4ed569
FC
321 }
322
032ecd45
MAL
323 /**
324 * Write the time stamp to the ByteBuffer so that it can be saved to disk.
325 * @param bufferOut the buffer to write to
032ecd45
MAL
326 */
327 public void serialize(ByteBuffer bufferOut) {
328 bufferOut.putLong(fValue);
329 bufferOut.putInt(fScale);
032ecd45 330 }
023761c4 331}
This page took 0.12246 seconds and 5 git commands to generate.