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