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 // ------------------------------------------------------------------------
29 * The beginning of time
31 public static final ITmfTimestamp BigBang
=
32 new TmfTimestamp(Long
.MIN_VALUE
, Integer
.MAX_VALUE
, 0);
37 public static final ITmfTimestamp BigCrunch
=
38 new TmfTimestamp(Long
.MAX_VALUE
, Integer
.MAX_VALUE
, 0);
43 public static final ITmfTimestamp Zero
=
44 new TmfTimestamp(0, 0, 0);
46 // ------------------------------------------------------------------------
48 // ------------------------------------------------------------------------
51 * The timestamp raw value (mantissa)
53 protected long fValue
;
56 * The timestamp scale (magnitude)
61 * The value precision (tolerance)
63 protected int fPrecision
;
65 // ------------------------------------------------------------------------
67 // ------------------------------------------------------------------------
72 public TmfTimestamp() {
77 * Simple constructor (scale = precision = 0)
79 * @param value the timestamp value
81 public TmfTimestamp(long value
) {
86 * Simple constructor (precision = 0)
88 * @param value the timestamp value
89 * @param scale the timestamp scale
91 public TmfTimestamp(long value
, int scale
) {
92 this(value
, scale
, 0);
98 * @param value the timestamp value
99 * @param scale the timestamp scale
100 * @param precision the timestamp precision
102 public TmfTimestamp(long value
, int scale
, int precision
) {
105 fPrecision
= Math
.abs(precision
);
111 * @param timestamp the timestamp to copy
113 public TmfTimestamp(ITmfTimestamp timestamp
) {
114 if (timestamp
== null)
115 throw new IllegalArgumentException();
116 fValue
= timestamp
.getValue();
117 fScale
= timestamp
.getScale();
118 fPrecision
= timestamp
.getPrecision();
121 // ------------------------------------------------------------------------
123 // ------------------------------------------------------------------------
126 * @see org.eclipse.linuxtools.tmf.core.event.ITmfTimestamp#getValue()
129 public long getValue() {
134 * @see org.eclipse.linuxtools.tmf.core.event.ITmfTimestamp#getScale()
137 public int getScale() {
142 * @see org.eclipse.linuxtools.tmf.core.event.ITmfTimestamp#getPrecision()
145 public int getPrecision() {
149 private static final long scalingFactors
[] = new long[] {
168 1000000000000000000L,
172 * @see org.eclipse.linuxtools.tmf.core.event.ITmfTimestamp#normalize(long, int)
175 public ITmfTimestamp
normalize(long offset
, int scale
) throws ArithmeticException
{
178 int precision
= fPrecision
;
180 // Handle the trivial case
181 if (fScale
== scale
&& offset
== 0)
182 return new TmfTimestamp(this);
184 // First, scale the timestamp
185 if (fScale
!= scale
) {
186 int scaleDiff
= Math
.abs(fScale
- scale
);
187 if (scaleDiff
>= scalingFactors
.length
) {
188 throw new ArithmeticException("Scaling exception"); //$NON-NLS-1$
191 long scalingFactor
= scalingFactors
[scaleDiff
];
192 if (scale
< fScale
) {
193 value
*= scalingFactor
;
194 precision
*= scalingFactor
;
196 value
/= scalingFactor
;
197 precision
/= scalingFactor
;
201 // Then, apply the offset
203 value
= (value
< Long
.MIN_VALUE
- offset
) ? Long
.MIN_VALUE
: value
+ offset
;
205 value
= (value
> Long
.MAX_VALUE
- offset
) ? Long
.MAX_VALUE
: value
+ offset
;
208 return new TmfTimestamp(value
, scale
, precision
);
212 * @see org.eclipse.linuxtools.tmf.core.event.ITmfTimestamp#compareTo(org.eclipse.linuxtools.tmf.core.event.ITmfTimestamp, boolean)
215 public int compareTo(ITmfTimestamp ts
, boolean withinPrecision
) {
217 // Check the corner cases (we can't use equals() because it uses compareTo()...)
218 if (this == ts
|| (fValue
== ts
.getValue() && fScale
== ts
.getScale()))
220 if ((fValue
== BigBang
.getValue() && fScale
== BigBang
.getScale()) || (ts
.getValue() == BigCrunch
.getValue() && ts
.getScale() == BigCrunch
.getScale()))
222 if ((fValue
== BigCrunch
.getValue() && fScale
== BigCrunch
.getScale()) || (ts
.getValue() == BigBang
.getValue() && ts
.getScale() == BigBang
.getScale()))
226 ITmfTimestamp nts
= ts
.normalize(0, fScale
);
227 long delta
= fValue
- nts
.getValue();
228 if ((delta
== 0) || (withinPrecision
&& (Math
.abs(delta
) <= (fPrecision
+ nts
.getPrecision())))) {
231 return (delta
> 0) ?
1 : -1;
233 catch (ArithmeticException e
) {
234 // Scaling error. We can figure it out nonetheless.
236 // First, look at the sign of the mantissa
237 long value
= ts
.getValue();
238 if (fValue
== 0 && value
== 0)
240 if (fValue
< 0 && value
>= 0)
242 if (fValue
>= 0 && value
< 0)
245 // Otherwise, just compare the scales
246 int scale
= ts
.getScale();
247 return (fScale
> scale
) ?
(fValue
>= 0) ?
1 : -1 : (fValue
>= 0) ?
-1 : 1;
252 * @see org.eclipse.linuxtools.tmf.core.event.ITmfTimestamp#getDelta(org.eclipse.linuxtools.tmf.core.event.ITmfTimestamp)
255 public ITmfTimestamp
getDelta(ITmfTimestamp ts
) {
256 ITmfTimestamp nts
= ts
.normalize(0, fScale
);
257 long value
= fValue
- nts
.getValue();
258 return new TmfTimestamp(value
, fScale
, fPrecision
+ nts
.getPrecision());
261 // ------------------------------------------------------------------------
263 // ------------------------------------------------------------------------
266 * @see java.lang.Object#clone()
269 public ITmfTimestamp
clone() {
270 TmfTimestamp clone
= null;
272 clone
= (TmfTimestamp
) super.clone();
273 clone
.fValue
= fValue
;
274 clone
.fScale
= fScale
;
275 clone
.fPrecision
= fPrecision
;
276 } catch (CloneNotSupportedException e
) {
281 // ------------------------------------------------------------------------
283 // ------------------------------------------------------------------------
286 * @see org.eclipse.linuxtools.tmf.core.event.ITmfTimestamp#compareTo(org.eclipse.linuxtools.tmf.core.event.ITmfTimestamp)
289 public int compareTo(ITmfTimestamp ts
) {
290 return compareTo(ts
, false);
293 // ------------------------------------------------------------------------
295 // ------------------------------------------------------------------------
298 * @see java.lang.Object#hashCode()
301 public int hashCode() {
302 final int prime
= 31;
304 result
= prime
* result
+ (int) (fValue ^
(fValue
>>> 32));
305 result
= prime
* result
+ fScale
;
306 result
= prime
* result
+ fPrecision
;
311 * @see java.lang.Object#equals(java.lang.Object)
314 public boolean equals(Object other
) {
319 if (!(other
instanceof TmfTimestamp
))
321 TmfTimestamp ts
= (TmfTimestamp
) other
;
322 return compareTo(ts
, false) == 0;
326 * @see java.lang.Object#toString()
329 @SuppressWarnings("nls")
330 public String
toString() {
331 return "TmfTimestamp [fValue=" + fValue
+ ", fScale=" + fScale
+ ", fPrecision=" + fPrecision
+ "]";