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 *******************************************************************************/
15 package org
.eclipse
.linuxtools
.tmf
.core
.event
;
18 * <b><u>TmfTimestamp</u></b>
20 * A generic implementation of ITmfTimestamp.
22 public class TmfTimestamp
implements ITmfTimestamp
{
24 // ------------------------------------------------------------------------
26 // ------------------------------------------------------------------------
28 // The beginning and end of time
29 public static final TmfTimestamp BigBang
= new TmfTimestamp(Long
.MIN_VALUE
, Integer
.MAX_VALUE
, 0);
30 public static final TmfTimestamp BigCrunch
= new TmfTimestamp(Long
.MAX_VALUE
, Integer
.MAX_VALUE
, 0);
31 public static final TmfTimestamp Zero
= new TmfTimestamp(0, 0, 0);
33 // ------------------------------------------------------------------------
35 // ------------------------------------------------------------------------
37 protected long fValue
; // The timestamp raw value
38 protected int fScale
; // The time scale
39 protected int fPrecision
; // The value precision (tolerance)
41 // ------------------------------------------------------------------------
43 // ------------------------------------------------------------------------
48 public TmfTimestamp() {
53 * Simple constructor (scale = precision = 0)
55 * @param value the timestamp value
57 public TmfTimestamp(long value
) {
62 * Simple constructor (precision = 0)
64 * @param value the timestamp value
65 * @param scale the timestamp scale
67 public TmfTimestamp(long value
, int scale
) {
68 this(value
, scale
, 0);
74 * @param value the timestamp value
75 * @param scale the timestamp scale
76 * @param precision the timestamp precision
78 public TmfTimestamp(long value
, int scale
, int precision
) {
81 fPrecision
= Math
.abs(precision
);
87 * @param timestamp the timestamp to copy
89 public TmfTimestamp(ITmfTimestamp timestamp
) {
90 if (timestamp
== null)
91 throw new IllegalArgumentException();
92 fValue
= timestamp
.getValue();
93 fScale
= timestamp
.getScale();
94 fPrecision
= timestamp
.getPrecision();
97 // ------------------------------------------------------------------------
99 // ------------------------------------------------------------------------
101 public long getValue() {
105 public int getScale() {
109 public int getPrecision() {
113 private static final long scalingFactors
[] = new long[] {
132 1000000000000000000L,
135 public ITmfTimestamp
normalize(long offset
, int scale
) throws ArithmeticException
{
138 int precision
= fPrecision
;
140 // Handle the trivial case
141 if (fScale
== scale
&& offset
== 0)
142 return new TmfTimestamp(this);
144 // First, scale the timestamp
145 if (fScale
!= scale
) {
146 int scaleDiff
= Math
.abs(fScale
- scale
);
147 if (scaleDiff
>= scalingFactors
.length
) {
148 throw new ArithmeticException("Scaling exception"); //$NON-NLS-1$
151 long scalingFactor
= scalingFactors
[scaleDiff
];
152 if (scale
< fScale
) {
153 value
*= scalingFactor
;
154 precision
*= scalingFactor
;
156 value
/= scalingFactor
;
157 precision
/= scalingFactor
;
161 // Then, apply the offset
163 value
= (value
< Long
.MIN_VALUE
- offset
) ? Long
.MIN_VALUE
: value
+ offset
;
165 value
= (value
> Long
.MAX_VALUE
- offset
) ? Long
.MAX_VALUE
: value
+ offset
;
168 return new TmfTimestamp(value
, scale
, precision
);
171 public int compareTo(ITmfTimestamp ts
, boolean withinPrecision
) {
173 // Check the corner cases (we can't use equals() because it uses compareTo()...)
174 if (this == ts
|| (fValue
== ts
.getValue() && fScale
== ts
.getScale()))
176 if ((fValue
== BigBang
.getValue() && fScale
== BigBang
.getScale()) || (ts
.getValue() == BigCrunch
.getValue() && ts
.getScale() == BigCrunch
.getScale()))
178 if ((fValue
== BigCrunch
.getValue() && fScale
== BigCrunch
.getScale()) || (ts
.getValue() == BigBang
.getValue() && ts
.getScale() == BigBang
.getScale()))
182 ITmfTimestamp nts
= ts
.normalize(0, fScale
);
183 long delta
= fValue
- nts
.getValue();
184 if ((delta
== 0) || (withinPrecision
&& (Math
.abs(delta
) <= (fPrecision
+ nts
.getPrecision())))) {
187 return (delta
> 0) ?
1 : -1;
189 catch (ArithmeticException e
) {
190 // Scaling error. We can figure it out nonetheless.
192 // First, look at the sign of the mantissa
193 long value
= ts
.getValue();
194 if (fValue
== 0 && value
== 0)
196 if (fValue
< 0 && value
>= 0)
198 if (fValue
>= 0 && value
< 0)
201 // Otherwise, just compare the scales
202 int scale
= ts
.getScale();
203 return (fScale
> scale
) ?
(fValue
> 0) ?
1 : -1 : (fValue
> 0) ?
-1 : 1;
208 public ITmfTimestamp
getDelta(ITmfTimestamp ts
) {
209 ITmfTimestamp nts
= ts
.normalize(0, fScale
);
210 long value
= fValue
- nts
.getValue();
211 return new TmfTimestamp(value
, fScale
, fPrecision
+ nts
.getPrecision());
214 // ------------------------------------------------------------------------
216 // ------------------------------------------------------------------------
219 public ITmfTimestamp
clone() {
220 TmfTimestamp clone
= null;
222 clone
= (TmfTimestamp
) super.clone();
223 clone
.fValue
= fValue
;
224 clone
.fScale
= fScale
;
225 clone
.fPrecision
= fPrecision
;
226 } catch (CloneNotSupportedException e
) {
231 // ------------------------------------------------------------------------
233 // ------------------------------------------------------------------------
236 public int compareTo(ITmfTimestamp ts
) {
237 return compareTo(ts
, false);
240 // ------------------------------------------------------------------------
242 // ------------------------------------------------------------------------
245 public int hashCode() {
246 final int prime
= 31;
248 result
= prime
* result
+ (int) (fValue ^
(fValue
>>> 32));
249 result
= prime
* result
+ fScale
;
250 result
= prime
* result
+ fPrecision
;
255 public boolean equals(Object other
) {
260 if (!(other
instanceof TmfTimestamp
))
262 TmfTimestamp ts
= (TmfTimestamp
) other
;
263 return compareTo(ts
, false) == 0;
267 @SuppressWarnings("nls")
268 public String
toString() {
269 return "TmfTimestamp [fValue=" + fValue
+ ", fScale=" + fScale
+ ", fPrecision=" + fPrecision
+ "]";