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