1 /*******************************************************************************
2 * Copyright (c) 2009, 2010, 2012 Ericsson
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
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 *******************************************************************************/
16 package org
.eclipse
.linuxtools
.tmf
.core
.event
;
19 * A generic timestamp implementation. The timestamp is represented by the
20 * tuple { value, scale, precision }. By default, timestamps are in the
24 * @author Francois Chouinard
26 public class TmfTimestamp
implements ITmfTimestamp
, Cloneable
{
28 // ------------------------------------------------------------------------
30 // ------------------------------------------------------------------------
33 * The beginning of time
35 public static final ITmfTimestamp BIG_BANG
=
36 new TmfTimestamp(Long
.MIN_VALUE
, Integer
.MAX_VALUE
, 0);
41 public static final ITmfTimestamp BIG_CRUNCH
=
42 new TmfTimestamp(Long
.MAX_VALUE
, Integer
.MAX_VALUE
, 0);
45 * A more practical definition of "beginning of time"
48 public static final ITmfTimestamp PROJECT_IS_FUNDED
= BIG_BANG
;
51 * A more practical definition of "end of time"
54 public static final ITmfTimestamp PROJECT_IS_CANCELLED
= BIG_CRUNCH
;
59 public static final ITmfTimestamp ZERO
=
60 new TmfTimestamp(0, 0, 0);
62 // ------------------------------------------------------------------------
64 // ------------------------------------------------------------------------
67 * The timestamp raw value (mantissa) in nanoseconds
72 * The timestamp scale (magnitude)
77 * The value precision (tolerance)
79 private int fPrecision
;
81 // ------------------------------------------------------------------------
83 // ------------------------------------------------------------------------
88 public TmfTimestamp() {
89 this(0, ITmfTimestamp
.SECOND_SCALE
, 0);
93 * Simple constructor (scale = precision = 0)
95 * @param value the timestamp value
97 public TmfTimestamp(final long value
) {
98 this(value
, ITmfTimestamp
.SECOND_SCALE
, 0);
102 * Simple constructor (precision = 0)
104 * @param value the timestamp value
105 * @param scale the timestamp scale
107 public TmfTimestamp(final long value
, final int scale
) {
108 this(value
, scale
, 0);
114 * @param value the timestamp value
115 * @param scale the timestamp scale
116 * @param precision the timestamp precision
118 public TmfTimestamp(final long value
, final int scale
, final int precision
) {
121 fPrecision
= Math
.abs(precision
);
127 * @param timestamp the timestamp to copy
129 public TmfTimestamp(final ITmfTimestamp timestamp
) {
130 if (timestamp
== null) {
131 throw new IllegalArgumentException();
133 fValue
= timestamp
.getValue();
134 fScale
= timestamp
.getScale();
135 fPrecision
= timestamp
.getPrecision();
138 // ------------------------------------------------------------------------
140 // ------------------------------------------------------------------------
142 protected void setValue(long value
, int scale
, int precision
) {
145 fPrecision
= precision
;
148 // ------------------------------------------------------------------------
150 // ------------------------------------------------------------------------
153 * @see org.eclipse.linuxtools.tmf.core.event.ITmfTimestamp#getValue()
156 public long getValue() {
161 * @see org.eclipse.linuxtools.tmf.core.event.ITmfTimestamp#getScale()
164 public int getScale() {
169 * @see org.eclipse.linuxtools.tmf.core.event.ITmfTimestamp#getPrecision()
172 public int getPrecision() {
176 private static final long scalingFactors
[] = new long[] {
195 1000000000000000000L,
199 * @see org.eclipse.linuxtools.tmf.core.event.ITmfTimestamp#normalize(long, int)
202 public ITmfTimestamp
normalize(final long offset
, final int scale
) {
205 int precision
= fPrecision
;
207 // Handle the trivial case
208 if (fScale
== scale
&& offset
== 0) {
209 return new TmfTimestamp(this);
212 // In case of big bang and big crunch just return this (no need to normalize)
213 if (this.equals(BIG_BANG
) || this.equals(BIG_CRUNCH
)) {
217 // First, scale the timestamp
218 if (fScale
!= scale
) {
219 final int scaleDiff
= Math
.abs(fScale
- scale
);
220 if (scaleDiff
>= scalingFactors
.length
) {
221 throw new ArithmeticException("Scaling exception"); //$NON-NLS-1$
224 final long scalingFactor
= scalingFactors
[scaleDiff
];
225 if (scale
< fScale
) {
226 value
*= scalingFactor
;
227 precision
*= scalingFactor
;
229 value
/= scalingFactor
;
230 precision
/= scalingFactor
;
234 // Then, apply the offset
236 value
= (value
< Long
.MIN_VALUE
- offset
) ? Long
.MIN_VALUE
: value
+ offset
;
238 value
= (value
> Long
.MAX_VALUE
- offset
) ? Long
.MAX_VALUE
: value
+ offset
;
241 return new TmfTimestamp(value
, scale
, precision
);
245 * @see org.eclipse.linuxtools.tmf.core.event.ITmfTimestamp#compareTo(org.eclipse.linuxtools.tmf.core.event.ITmfTimestamp, boolean)
248 public int compareTo(final ITmfTimestamp ts
, final boolean withinPrecision
) {
250 // Check the corner cases (we can't use equals() because it uses compareTo()...)
254 if (this == ts
|| (fValue
== ts
.getValue() && fScale
== ts
.getScale())) {
257 if ((fValue
== BIG_BANG
.getValue() && fScale
== BIG_BANG
.getScale()) || (ts
.getValue() == BIG_CRUNCH
.getValue() && ts
.getScale() == BIG_CRUNCH
.getScale())) {
260 if ((fValue
== BIG_CRUNCH
.getValue() && fScale
== BIG_CRUNCH
.getScale()) || (ts
.getValue() == BIG_BANG
.getValue() && ts
.getScale() == BIG_BANG
.getScale())) {
265 final ITmfTimestamp nts
= ts
.normalize(0, fScale
);
266 final long delta
= fValue
- nts
.getValue();
267 if ((delta
== 0) || (withinPrecision
&& (Math
.abs(delta
) <= (fPrecision
+ nts
.getPrecision())))) {
270 return (delta
> 0) ?
1 : -1;
272 catch (final ArithmeticException e
) {
273 // Scaling error. We can figure it out nonetheless.
275 // First, look at the sign of the mantissa
276 final long value
= ts
.getValue();
277 if (fValue
== 0 && value
== 0) {
280 if (fValue
< 0 && value
>= 0) {
283 if (fValue
>= 0 && value
< 0) {
287 // Otherwise, just compare the scales
288 final int scale
= ts
.getScale();
289 return (fScale
> scale
) ?
(fValue
>= 0) ?
1 : -1 : (fValue
>= 0) ?
-1 : 1;
294 * @see org.eclipse.linuxtools.tmf.core.event.ITmfTimestamp#getDelta(org.eclipse.linuxtools.tmf.core.event.ITmfTimestamp)
297 public ITmfTimestamp
getDelta(final ITmfTimestamp ts
) {
298 final ITmfTimestamp nts
= ts
.normalize(0, fScale
);
299 final long value
= fValue
- nts
.getValue();
300 return new TmfTimestamp(value
, fScale
, fPrecision
+ nts
.getPrecision());
303 // ------------------------------------------------------------------------
305 // ------------------------------------------------------------------------
308 * @see java.lang.Object#clone()
311 public TmfTimestamp
clone() {
312 TmfTimestamp clone
= null;
314 clone
= (TmfTimestamp
) super.clone();
315 clone
.fValue
= fValue
;
316 clone
.fScale
= fScale
;
317 clone
.fPrecision
= fPrecision
;
318 } catch (final CloneNotSupportedException e
) {
323 // ------------------------------------------------------------------------
325 // ------------------------------------------------------------------------
328 * @see org.eclipse.linuxtools.tmf.core.event.ITmfTimestamp#compareTo(org.eclipse.linuxtools.tmf.core.event.ITmfTimestamp)
331 public int compareTo(final ITmfTimestamp ts
) {
332 return compareTo(ts
, false);
335 // ------------------------------------------------------------------------
337 // ------------------------------------------------------------------------
340 * @see java.lang.Object#hashCode()
343 public int hashCode() {
344 final int prime
= 31;
346 result
= prime
* result
+ (int) (fValue ^
(fValue
>>> 32));
347 result
= prime
* result
+ fScale
;
348 result
= prime
* result
+ fPrecision
;
353 * @see java.lang.Object#equals(java.lang.Object)
356 public boolean equals(final Object other
) {
363 if (!(other
instanceof TmfTimestamp
)) {
366 final TmfTimestamp ts
= (TmfTimestamp
) other
;
367 return compareTo(ts
, false) == 0;
371 * @see java.lang.Object#toString()
374 public String
toString() {
375 return toString(TmfTimestampFormat
.getDefaulTimeFormat());
379 * @see org.eclipse.linuxtools.tmf.core.event.ITmfTimestamp#toString(org.eclipse.linuxtools.tmf.core.event.TmfTimestampFormat)
385 public String
toString(final TmfTimestampFormat format
) {
387 ITmfTimestamp ts
= normalize(0, ITmfTimestamp
.NANOSECOND_SCALE
);
388 return format
.format(ts
.getValue());
390 catch (ArithmeticException e
) {
391 return format
.format(0);