Author: reschke
Date: Wed Apr  5 13:27:11 2017
New Revision: 1790245

URL: http://svn.apache.org/viewvc?rev=1790245&view=rev
Log:
OAK-6020: add a Guava Stopwatch like duration formatter

Added:
    
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/util/TimeDurationFormatter.java
   (with props)
    
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/util/TimeDurationFormatterTest.java
   (with props)

Added: 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/util/TimeDurationFormatter.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/util/TimeDurationFormatter.java?rev=1790245&view=auto
==============================================================================
--- 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/util/TimeDurationFormatter.java
 (added)
+++ 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/util/TimeDurationFormatter.java
 Wed Apr  5 13:27:11 2017
@@ -0,0 +1,106 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.jackrabbit.oak.util;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+
+import com.google.common.base.Stopwatch;
+import com.google.common.collect.Maps;
+
+/**
+ * Format a time duration as human-readable string, inspired by
+ * {@link Stopwatch#toString()}.
+ */
+public class TimeDurationFormatter {
+
+    private final int threshold;
+    private final boolean allowNonAscii;
+    private final Locale locale;
+
+    private static TimeUnit[] UNITS = { TimeUnit.DAYS, TimeUnit.HOURS, 
TimeUnit.MINUTES, TimeUnit.SECONDS, TimeUnit.MILLISECONDS,
+            TimeUnit.MICROSECONDS, TimeUnit.NANOSECONDS };
+    private static Map<TimeUnit, String> DISPLAYUNIT;
+    private static Map<TimeUnit, String> DISPLAYUNIT_ASCII;
+
+    static {
+        HashMap<TimeUnit, String> t = Maps.newHashMap();
+        t.put(TimeUnit.DAYS, "d");
+        t.put(TimeUnit.HOURS, "h");
+        t.put(TimeUnit.MINUTES, "min");
+        t.put(TimeUnit.SECONDS, "s");
+        t.put(TimeUnit.MILLISECONDS, "ms");
+        t.put(TimeUnit.MICROSECONDS, "us");
+        t.put(TimeUnit.NANOSECONDS, "ns");
+        DISPLAYUNIT_ASCII = Collections.unmodifiableMap(t);
+        t = Maps.newHashMap(t);
+        // Unicode "MICRO SIGN"
+        t.put(TimeUnit.MICROSECONDS, "\u00b5s");
+        DISPLAYUNIT = Collections.unmodifiableMap(t);
+    }
+
+    private static TimeDurationFormatter FOR_LOGGING = new 
TimeDurationFormatter(Locale.US, 2, false);
+
+    /**
+     * Default formatter suitable for logging (ASCII-only)
+     */
+    public static TimeDurationFormatter forLogging() {
+        return FOR_LOGGING;
+    }
+
+    /**
+     * @param local
+     *            local for formatting (affects the decimal point)
+     * @param threshold
+     *            integral value that needs to be exceeded to switch to a
+     *            certain time unit for display (e.g., specify {@code 2} to
+     *            switch to 'days' when the elapsed time is two or more days.
+     * @param allowNonAscii
+     *            set to {@code true} if the display unit can use the non-ASCII
+     *            "micro" Unicode character
+     */
+    public TimeDurationFormatter(Locale locale, int threshold, boolean 
allowNonAscii) {
+        this.locale = locale;
+        this.threshold = threshold;
+        this.allowNonAscii = allowNonAscii;
+    }
+
+    /**
+     * Format the specified duration
+     * @param amount number of time units
+     * @param unit time unit
+     */
+    public String format(long amount, TimeUnit unit) {
+        long nanos = unit.toNanos(amount);
+
+        TimeUnit outputUnit = TimeUnit.NANOSECONDS;
+        for (TimeUnit u : UNITS) {
+            if (u.convert(nanos, TimeUnit.NANOSECONDS) >= this.threshold) {
+                outputUnit = u;
+                break;
+            }
+        }
+
+        double convertedToUnit = ((double) nanos) / 
(TimeUnit.NANOSECONDS.convert(1, outputUnit));
+
+        return String.format(this.locale, "%.4g %s", convertedToUnit,
+                this.allowNonAscii ? DISPLAYUNIT.get(outputUnit) : 
DISPLAYUNIT_ASCII.get(outputUnit));
+    }
+}

Propchange: 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/util/TimeDurationFormatter.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/util/TimeDurationFormatter.java
------------------------------------------------------------------------------
    svn:executable = *

Added: 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/util/TimeDurationFormatterTest.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/util/TimeDurationFormatterTest.java?rev=1790245&view=auto
==============================================================================
--- 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/util/TimeDurationFormatterTest.java
 (added)
+++ 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/util/TimeDurationFormatterTest.java
 Wed Apr  5 13:27:11 2017
@@ -0,0 +1,53 @@
+package org.apache.jackrabbit.oak.util;
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.Locale;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.jackrabbit.oak.util.TimeDurationFormatter;
+import org.junit.Test;
+
+public class TimeDurationFormatterTest {
+
+    private TimeDurationFormatter df = TimeDurationFormatter.forLogging();
+    private TimeDurationFormatter dfu = new 
TimeDurationFormatter(Locale.GERMAN, 1, true);
+
+    @Test
+    public void defaultFormatter() {
+        assertEquals("2.000 d", df.format(2, TimeUnit.DAYS));
+        assertEquals("24.00 h", df.format(1, TimeUnit.DAYS));
+        assertEquals("10.50 d", df.format(24 * 10 + 12, TimeUnit.HOURS));
+        assertEquals("2.500 h", df.format(150, TimeUnit.MINUTES));
+        assertEquals("10.00 min", df.format(10, TimeUnit.MINUTES));
+        assertEquals("1234 us", df.format(1234, TimeUnit.MICROSECONDS));
+        assertEquals("1234 ns", df.format(1234, TimeUnit.NANOSECONDS));
+    }
+
+    @Test
+    public void uniFormatterWithOneThreshold() {
+        assertEquals("2,000 d", dfu.format(2, TimeUnit.DAYS));
+        assertEquals("1,000 d", dfu.format(1, TimeUnit.DAYS));
+        assertEquals("10,50 d", dfu.format(24 * 10 + 12, TimeUnit.HOURS));
+        assertEquals("2,500 h", dfu.format(150, TimeUnit.MINUTES));
+        assertEquals("10,00 min", dfu.format(10, TimeUnit.MINUTES));
+        assertEquals("1,234 ms", dfu.format(1234, TimeUnit.MICROSECONDS));
+        assertEquals("1,234 \u00b5s", dfu.format(1234, TimeUnit.NANOSECONDS));
+    }
+}

Propchange: 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/util/TimeDurationFormatterTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/util/TimeDurationFormatterTest.java
------------------------------------------------------------------------------
    svn:executable = *


Reply via email to