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();
-    }
-
 }

Reply via email to