1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.spf4j.base;
17
18 import com.google.common.annotations.Beta;
19 import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
20 import gnu.trove.iterator.TLongIterator;
21 import gnu.trove.list.array.TLongArrayList;
22 import java.util.function.LongSupplier;
23 import javax.annotation.Nonnull;
24 import org.slf4j.Logger;
25 import org.slf4j.LoggerFactory;
26
27
28
29
30 @Beta
31 public final class TestTimeSource implements LongSupplier {
32
33 private static final Logger LOG = LoggerFactory.getLogger(TestTimeSource.class);
34
35 public static final TLongIterator SYSTEM_NANO_TIME_STREAM = new TLongIterator() {
36 @Override
37 public long next() {
38 return System.nanoTime();
39 }
40
41 @Override
42 public boolean hasNext() {
43 return true;
44 }
45
46 @Override
47 public void remove() {
48 throw new UnsupportedOperationException();
49 }
50 };
51
52 private static volatile TLongIterator timeStream = SYSTEM_NANO_TIME_STREAM;
53
54 public static void clear() {
55 timeStream = SYSTEM_NANO_TIME_STREAM;
56 }
57
58 public static void setTimeStream(final TLongIterator stream) {
59 timeStream = stream;
60 }
61
62 public static void setTimeStream(final long... times) {
63 timeStream = new TLongArrayList(times).iterator();
64 }
65
66 public static long freezeTime() {
67 long nanoTime = TimeSource.nanoTime();
68 setTimeStream(new TLongIterator() {
69 @Override
70 public long next() {
71 return nanoTime;
72 }
73
74 @Override
75 public boolean hasNext() {
76 return true;
77 }
78
79 @Override
80 public void remove() {
81 throw new UnsupportedOperationException();
82 }
83 });
84 return nanoTime;
85 }
86
87
88 @Override
89 @Nonnull
90 @SuppressFBWarnings("CLI_CONSTANT_LIST_INDEX")
91 public long getAsLong() {
92 long nextTime;
93 if (timeStream.hasNext()) {
94 nextTime = timeStream.next();
95 } else {
96 StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
97 throw new AssertionError("End of time reached at "
98 + (stackTrace.length > 2 ? stackTrace[2] : "unknown"));
99 }
100 if (LOG.isTraceEnabled()) {
101 StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
102 LOG.trace("nanoTime = {} at {}", nextTime, stackTrace.length > 2 ? stackTrace[2] : "unknown");
103 }
104 return nextTime;
105 }
106
107 }