1 /*******************************************************************************
2 * Copyright (c) 2009 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 (fchouinard@gmail.com) - Initial API and implementation
11 *******************************************************************************/
13 package org
.eclipse
.linuxtools
.tmf
.event
;
16 * <b><u>TmfTimestamp</u></b>
18 * The fundamental time reference in the TMF.
20 * It provides a generic timestamp implementation in its most basic form:
22 * <li> an unstructured integer value
23 * <li> a time scale corresponding to the magnitude of the value wrt some
24 * application-specific base unit (e.g. the second)
25 * <li> a precision to indicate the error on the value (useful for comparing
26 * timestamps in different scales). Default: 0.
28 * To allow synchronization of timestamps from different reference clocks,
29 * there is a possibility to "adjust" the timestamp both by changing its
30 * scale (traces of different scale) and by adding an offset to its value
31 * (clock drift between traces).
33 * Note that the adjusted timestamp value could be negative e.g. for events
34 * that occurred before t0 of the reference clock.
37 public class TmfTimestamp
{
39 // ========================================================================
41 // ========================================================================
43 private final long fValue
; // The timestamp value
44 private final byte fScale
; // The time scale
45 private final long fPrecision
; // The value precision (tolerance)
47 // ========================================================================
49 // ========================================================================
51 // The beginning and end of time
52 public static final TmfTimestamp BigBang
= new TmfTimestamp(0, (byte) 0, 0);
53 public static final TmfTimestamp BigCrunch
= new TmfTimestamp(Long
.MAX_VALUE
, Byte
.MAX_VALUE
, 0);
55 // ========================================================================
57 // ========================================================================
60 * Default constructor.
62 public TmfTimestamp() {
67 * Simple constructor with default error value
69 * @param value - the original time value
70 * @param scale - the time scale
72 public TmfTimestamp(long value
, byte scale
) {
73 this(value
, scale
, 0);
77 * Constructor with measurement error.
79 * @param value - the time value
80 * @param scale - the time scale
81 * @param precision - the value precision (tolerance)
83 public TmfTimestamp(long value
, byte scale
, long precision
) {
86 fPrecision
= Math
.abs(precision
);
92 * @param other - the timestamp to clone
94 public TmfTimestamp(TmfTimestamp other
) {
95 this(other
.fValue
, other
.fScale
, other
.fPrecision
);
98 // ========================================================================
100 // ========================================================================
103 * @return The timestamp value
105 public long getValue() {
110 * @return The timestamp scale
112 public byte getScale() {
117 * @return The timestamp value precision
119 public long getPrecision() {
123 // ========================================================================
125 // ========================================================================
128 public String
toString() {
129 return "[TmfTimestamp:" + fValue
+ "," + fScale
+ "," + fPrecision
+ "]";
133 * Return a shifted and scaled timestamp.
135 * Limitation: The scaling is limited to MAX_SCALING orders of magnitude.
136 * The main reason is that the 64 bits value starts to lose any significance
137 * meaning beyond that scale difference and it's not even worth the trouble
138 * to switch to BigDecimal arithmetics.
140 * @param offset - the shift value (in the same scale as newScale)
141 * @param newScale - the new scale
142 * @return The synchronized timestamp
146 * A java <code>long</code> has a maximum of 19 significant digits.
147 * (-9,223,372,036,854,775,808 .. +9,223,372,036,854,775,807)
149 * It is therefore useless to try to synchronize 2 timestamps whose
150 * difference in scale exceeds that value.
152 private static int MAX_SCALING
= 19;
153 public TmfTimestamp
synchronize(long offset
, byte newScale
) throws ArithmeticException
{
154 long newValue
= fValue
;
155 long newPrecision
= fPrecision
;
157 // Determine the scaling factor
158 if (fScale
!= newScale
) {
159 int scaleDiff
= Math
.abs(fScale
- newScale
);
160 // Let's try to be realistic...
161 if (scaleDiff
> MAX_SCALING
) {
162 throw new ArithmeticException("Scaling exception");
164 long scalingFactor
= 1;
165 for (int i
= 0; i
< Math
.abs(fScale
- newScale
); i
++) {
168 if (newScale
< fScale
) {
169 newValue
*= scalingFactor
;
170 newPrecision
*= scalingFactor
;
172 newValue
/= scalingFactor
;
173 newPrecision
/= scalingFactor
;
177 return new TmfTimestamp(newValue
+ offset
, newScale
, newPrecision
);
181 * Compute the adjustment, in the reference scale, needed to synchronize
182 * this timestamp with a reference timestamp.
184 * @param reference - the reference timestamp to synchronize with
185 * @return The adjustment term in the reference time scale
186 * @throws TmfNumericalException
188 public long getAdjustment(TmfTimestamp reference
) throws ArithmeticException
{
189 TmfTimestamp ts
= synchronize(0, reference
.fScale
);
190 return reference
.fValue
- ts
.fValue
;
194 * Compare with another timestamp
196 * @param other - the otehr timestamp
197 * @param withinPrecision - indicates if precision is to be take into consideration
198 * @return <li> -1: this timestamp is lower
199 * <li> 0: timestamps are equal (within precision if requested)
200 * <li> 1: this timestamp is higher
201 * @throws TmfNumericalException
203 public int compareTo(final TmfTimestamp other
, boolean withinPrecision
) {
205 // If values have the same time scale, perform the comparison
206 if (fScale
== other
.fScale
) {
207 if (withinPrecision
) {
208 if ((fValue
+ fPrecision
) < (other
.fValue
- other
.fPrecision
))
210 if ((fValue
- fPrecision
) > (other
.fValue
+ other
.fPrecision
))
214 return (fValue
== other
.fValue
) ?
0 :
215 (fValue
< other
.fValue
) ?
-1 : 1;
218 // If values have different time scales, adjust to the finest one and
219 // then compare. If the scaling difference is too large, revert to
220 // some heuristics. Hopefully, nobody will try to compare galactic and
221 // atomic clock events...
222 byte newScale
= (fScale
< other
.fScale
) ? fScale
: other
.fScale
;
224 TmfTimestamp ts1
= this.synchronize(0, newScale
);
225 TmfTimestamp ts2
= other
.synchronize(0, newScale
);
226 return ts1
.compareTo(ts2
, withinPrecision
);
227 } catch (ArithmeticException e
) {
228 if ((fValue
== 0) || (other
.fValue
== 0)) {
229 return (fValue
== other
.fValue
) ?
0 : (fValue
< other
.fValue
) ?
-1 : 1;
231 if ((fValue
> 0) && (other
.fValue
> 0)) {
232 return (fScale
< other
.fScale
) ?
-1 : 1;
234 if ((fValue
< 0) && (other
.fValue
< 0)) {
235 return (fScale
> other
.fScale
) ?
-1 : 1;
237 return (fValue
< 0) ?
-1 : 1;
242 * @see java.lang.Object#equals(java.lang.Object)
245 public boolean equals(Object other
) {
246 if (other
instanceof TmfTimestamp
)
247 return compareTo((TmfTimestamp
) other
, false) == 0;
248 return super.equals(other
);
This page took 0.035895 seconds and 6 git commands to generate.