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 scaled in
24 * @author Francois Chouinard
26 public class TmfTimestamp
implements ITmfTimestamp
{
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_CANNED
= BIG_CRUNCH
;
59 public static final ITmfTimestamp ZERO
=
60 new TmfTimestamp(0, 0, 0);
62 // ------------------------------------------------------------------------
64 // ------------------------------------------------------------------------
67 * The timestamp raw value (mantissa)
69 private final long fValue
;
72 * The timestamp scale (magnitude)
74 private final int fScale
;
77 * The value precision (tolerance)
79 private final 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 // ------------------------------------------------------------------------
143 * @see org.eclipse.linuxtools.tmf.core.event.ITmfTimestamp#getValue()
146 public long getValue() {
151 * @see org.eclipse.linuxtools.tmf.core.event.ITmfTimestamp#getScale()
154 public int getScale() {
159 * @see org.eclipse.linuxtools.tmf.core.event.ITmfTimestamp#getPrecision()
162 public int getPrecision() {
166 private static final long scalingFactors
[] = new long[] {
185 1000000000000000000L,
189 * @see org.eclipse.linuxtools.tmf.core.event.ITmfTimestamp#normalize(long, int)
192 public ITmfTimestamp
normalize(final long offset
, final int scale
) {
195 int precision
= fPrecision
;
197 // Handle the trivial case
198 if (fScale
== scale
&& offset
== 0) {
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
)) {
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$
214 final long scalingFactor
= scalingFactors
[scaleDiff
];
215 if (scale
< fScale
) {
216 value
*= scalingFactor
;
217 precision
*= scalingFactor
;
219 value
/= scalingFactor
;
220 precision
/= scalingFactor
;
224 // Then, apply the offset
226 value
= (value
< Long
.MIN_VALUE
- offset
) ? Long
.MIN_VALUE
: value
+ offset
;
228 value
= (value
> Long
.MAX_VALUE
- offset
) ? Long
.MAX_VALUE
: value
+ offset
;
231 return new TmfTimestamp(value
, scale
, precision
);
235 * @see org.eclipse.linuxtools.tmf.core.event.ITmfTimestamp#compareTo(org.eclipse.linuxtools.tmf.core.event.ITmfTimestamp, boolean)
238 public int compareTo(final ITmfTimestamp ts
, final boolean withinPrecision
) {
240 // Check the corner cases (we can't use equals() because it uses compareTo()...)
244 if (this == ts
|| (fValue
== ts
.getValue() && fScale
== ts
.getScale())) {
247 if ((fValue
== BIG_BANG
.getValue() && fScale
== BIG_BANG
.getScale()) || (ts
.getValue() == BIG_CRUNCH
.getValue() && ts
.getScale() == BIG_CRUNCH
.getScale())) {
250 if ((fValue
== BIG_CRUNCH
.getValue() && fScale
== BIG_CRUNCH
.getScale()) || (ts
.getValue() == BIG_BANG
.getValue() && ts
.getScale() == BIG_BANG
.getScale())) {
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())))) {
260 return (delta
> 0) ?
1 : -1;
262 catch (final ArithmeticException e
) {
263 // Scaling error. We can figure it out nonetheless.
265 // First, look at the sign of the mantissa
266 final long value
= ts
.getValue();
267 if (fValue
== 0 && value
== 0) {
270 if (fValue
< 0 && value
>= 0) {
273 if (fValue
>= 0 && value
< 0) {
277 // Otherwise, just compare the scales
278 final int scale
= ts
.getScale();
279 return (fScale
> scale
) ?
(fValue
>= 0) ?
1 : -1 : (fValue
>= 0) ?
-1 : 1;
284 * @see org.eclipse.linuxtools.tmf.core.event.ITmfTimestamp#getDelta(org.eclipse.linuxtools.tmf.core.event.ITmfTimestamp)
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());
293 // ------------------------------------------------------------------------
295 // ------------------------------------------------------------------------
298 * @see org.eclipse.linuxtools.tmf.core.event.ITmfTimestamp#compareTo(org.eclipse.linuxtools.tmf.core.event.ITmfTimestamp)
301 public int compareTo(final ITmfTimestamp ts
) {
302 return compareTo(ts
, false);
305 // ------------------------------------------------------------------------
307 // ------------------------------------------------------------------------
310 * @see java.lang.Object#hashCode()
313 public int hashCode() {
314 final int prime
= 31;
316 result
= prime
* result
+ (int) (fValue ^
(fValue
>>> 32));
317 result
= prime
* result
+ fScale
;
318 result
= prime
* result
+ fPrecision
;
323 * @see java.lang.Object#equals(java.lang.Object)
326 public boolean equals(final Object other
) {
333 if (!(other
instanceof TmfTimestamp
)) {
336 final TmfTimestamp ts
= (TmfTimestamp
) other
;
337 return compareTo(ts
, false) == 0;
341 * @see java.lang.Object#toString()
344 public String
toString() {
345 return toString(TmfTimestampFormat
.getDefaulTimeFormat());
349 * @see org.eclipse.linuxtools.tmf.core.event.ITmfTimestamp#toString(org.eclipse.linuxtools.tmf.core.event.TmfTimestampFormat)
355 public String
toString(final TmfTimestampFormat format
) {
357 ITmfTimestamp ts
= normalize(0, ITmfTimestamp
.NANOSECOND_SCALE
);
358 return format
.format(ts
.getValue());
360 catch (ArithmeticException e
) {
361 return format
.format(0);