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 - Initial API and implementation
11 *******************************************************************************/
13 package org
.eclipse
.linuxtools
.tmf
.event
;
17 * <b><u>TmfTimestamp</u></b>
19 * The fundamental time reference in the TMF.
21 * It provides a generic timestamp implementation in its most basic form:
23 * <li>an unstructured integer value
24 * <li>a time scale corresponding to the magnitude of the value wrt some
25 * application-specific base unit (e.g. the second)
26 * <li>a precision to indicate the error on the value (useful for comparing
27 * timestamps in different scales). Default: 0.
29 * To allow synchronization of timestamps from different reference clocks,
30 * there is a possibility to "adjust" the timestamp both by changing its scale
31 * (traces of different scale) and by adding an offset to its value (clock
32 * drift between traces).
34 * Notice that the adjusted timestamp value could be negative e.g. for events
35 * that occurred before t0 wrt the reference clock.
37 * Finally, notice that timestamps are immutable.
39 public class TmfTimestamp
implements Cloneable
{
41 // ========================================================================
43 // ========================================================================
45 protected long fValue
; // The timestamp value
46 protected byte fScale
; // The time scale
47 protected long fPrecision
; // The value precision (tolerance)
49 // ========================================================================
51 // ========================================================================
53 // The beginning and end of time
54 public static final TmfTimestamp BigBang
= new TmfTimestamp(Long
.MIN_VALUE
, Byte
.MAX_VALUE
, 0);
55 public static final TmfTimestamp BigCrunch
= new TmfTimestamp(Long
.MAX_VALUE
, Byte
.MAX_VALUE
, 0);
56 public static final TmfTimestamp Zero
= new TmfTimestamp(0, (byte) 0, 0);
58 // ========================================================================
60 // ========================================================================
65 public TmfTimestamp() {
70 * Simple constructor with value only
72 public TmfTimestamp(long value
) {
73 this(value
, (byte) 0, 0);
77 * Simple constructor with value and scale
82 public TmfTimestamp(long value
, byte scale
) {
83 this(value
, scale
, 0);
87 * Constructor with value, scale and precision
93 public TmfTimestamp(long value
, byte scale
, long precision
) {
96 fPrecision
= Math
.abs(precision
);
104 public TmfTimestamp(TmfTimestamp other
) {
105 assert(other
!= null);
106 fValue
= other
.fValue
;
107 fScale
= other
.fScale
;
108 fPrecision
= other
.fPrecision
;
111 // ========================================================================
113 // ========================================================================
116 * @return the timestamp value
118 public long getValue() {
123 * @return the timestamp scale
125 public byte getScale() {
130 * @return the timestamp value precision
132 public long getPrecision() {
136 // ========================================================================
138 // ========================================================================
141 * Return a shifted and scaled timestamp.
143 * Limitation: The scaling is limited to MAX_SCALING orders of magnitude.
144 * The main reason is that the 64 bits value starts to lose any significance
145 * meaning beyond that scale difference and it's not even worth the trouble
146 * to switch to BigDecimal arithmetics.
149 * - the shift value (in the same scale as newScale)
152 * @return The synchronized timestamp
156 * A java <code>long</code> has a maximum of 19 significant digits.
157 * (-9,223,372,036,854,775,808 .. +9,223,372,036,854,775,807)
159 * It is therefore useless to try to synchronize 2 timestamps whose
160 * difference in scale exceeds that value.
162 private static int MAX_SCALING
= 19;
164 public TmfTimestamp
synchronize(long offset
, byte newScale
) throws ArithmeticException
{
165 long newValue
= fValue
;
166 long newPrecision
= fPrecision
;
168 // Determine the scaling factor
169 if (fScale
!= newScale
) {
170 int scaleDiff
= Math
.abs(fScale
- newScale
);
171 // Let's try to be realistic...
172 if (scaleDiff
> MAX_SCALING
) {
173 throw new ArithmeticException("Scaling exception");
176 long scalingFactor
= 1;
177 for (int i
= 0; i
< scaleDiff
; i
++) {
180 if (newScale
< fScale
) {
181 newValue
*= scalingFactor
;
182 newPrecision
*= scalingFactor
;
184 newValue
/= scalingFactor
;
185 newPrecision
/= scalingFactor
;
189 return new TmfTimestamp(newValue
+ offset
, newScale
, newPrecision
);
193 * Compute the adjustment, in the reference scale, needed to synchronize
194 * this timestamp with a reference timestamp.
197 * - the reference timestamp to synchronize with
198 * @return the adjustment term in the reference time scale
199 * @throws TmfNumericalException
201 public long getAdjustment(TmfTimestamp reference
) throws ArithmeticException
{
202 TmfTimestamp ts
= synchronize(0, reference
.fScale
);
203 return reference
.fValue
- ts
.fValue
;
207 * Compare with another timestamp
210 * - the other timestamp
211 * @param withinPrecision
212 * - indicates if precision is to be take into consideration
213 * @return -1: this timestamp is lower
214 * 0: timestamps are equal (within precision if requested)
215 * 1: this timestamp is higher
216 * @throws TmfNumericalException
218 public int compareTo(final TmfTimestamp other
, boolean withinPrecision
) {
220 // If values have the same time scale, perform the comparison
221 if (fScale
== other
.fScale
) {
222 if (withinPrecision
) {
223 if ((fValue
+ fPrecision
) < (other
.fValue
- other
.fPrecision
))
225 if ((fValue
- fPrecision
) > (other
.fValue
+ other
.fPrecision
))
229 return (fValue
== other
.fValue
) ?
0 : (fValue
< other
.fValue
) ?
-1
233 // If values have different time scales, adjust to the finest one and
234 // then compare. If the scaling difference is too large, revert to
235 // some heuristics. Hopefully, nobody will try to compare galactic and
236 // quantic clock events...
237 byte newScale
= (fScale
< other
.fScale
) ? fScale
: other
.fScale
;
239 TmfTimestamp ts1
= this.synchronize(0, newScale
);
240 TmfTimestamp ts2
= other
.synchronize(0, newScale
);
241 return ts1
.compareTo(ts2
, withinPrecision
);
242 } catch (ArithmeticException e
) {
243 if ((fValue
== 0) || (other
.fValue
== 0)) {
244 return (fValue
== other
.fValue
) ?
0
245 : (fValue
< other
.fValue
) ?
-1 : 1;
247 if ((fValue
> 0) && (other
.fValue
> 0)) {
248 return (fScale
< other
.fScale
) ?
-1 : 1;
250 if ((fValue
< 0) && (other
.fValue
< 0)) {
251 return (fScale
> other
.fScale
) ?
-1 : 1;
253 return (fValue
< 0) ?
-1 : 1;
258 public TmfTimestamp
clone() {
259 return new TmfTimestamp(this);
263 public boolean equals(Object other
) {
264 if (other
instanceof TmfTimestamp
)
265 return compareTo((TmfTimestamp
) other
, false) == 0;
266 return super.equals(other
);
270 public String
toString() {
271 return "[TmfTimestamp(" + fValue
+ "," + fScale
+ "," + fPrecision
+ ")]";
This page took 0.035865 seconds and 5 git commands to generate.