Merge branch 'master' into TmfTrace-new
[deliverable/tracecompass.git] / org.eclipse.linuxtools.tmf.core / src / org / eclipse / linuxtools / tmf / core / event / TmfTimestamp.java
1 /*******************************************************************************
2 * Copyright (c) 2009, 2010, 2012 Ericsson
3 *
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
8 *
9 * Contributors:
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 *******************************************************************************/
14
15 package org.eclipse.linuxtools.tmf.core.event;
16
17
18 /**
19 * A generic timestamp implementation. The timestamp is represented by the
20 * tuple { value, scale, precision }.
21 *
22 * @version 1.0
23 * @author Francois Chouinard
24 */
25 public class TmfTimestamp implements ITmfTimestamp, Cloneable {
26
27 // ------------------------------------------------------------------------
28 // Constants
29 // ------------------------------------------------------------------------
30
31 /**
32 * The beginning of time
33 */
34 public static final ITmfTimestamp BIG_BANG =
35 new TmfTimestamp(Long.MIN_VALUE, Integer.MAX_VALUE, 0);
36
37 /**
38 * The end of time
39 */
40 public static final ITmfTimestamp BIG_CRUNCH =
41 new TmfTimestamp(Long.MAX_VALUE, Integer.MAX_VALUE, 0);
42
43 /**
44 * Zero
45 */
46 public static final ITmfTimestamp ZERO =
47 new TmfTimestamp(0, 0, 0);
48
49 // ------------------------------------------------------------------------
50 // Attributes
51 // ------------------------------------------------------------------------
52
53 /**
54 * The timestamp raw value (mantissa)
55 */
56 private long fValue;
57
58 /**
59 * The timestamp scale (magnitude)
60 */
61 private int fScale;
62
63 /**
64 * The value precision (tolerance)
65 */
66 private int fPrecision;
67
68 // ------------------------------------------------------------------------
69 // Constructors
70 // ------------------------------------------------------------------------
71
72 /**
73 * Default constructor
74 */
75 public TmfTimestamp() {
76 this(0, 0, 0);
77 }
78
79 /**
80 * Simple constructor (scale = precision = 0)
81 *
82 * @param value the timestamp value
83 */
84 public TmfTimestamp(final long value) {
85 this(value, 0, 0);
86 }
87
88 /**
89 * Simple constructor (precision = 0)
90 *
91 * @param value the timestamp value
92 * @param scale the timestamp scale
93 */
94 public TmfTimestamp(final long value, final int scale) {
95 this(value, scale, 0);
96 }
97
98 /**
99 * Full constructor
100 *
101 * @param value the timestamp value
102 * @param scale the timestamp scale
103 * @param precision the timestamp precision
104 */
105 public TmfTimestamp(final long value, final int scale, final int precision) {
106 fValue = value;
107 fScale = scale;
108 fPrecision = Math.abs(precision);
109 }
110
111 /**
112 * Copy constructor
113 *
114 * @param timestamp the timestamp to copy
115 */
116 public TmfTimestamp(final ITmfTimestamp timestamp) {
117 if (timestamp == null) {
118 throw new IllegalArgumentException();
119 }
120 fValue = timestamp.getValue();
121 fScale = timestamp.getScale();
122 fPrecision = timestamp.getPrecision();
123 }
124
125 // ------------------------------------------------------------------------
126 // Setters
127 // ------------------------------------------------------------------------
128
129 protected void setValue(long value, int scale, int precision) {
130 fValue = value;
131 fScale = scale;
132 fPrecision = precision;
133 }
134
135 // ------------------------------------------------------------------------
136 // ITmfTimestamp
137 // ------------------------------------------------------------------------
138
139 /* (non-Javadoc)
140 * @see org.eclipse.linuxtools.tmf.core.event.ITmfTimestamp#getValue()
141 */
142 @Override
143 public long getValue() {
144 return fValue;
145 }
146
147 /* (non-Javadoc)
148 * @see org.eclipse.linuxtools.tmf.core.event.ITmfTimestamp#getScale()
149 */
150 @Override
151 public int getScale() {
152 return fScale;
153 }
154
155 /* (non-Javadoc)
156 * @see org.eclipse.linuxtools.tmf.core.event.ITmfTimestamp#getPrecision()
157 */
158 @Override
159 public int getPrecision() {
160 return fPrecision;
161 }
162
163 private static final long scalingFactors[] = new long[] {
164 1L,
165 10L,
166 100L,
167 1000L,
168 10000L,
169 100000L,
170 1000000L,
171 10000000L,
172 100000000L,
173 1000000000L,
174 10000000000L,
175 100000000000L,
176 1000000000000L,
177 10000000000000L,
178 100000000000000L,
179 1000000000000000L,
180 10000000000000000L,
181 100000000000000000L,
182 1000000000000000000L,
183 };
184
185 /* (non-Javadoc)
186 * @see org.eclipse.linuxtools.tmf.core.event.ITmfTimestamp#normalize(long, int)
187 */
188 @Override
189 public ITmfTimestamp normalize(final long offset, final int scale) {
190
191 long value = fValue;
192 int precision = fPrecision;
193
194 // Handle the trivial case
195 if (fScale == scale && offset == 0) {
196 return new TmfTimestamp(this);
197 }
198
199 // First, scale the timestamp
200 if (fScale != scale) {
201 final int scaleDiff = Math.abs(fScale - scale);
202 if (scaleDiff >= scalingFactors.length) {
203 throw new ArithmeticException("Scaling exception"); //$NON-NLS-1$
204 }
205
206 final long scalingFactor = scalingFactors[scaleDiff];
207 if (scale < fScale) {
208 value *= scalingFactor;
209 precision *= scalingFactor;
210 } else {
211 value /= scalingFactor;
212 precision /= scalingFactor;
213 }
214 }
215
216 // Then, apply the offset
217 if (offset < 0) {
218 value = (value < Long.MIN_VALUE - offset) ? Long.MIN_VALUE : value + offset;
219 } else {
220 value = (value > Long.MAX_VALUE - offset) ? Long.MAX_VALUE : value + offset;
221 }
222
223 return new TmfTimestamp(value, scale, precision);
224 }
225
226 /* (non-Javadoc)
227 * @see org.eclipse.linuxtools.tmf.core.event.ITmfTimestamp#compareTo(org.eclipse.linuxtools.tmf.core.event.ITmfTimestamp, boolean)
228 */
229 @Override
230 public int compareTo(final ITmfTimestamp ts, final boolean withinPrecision) {
231
232 // Check the corner cases (we can't use equals() because it uses compareTo()...)
233 if (ts == null) {
234 return 1;
235 }
236 if (this == ts || (fValue == ts.getValue() && fScale == ts.getScale())) {
237 return 0;
238 }
239 if ((fValue == BIG_BANG.getValue() && fScale == BIG_BANG.getScale()) || (ts.getValue() == BIG_CRUNCH.getValue() && ts.getScale() == BIG_CRUNCH.getScale())) {
240 return -1;
241 }
242 if ((fValue == BIG_CRUNCH.getValue() && fScale == BIG_CRUNCH.getScale()) || (ts.getValue() == BIG_BANG.getValue() && ts.getScale() == BIG_BANG.getScale())) {
243 return 1;
244 }
245
246 try {
247 final ITmfTimestamp nts = ts.normalize(0, fScale);
248 final long delta = fValue - nts.getValue();
249 if ((delta == 0) || (withinPrecision && (Math.abs(delta) <= (fPrecision + nts.getPrecision())))) {
250 return 0;
251 }
252 return (delta > 0) ? 1 : -1;
253 }
254 catch (final ArithmeticException e) {
255 // Scaling error. We can figure it out nonetheless.
256
257 // First, look at the sign of the mantissa
258 final long value = ts.getValue();
259 if (fValue == 0 && value == 0) {
260 return 0;
261 }
262 if (fValue < 0 && value >= 0) {
263 return -1;
264 }
265 if (fValue >= 0 && value < 0) {
266 return 1;
267 }
268
269 // Otherwise, just compare the scales
270 final int scale = ts.getScale();
271 return (fScale > scale) ? (fValue >= 0) ? 1 : -1 : (fValue >= 0) ? -1 : 1;
272 }
273 }
274
275 /* (non-Javadoc)
276 * @see org.eclipse.linuxtools.tmf.core.event.ITmfTimestamp#getDelta(org.eclipse.linuxtools.tmf.core.event.ITmfTimestamp)
277 */
278 @Override
279 public ITmfTimestamp getDelta(final ITmfTimestamp ts) {
280 final ITmfTimestamp nts = ts.normalize(0, fScale);
281 final long value = fValue - nts.getValue();
282 return new TmfTimestamp(value, fScale, fPrecision + nts.getPrecision());
283 }
284
285 // ------------------------------------------------------------------------
286 // Cloneable
287 // ------------------------------------------------------------------------
288
289 /* (non-Javadoc)
290 * @see java.lang.Object#clone()
291 */
292 @Override
293 public TmfTimestamp clone() {
294 TmfTimestamp clone = null;
295 try {
296 clone = (TmfTimestamp) super.clone();
297 clone.fValue = fValue;
298 clone.fScale = fScale;
299 clone.fPrecision = fPrecision;
300 } catch (final CloneNotSupportedException e) {
301 }
302 return clone;
303 }
304
305 // ------------------------------------------------------------------------
306 // Comparable
307 // ------------------------------------------------------------------------
308
309 /* (non-Javadoc)
310 * @see org.eclipse.linuxtools.tmf.core.event.ITmfTimestamp#compareTo(org.eclipse.linuxtools.tmf.core.event.ITmfTimestamp)
311 */
312 @Override
313 public int compareTo(final ITmfTimestamp ts) {
314 return compareTo(ts, false);
315 }
316
317 // ------------------------------------------------------------------------
318 // Object
319 // ------------------------------------------------------------------------
320
321 /* (non-Javadoc)
322 * @see java.lang.Object#hashCode()
323 */
324 @Override
325 public int hashCode() {
326 final int prime = 31;
327 int result = 1;
328 result = prime * result + (int) (fValue ^ (fValue >>> 32));
329 result = prime * result + fScale;
330 result = prime * result + fPrecision;
331 return result;
332 }
333
334 /* (non-Javadoc)
335 * @see java.lang.Object#equals(java.lang.Object)
336 */
337 @Override
338 public boolean equals(final Object other) {
339 if (this == other) {
340 return true;
341 }
342 if (other == null) {
343 return false;
344 }
345 if (!(other instanceof TmfTimestamp)) {
346 return false;
347 }
348 final TmfTimestamp ts = (TmfTimestamp) other;
349 return compareTo(ts, false) == 0;
350 }
351
352 /* (non-Javadoc)
353 * @see java.lang.Object#toString()
354 */
355 @Override
356 @SuppressWarnings("nls")
357 public String toString() {
358 return "TmfTimestamp [fValue=" + fValue + ", fScale=" + fScale + ", fPrecision=" + fPrecision + "]";
359 }
360
361 }
This page took 0.051329 seconds and 6 git commands to generate.