TMF: Add some NonNull annotations to ITmfTimestampTransform
[deliverable/tracecompass.git] / 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
8c8bf09f 20/**
b9e37ffd 21 * A generic timestamp implementation. The timestamp is represented by the
d96e9054
FC
22 * tuple { value, scale, precision }. By default, timestamps are scaled in
23 * seconds.
f8177ba2 24 *
b9e37ffd 25 * @author Francois Chouinard
3bd46eef 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 =
065cc19b 38 new TmfTimestamp(Long.MIN_VALUE, Integer.MAX_VALUE);
d7dbf09a
FC
39
40 /**
41 * The end of time
42 */
085d898f 43 public static final ITmfTimestamp BIG_CRUNCH =
065cc19b 44 new TmfTimestamp(Long.MAX_VALUE, Integer.MAX_VALUE);
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 =
065cc19b 60 new TmfTimestamp(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 75
5179fc01 76 // ------------------------------------------------------------------------
8c8bf09f 77 // Constructors
5179fc01 78 // ------------------------------------------------------------------------
8c8bf09f
ASL
79
80 /**
28b94d61 81 * Default constructor
8c8bf09f
ASL
82 */
83 public TmfTimestamp() {
065cc19b 84 this(0, ITmfTimestamp.SECOND_SCALE);
8c8bf09f
ASL
85 }
86
1f506a43 87 /**
065cc19b 88 * Simple constructor (scale = 0)
5179fc01 89 *
065cc19b
AM
90 * @param value
91 * the timestamp value
1f506a43 92 */
085d898f 93 public TmfTimestamp(final long value) {
065cc19b 94 this(value, ITmfTimestamp.SECOND_SCALE);
8c8bf09f
ASL
95 }
96
97 /**
5179fc01 98 * Full constructor
f8177ba2 99 *
065cc19b
AM
100 * @param value
101 * the timestamp value
102 * @param scale
103 * the timestamp scale
8c8bf09f 104 */
065cc19b 105 public TmfTimestamp(final long value, final int scale) {
8c8bf09f
ASL
106 fValue = value;
107 fScale = scale;
8c8bf09f
ASL
108 }
109
110 /**
28b94d61 111 * Copy constructor
f8177ba2 112 *
065cc19b
AM
113 * @param timestamp
114 * 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();
8c8bf09f 122 }
e73a4ba5
GB
123
124 /**
125 * Copies a timestamp but with a new time value
126 *
127 * @param timestamp
128 * The timestamp to copy
129 * @param newvalue
130 * The value the new timestamp will have
131 * @since 3.0
132 */
133 public TmfTimestamp(ITmfTimestamp timestamp, long newvalue) {
134 if (timestamp == null) {
135 throw new IllegalArgumentException();
136 }
137 fValue = newvalue;
138 fScale = timestamp.getScale();
e73a4ba5 139 }
8c8bf09f 140
5179fc01
FC
141 // ------------------------------------------------------------------------
142 // ITmfTimestamp
143 // ------------------------------------------------------------------------
8c8bf09f 144
032ecd45
MAL
145 /**
146 * Construct the timestamp from the ByteBuffer.
147 *
148 * @param bufferIn
149 * the buffer to read from
150 *
151 * @since 3.0
152 */
153 public TmfTimestamp(ByteBuffer bufferIn) {
065cc19b 154 this(bufferIn.getLong(), bufferIn.getInt());
032ecd45
MAL
155 }
156
d7dbf09a 157 @Override
8c8bf09f
ASL
158 public long getValue() {
159 return fValue;
160 }
161
d7dbf09a 162 @Override
5179fc01 163 public int getScale() {
8c8bf09f
ASL
164 return fScale;
165 }
166
5179fc01
FC
167 private static final long scalingFactors[] = new long[] {
168 1L,
169 10L,
170 100L,
171 1000L,
172 10000L,
173 100000L,
174 1000000L,
175 10000000L,
176 100000000L,
177 1000000000L,
178 10000000000L,
179 100000000000L,
180 1000000000000L,
181 10000000000000L,
182 100000000000000L,
183 1000000000000000L,
184 10000000000000000L,
185 100000000000000000L,
186 1000000000000000000L,
187 };
4ab33d2b 188
d7dbf09a 189 @Override
0316808c 190 public ITmfTimestamp normalize(final long offset, final int scale) {
8c8bf09f 191
5179fc01 192 long value = fValue;
8c8bf09f 193
5179fc01 194 // Handle the trivial case
b9e37ffd 195 if (fScale == scale && offset == 0) {
4593bd5b 196 return this;
b9e37ffd 197 }
f8177ba2
FC
198
199 // In case of big bang and big crunch just return this (no need to normalize)
e461c849
BH
200 if (this.equals(BIG_BANG) || this.equals(BIG_CRUNCH)) {
201 return this;
202 }
5179fc01
FC
203
204 // First, scale the timestamp
205 if (fScale != scale) {
085d898f 206 final int scaleDiff = Math.abs(fScale - scale);
b9e37ffd 207 if (scaleDiff >= scalingFactors.length) {
3b38ea61 208 throw new ArithmeticException("Scaling exception"); //$NON-NLS-1$
b9e37ffd 209 }
5179fc01 210
085d898f 211 final long scalingFactor = scalingFactors[scaleDiff];
5179fc01
FC
212 if (scale < fScale) {
213 value *= scalingFactor;
8c8bf09f 214 } else {
5179fc01 215 value /= scalingFactor;
8c8bf09f
ASL
216 }
217 }
218
5179fc01 219 // Then, apply the offset
b9e37ffd 220 if (offset < 0) {
5179fc01 221 value = (value < Long.MIN_VALUE - offset) ? Long.MIN_VALUE : value + offset;
b9e37ffd 222 } else {
5179fc01 223 value = (value > Long.MAX_VALUE - offset) ? Long.MAX_VALUE : value + offset;
b9e37ffd 224 }
023761c4 225
065cc19b 226 return new TmfTimestamp(value, scale);
8c8bf09f
ASL
227 }
228
d7dbf09a 229 @Override
065cc19b
AM
230 public ITmfTimestamp getDelta(final ITmfTimestamp ts) {
231 final ITmfTimestamp nts = ts.normalize(0, fScale);
232 final long value = fValue - nts.getValue();
233 return new TmfTimestampDelta(value, fScale);
234 }
235
236 @Override
237 public boolean intersects(TmfTimeRange range) {
238 if (this.compareTo(range.getStartTime()) >= 0 &&
239 this.compareTo(range.getEndTime()) <= 0) {
240 return true;
241 }
242 return false;
243 }
244
245 // ------------------------------------------------------------------------
246 // Comparable
247 // ------------------------------------------------------------------------
023761c4 248
065cc19b
AM
249 @Override
250 public int compareTo(final ITmfTimestamp ts) {
5179fc01 251 // Check the corner cases (we can't use equals() because it uses compareTo()...)
b9e37ffd
FC
252 if (ts == null) {
253 return 1;
254 }
255 if (this == ts || (fValue == ts.getValue() && fScale == ts.getScale())) {
5179fc01 256 return 0;
b9e37ffd
FC
257 }
258 if ((fValue == BIG_BANG.getValue() && fScale == BIG_BANG.getScale()) || (ts.getValue() == BIG_CRUNCH.getValue() && ts.getScale() == BIG_CRUNCH.getScale())) {
5179fc01 259 return -1;
b9e37ffd
FC
260 }
261 if ((fValue == BIG_CRUNCH.getValue() && fScale == BIG_CRUNCH.getScale()) || (ts.getValue() == BIG_BANG.getValue() && ts.getScale() == BIG_BANG.getScale())) {
5179fc01 262 return 1;
b9e37ffd 263 }
085d898f 264
5179fc01 265 try {
085d898f
FC
266 final ITmfTimestamp nts = ts.normalize(0, fScale);
267 final long delta = fValue - nts.getValue();
065cc19b 268 return Long.compare(delta, 0);
5179fc01 269 }
085d898f 270 catch (final ArithmeticException e) {
5179fc01
FC
271 // Scaling error. We can figure it out nonetheless.
272
273 // First, look at the sign of the mantissa
085d898f 274 final long value = ts.getValue();
b9e37ffd 275 if (fValue == 0 && value == 0) {
5179fc01 276 return 0;
b9e37ffd
FC
277 }
278 if (fValue < 0 && value >= 0) {
5179fc01 279 return -1;
b9e37ffd
FC
280 }
281 if (fValue >= 0 && value < 0) {
5179fc01 282 return 1;
b9e37ffd 283 }
5179fc01
FC
284
285 // Otherwise, just compare the scales
085d898f
FC
286 final int scale = ts.getScale();
287 return (fScale > scale) ? (fValue >= 0) ? 1 : -1 : (fValue >= 0) ? -1 : 1;
5179fc01 288 }
8c8bf09f
ASL
289 }
290
5179fc01 291 // ------------------------------------------------------------------------
cbd4ad82 292 // Object
5179fc01 293 // ------------------------------------------------------------------------
28b94d61 294
8c8bf09f 295 @Override
cbd4ad82 296 public int hashCode() {
5179fc01
FC
297 final int prime = 31;
298 int result = 1;
299 result = prime * result + (int) (fValue ^ (fValue >>> 32));
300 result = prime * result + fScale;
cbd4ad82
FC
301 return result;
302 }
303
5179fc01 304 @Override
085d898f 305 public boolean equals(final Object other) {
b9e37ffd 306 if (this == other) {
5179fc01 307 return true;
b9e37ffd
FC
308 }
309 if (other == null) {
5179fc01 310 return false;
b9e37ffd 311 }
065cc19b 312 if (!(other instanceof ITmfTimestamp)) {
5179fc01 313 return false;
b9e37ffd 314 }
065cc19b
AM
315 /* We allow comparing with other types of *I*TmfTimestamp though */
316 final ITmfTimestamp ts = (ITmfTimestamp) other;
317 return (compareTo(ts) == 0);
8c8bf09f
ASL
318 }
319
1f506a43
FC
320 @Override
321 public String toString() {
f8177ba2
FC
322 return toString(TmfTimestampFormat.getDefaulTimeFormat());
323 }
324
f8177ba2
FC
325 /**
326 * @since 2.0
327 */
328 @Override
329 public String toString(final TmfTimestampFormat format) {
330 try {
331 ITmfTimestamp ts = normalize(0, ITmfTimestamp.NANOSECOND_SCALE);
332 return format.format(ts.getValue());
333 }
334 catch (ArithmeticException e) {
335 return format.format(0);
336 }
ff4ed569
FC
337 }
338
032ecd45
MAL
339 /**
340 * Write the time stamp to the ByteBuffer so that it can be saved to disk.
341 * @param bufferOut the buffer to write to
342 *
343 * @since 3.0
344 */
345 public void serialize(ByteBuffer bufferOut) {
346 bufferOut.putLong(fValue);
347 bufferOut.putInt(fScale);
032ecd45 348 }
023761c4 349}
This page took 0.089325 seconds and 5 git commands to generate.