This is an automated email from the ASF dual-hosted git repository.
reschke pushed a commit to branch OAK-11618
in repository https://gitbox.apache.org/repos/asf/jackrabbit-oak.git
The following commit(s) were added to refs/heads/OAK-11618 by this push:
new ccfa147f27 OAK-11618: Remove usage of Guava Stopwatch - work in
progress
ccfa147f27 is described below
commit ccfa147f27e4f4ffb0ecd782cf6710cbdbf9ef32
Author: Julian Reschke <[email protected]>
AuthorDate: Wed Apr 9 09:31:06 2025 +0100
OAK-11618: Remove usage of Guava Stopwatch - work in progress
---
.../apache/jackrabbit/oak/commons/StopWatch.java | 159 +++++++++++++++++++--
1 file changed, 149 insertions(+), 10 deletions(-)
diff --git
a/oak-commons/src/test/java/org/apache/jackrabbit/oak/commons/StopWatch.java
b/oak-commons/src/test/java/org/apache/jackrabbit/oak/commons/StopWatch.java
index 7677b33c56..f6519b80f1 100644
--- a/oak-commons/src/test/java/org/apache/jackrabbit/oak/commons/StopWatch.java
+++ b/oak-commons/src/test/java/org/apache/jackrabbit/oak/commons/StopWatch.java
@@ -16,18 +16,162 @@
*/
package org.apache.jackrabbit.oak.commons;
+import org.apache.jackrabbit.oak.commons.conditions.Validate;
+
+import java.time.Clock;
+import java.time.Duration;
+import java.util.concurrent.TimeUnit;
+import java.util.function.Supplier;
+
/**
- * A utility class to time an operation.
+ * A stop watch based either on a {@link Supplier} of nanoseconds, or a {@link
java.time.Clock}.
+ * <p>
+ * The accuracy of measurements depends on the precision of the time source,
which likely depends on platform and
+ * configuration.
+ * <p>
+ * Inspired by Guava's.
*/
public class StopWatch {
private static final long NANOS_PER_SECOND = 1000 * 1000 * 1000;
- private long start = System.nanoTime();
- private long lastLog = start;
+ private long startTime;
+ private long accumulated;
+ private boolean running;
+ private final Supplier<Long> ticker;
+
+ private StopWatch(Supplier<Long> ticker) {
+ this.ticker = ticker;
+ this.accumulated = 0L;
+ this.startTime = ticker.get();
+ this.running = false;
+ }
+
+ /**
+ * @return a running stop watch, using {@link System#nanoTime()}.
+ */
+ public static StopWatch createStarted() {
+ return new StopWatch(StopWatch::tick).start();
+ }
+
+ /**
+ * @return a running stop watch, using the supplied provider.
+ */
+ public static StopWatch createStarted(Supplier<Long> ticker) {
+ return new StopWatch(ticker).start();
+ }
+
+ /**
+ * @return a running stop watch, using the supplied clock.
+ * <p>
+ * Note that only {@link Clock#millis()} will be used, thus the watch will
have ms precision at most.
+ */
+ public static StopWatch createStarted(Clock clock) {
+ return new StopWatch(clockAsLongSupplier(clock)).start();
+ }
+
+ /**
+ * @return a non-running stop watch, using {@link System#nanoTime()}.
+ */
+ public static StopWatch createUnstarted() {
+ return new StopWatch(StopWatch::tick);
+ }
+
+ /**
+ * creates a running stop watch, using {@link System#nanoTime()}.
+ * <p>
+ * @deprecated use factory methods, such as {@link #createStarted()}
+ */
+ @Deprecated
+ public StopWatch() {
+ this.ticker = StopWatch::tick;
+ createStarted();
+ }
+
+ /**
+ * Starts the stop watch, will fail when running.
+ * @return the stop watch
+ */
+ public StopWatch start() {
+ Validate.checkState(!this.running, "StopWatch already running.");
+ this.startTime = this.ticker.get();
+ this.running = true;
+ return this;
+ }
+
+ /**
+ * Stops the stop watch, will fail when not running.
+ * @return the stop watch
+ */
+ public StopWatch stop() {
+ Validate.checkState(this.running, "StopWatch not running.");
+ this.accumulated += elapsedNanos();
+ this.startTime = 0L;
+ this.running = false;
+ return this;
+ }
+
+ /**
+ * Resets the stop watch, and puts it into stopped state.
+ * @return the stop watch
+ */
+ public StopWatch reset() {
+ this.accumulated = 0L;
+ this.startTime = 0;
+ this.running = false;
+ return this;
+ }
+
+ /**
+ * @return whether the stop watch is running
+ */
+ public boolean isRunning() {
+ return this.running;
+ }
+
+ /**
+ * Gets elapsed time using the supplied {@link TimeUnit}.
+ * @param timeunit time unit
+ * @return elapsed time in the specified unit
+ */
+ public long elapsed(TimeUnit timeunit) {
+ return timeunit.convert(elapsedNanos(), TimeUnit.NANOSECONDS);
+ }
+
+ /**
+ * Gets elapsed time as {@link Duration}.
+ * @return elapsed time
+ */
+ public Duration elapsed() {
+ return Duration.ofMillis(elapsedNanos());
+ }
+
+ @Override
+ public String toString() {
+ return java.time.Duration.ofNanos(elapsedNanos()).toString();
+ }
+
+ // private parts
+
+ private long elapsedNanos() {
+ long delta = this.running ? this.ticker.get() - this.startTime : 0;
+ return this.accumulated + delta;
+ }
+
+ private static long tick() {
+ return System.nanoTime();
+ }
+
+ private static Supplier<Long> clockAsLongSupplier(java.time.Clock clock) {
+ return () -> TimeUnit.MILLISECONDS.toNanos(clock.millis());
+ }
+
+ // "legacy methods" (pre OAK-11620)
+
+ private long lastLog = startTime;
public long time() {
- return System.nanoTime() - start;
+ return ticker.get() - startTime;
}
public String seconds() {
@@ -51,16 +195,11 @@ public class StopWatch {
* @return true once every 5 seconds
*/
public boolean log() {
- long t = System.nanoTime();
+ long t = ticker.get();
if (t - lastLog > 5 * NANOS_PER_SECOND) {
lastLog = t;
return true;
}
return false;
}
-
- public void reset() {
- start = System.nanoTime();
- }
-
}