a84447f52caf8641fdc60855a436a3e544b90090
[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 * <b><u>TmfTimestamp</u></b>
19 * <p>
20 * A generic implementation of ITmfTimestamp.
21 */
22 public class TmfTimestamp implements ITmfTimestamp {
23
24 // ------------------------------------------------------------------------
25 // Constants
26 // ------------------------------------------------------------------------
27
28 // The beginning and end of time
29 public static final TmfTimestamp BigBang = new TmfTimestamp(Long.MIN_VALUE, Integer.MAX_VALUE, 0);
30 public static final TmfTimestamp BigCrunch = new TmfTimestamp(Long.MAX_VALUE, Integer.MAX_VALUE, 0);
31 public static final TmfTimestamp Zero = new TmfTimestamp(0, 0, 0);
32
33 // ------------------------------------------------------------------------
34 // Attributes
35 // ------------------------------------------------------------------------
36
37 protected long fValue; // The timestamp raw value
38 protected int fScale; // The time scale
39 protected int fPrecision; // The value precision (tolerance)
40
41 // ------------------------------------------------------------------------
42 // Constructors
43 // ------------------------------------------------------------------------
44
45 /**
46 * Default constructor
47 */
48 public TmfTimestamp() {
49 this(0, 0, 0);
50 }
51
52 /**
53 * Simple constructor (scale = precision = 0)
54 *
55 * @param value the timestamp value
56 */
57 public TmfTimestamp(long value) {
58 this(value, 0, 0);
59 }
60
61 /**
62 * Simple constructor (precision = 0)
63 *
64 * @param value the timestamp value
65 * @param scale the timestamp scale
66 */
67 public TmfTimestamp(long value, int scale) {
68 this(value, scale, 0);
69 }
70
71 /**
72 * Full constructor
73 *
74 * @param value the timestamp value
75 * @param scale the timestamp scale
76 * @param precision the timestamp precision
77 */
78 public TmfTimestamp(long value, int scale, int precision) {
79 fValue = value;
80 fScale = scale;
81 fPrecision = Math.abs(precision);
82 }
83
84 /**
85 * Copy constructor
86 *
87 * @param timestamp the timestamp to copy
88 */
89 public TmfTimestamp(ITmfTimestamp timestamp) {
90 if (timestamp == null)
91 throw new IllegalArgumentException();
92 fValue = timestamp.getValue();
93 fScale = timestamp.getScale();
94 fPrecision = timestamp.getPrecision();
95 }
96
97 // ------------------------------------------------------------------------
98 // ITmfTimestamp
99 // ------------------------------------------------------------------------
100
101 public long getValue() {
102 return fValue;
103 }
104
105 public int getScale() {
106 return fScale;
107 }
108
109 public int getPrecision() {
110 return fPrecision;
111 }
112
113 private static final long scalingFactors[] = new long[] {
114 1L,
115 10L,
116 100L,
117 1000L,
118 10000L,
119 100000L,
120 1000000L,
121 10000000L,
122 100000000L,
123 1000000000L,
124 10000000000L,
125 100000000000L,
126 1000000000000L,
127 10000000000000L,
128 100000000000000L,
129 1000000000000000L,
130 10000000000000000L,
131 100000000000000000L,
132 1000000000000000000L,
133 };
134
135 public ITmfTimestamp normalize(long offset, int scale) throws ArithmeticException {
136
137 long value = fValue;
138 int precision = fPrecision;
139
140 // Handle the trivial case
141 if (fScale == scale && offset == 0)
142 return new TmfTimestamp(this);
143
144 // First, scale the timestamp
145 if (fScale != scale) {
146 int scaleDiff = Math.abs(fScale - scale);
147 if (scaleDiff >= scalingFactors.length) {
148 throw new ArithmeticException("Scaling exception"); //$NON-NLS-1$
149 }
150
151 long scalingFactor = scalingFactors[scaleDiff];
152 if (scale < fScale) {
153 value *= scalingFactor;
154 precision *= scalingFactor;
155 } else {
156 value /= scalingFactor;
157 precision /= scalingFactor;
158 }
159 }
160
161 // Then, apply the offset
162 if (offset < 0) {
163 value = (value < Long.MIN_VALUE - offset) ? Long.MIN_VALUE : value + offset;
164 } else {
165 value = (value > Long.MAX_VALUE - offset) ? Long.MAX_VALUE : value + offset;
166 }
167
168 return new TmfTimestamp(value, scale, precision);
169 }
170
171 public int compareTo(ITmfTimestamp ts, boolean withinPrecision) {
172
173 // Check the corner cases (we can't use equals() because it uses compareTo()...)
174 if (this == ts || (fValue == ts.getValue() && fScale == ts.getScale()))
175 return 0;
176 if ((fValue == BigBang.getValue() && fScale == BigBang.getScale()) || (ts.getValue() == BigCrunch.getValue() && ts.getScale() == BigCrunch.getScale()))
177 return -1;
178 if ((fValue == BigCrunch.getValue() && fScale == BigCrunch.getScale()) || (ts.getValue() == BigBang.getValue() && ts.getScale() == BigBang.getScale()))
179 return 1;
180
181 try {
182 ITmfTimestamp nts = ts.normalize(0, fScale);
183 long delta = fValue - nts.getValue();
184 if ((delta == 0) || (withinPrecision && (Math.abs(delta) <= (fPrecision + nts.getPrecision())))) {
185 return 0;
186 }
187 return (delta > 0) ? 1 : -1;
188 }
189 catch (ArithmeticException e) {
190 // Scaling error. We can figure it out nonetheless.
191
192 // First, look at the sign of the mantissa
193 long value = ts.getValue();
194 if (fValue == 0 && value == 0)
195 return 0;
196 if (fValue < 0 && value >= 0)
197 return -1;
198 if (fValue >= 0 && value < 0)
199 return 1;
200
201 // Otherwise, just compare the scales
202 int scale = ts.getScale();
203 return (fScale > scale) ? (fValue > 0) ? 1 : -1 : (fValue > 0) ? -1 : 1;
204 }
205 }
206
207 @Override
208 public ITmfTimestamp getDelta(ITmfTimestamp ts) {
209 ITmfTimestamp nts = ts.normalize(0, fScale);
210 long value = fValue - nts.getValue();
211 return new TmfTimestamp(value, fScale, fPrecision + nts.getPrecision());
212 }
213
214 // ------------------------------------------------------------------------
215 // Cloneable
216 // ------------------------------------------------------------------------
217
218 @Override
219 public ITmfTimestamp clone() {
220 TmfTimestamp clone = null;
221 try {
222 clone = (TmfTimestamp) super.clone();
223 clone.fValue = fValue;
224 clone.fScale = fScale;
225 clone.fPrecision = fPrecision;
226 } catch (CloneNotSupportedException e) {
227 }
228 return clone;
229 }
230
231 // ------------------------------------------------------------------------
232 // Comparable
233 // ------------------------------------------------------------------------
234
235 @Override
236 public int compareTo(ITmfTimestamp ts) {
237 return compareTo(ts, false);
238 }
239
240 // ------------------------------------------------------------------------
241 // Object
242 // ------------------------------------------------------------------------
243
244 @Override
245 public int hashCode() {
246 final int prime = 31;
247 int result = 1;
248 result = prime * result + (int) (fValue ^ (fValue >>> 32));
249 result = prime * result + fScale;
250 result = prime * result + fPrecision;
251 return result;
252 }
253
254 @Override
255 public boolean equals(Object other) {
256 if (this == other)
257 return true;
258 if (other == null)
259 return false;
260 if (!(other instanceof TmfTimestamp))
261 return false;
262 TmfTimestamp ts = (TmfTimestamp) other;
263 return compareTo(ts, false) == 0;
264 }
265
266 @Override
267 @SuppressWarnings("nls")
268 public String toString() {
269 return "TmfTimestamp [fValue=" + fValue + ", fScale=" + fScale + ", fPrecision=" + fPrecision + "]";
270 }
271
272 }
This page took 0.036519 seconds and 4 git commands to generate.