1
16
17 package com.zaxxer.hikari.util;
18
19 import static java.util.concurrent.TimeUnit.DAYS;
20 import static java.util.concurrent.TimeUnit.HOURS;
21 import static java.util.concurrent.TimeUnit.MICROSECONDS;
22 import static java.util.concurrent.TimeUnit.MILLISECONDS;
23 import static java.util.concurrent.TimeUnit.MINUTES;
24 import static java.util.concurrent.TimeUnit.NANOSECONDS;
25 import static java.util.concurrent.TimeUnit.SECONDS;
26
27 import java.util.concurrent.TimeUnit;
28
29
35 public interface ClockSource
36 {
37 static ClockSource CLOCK = Factory.create();
38
39
44 static long currentTime() {
45 return CLOCK.currentTime0();
46 }
47
48 long currentTime0();
49
50
57 static long toMillis(long time) {
58 return CLOCK.toMillis0(time);
59 }
60
61 long toMillis0(long time);
62
63
70 static long toNanos(long time) {
71 return CLOCK.toNanos0(time);
72 }
73
74 long toNanos0(long time);
75
76
83 static long elapsedMillis(long startTime) {
84 return CLOCK.elapsedMillis0(startTime);
85 }
86
87 long elapsedMillis0(long startTime);
88
89
97 static long elapsedMillis(long startTime, long endTime) {
98 return CLOCK.elapsedMillis0(startTime, endTime);
99 }
100
101 long elapsedMillis0(long startTime, long endTime);
102
103
110 static long elapsedNanos(long startTime) {
111 return CLOCK.elapsedNanos0(startTime);
112 }
113
114 long elapsedNanos0(long startTime);
115
116
124 static long elapsedNanos(long startTime, long endTime) {
125 return CLOCK.elapsedNanos0(startTime, endTime);
126 }
127
128 long elapsedNanos0(long startTime, long endTime);
129
130
137 static long plusMillis(long time, long millis) {
138 return CLOCK.plusMillis0(time, millis);
139 }
140
141 long plusMillis0(long time, long millis);
142
143
147 static TimeUnit getSourceTimeUnit() {
148 return CLOCK.getSourceTimeUnit0();
149 }
150
151 TimeUnit getSourceTimeUnit0();
152
153
160 static String elapsedDisplayString(long startTime, long endTime) {
161 return CLOCK.elapsedDisplayString0(startTime, endTime);
162 }
163
164 default String elapsedDisplayString0(long startTime, long endTime) {
165 long elapsedNanos = elapsedNanos0(startTime, endTime);
166
167 StringBuilder sb = new StringBuilder(elapsedNanos < 0 ? "-" : "");
168 elapsedNanos = Math.abs(elapsedNanos);
169
170 for (TimeUnit unit : TIMEUNITS_DESCENDING) {
171 long converted = unit.convert(elapsedNanos, NANOSECONDS);
172 if (converted > 0) {
173 sb.append(converted).append(TIMEUNIT_DISPLAY_VALUES[unit.ordinal()]);
174 elapsedNanos -= NANOSECONDS.convert(converted, unit);
175 }
176 }
177
178 return sb.toString();
179 }
180
181 TimeUnit[] TIMEUNITS_DESCENDING = {DAYS, HOURS, MINUTES, SECONDS, MILLISECONDS, MICROSECONDS, NANOSECONDS};
182
183 String[] TIMEUNIT_DISPLAY_VALUES = {"ns", "µs", "ms", "s", "m", "h", "d"};
184
185
188 class Factory
189 {
190 private static ClockSource create() {
191 String os = System.getProperty("os.name");
192 if ("Mac OS X".equals(os)) {
193 return new MillisecondClockSource();
194 }
195
196 return new NanosecondClockSource();
197 }
198 }
199
200 final class MillisecondClockSource implements ClockSource
201 {
202
203 @Override
204 public long currentTime0() {
205 return System.currentTimeMillis();
206 }
207
208
209 @Override
210 public long elapsedMillis0(final long startTime) {
211 return System.currentTimeMillis() - startTime;
212 }
213
214
215 @Override
216 public long elapsedMillis0(final long startTime, final long endTime) {
217 return endTime - startTime;
218 }
219
220
221 @Override
222 public long elapsedNanos0(final long startTime) {
223 return MILLISECONDS.toNanos(System.currentTimeMillis() - startTime);
224 }
225
226
227 @Override
228 public long elapsedNanos0(final long startTime, final long endTime) {
229 return MILLISECONDS.toNanos(endTime - startTime);
230 }
231
232
233 @Override
234 public long toMillis0(final long time) {
235 return time;
236 }
237
238
239 @Override
240 public long toNanos0(final long time) {
241 return MILLISECONDS.toNanos(time);
242 }
243
244
245 @Override
246 public long plusMillis0(final long time, final long millis) {
247 return time + millis;
248 }
249
250
251 @Override
252 public TimeUnit getSourceTimeUnit0() {
253 return MILLISECONDS;
254 }
255 }
256
257 class NanosecondClockSource implements ClockSource
258 {
259
260 @Override
261 public long currentTime0() {
262 return System.nanoTime();
263 }
264
265
266 @Override
267 public long toMillis0(final long time) {
268 return NANOSECONDS.toMillis(time);
269 }
270
271
272 @Override
273 public long toNanos0(final long time) {
274 return time;
275 }
276
277
278 @Override
279 public long elapsedMillis0(final long startTime) {
280 return NANOSECONDS.toMillis(System.nanoTime() - startTime);
281 }
282
283
284 @Override
285 public long elapsedMillis0(final long startTime, final long endTime) {
286 return NANOSECONDS.toMillis(endTime - startTime);
287 }
288
289
290 @Override
291 public long elapsedNanos0(final long startTime) {
292 return System.nanoTime() - startTime;
293 }
294
295
296 @Override
297 public long elapsedNanos0(final long startTime, final long endTime) {
298 return endTime - startTime;
299 }
300
301
302 @Override
303 public long plusMillis0(final long time, final long millis) {
304 return time + MILLISECONDS.toNanos(millis);
305 }
306
307
308 @Override
309 public TimeUnit getSourceTimeUnit0() {
310 return NANOSECONDS;
311 }
312 }
313 }
314