Ver Fonte

change: FormatUnit to FormatNumber
change: FormatNumber#format to #group
new: FormatNumber#asEngineer

Ranides Atterwim há 10 anos atrás
pai
commit
b542ea0ef8

+ 2 - 2
assira/src/main/java/net/ranides/assira/system/RuntimeUtils.java

@@ -10,7 +10,7 @@ import java.security.AccessController;
 import java.security.PrivilegedAction;
 import java.util.LinkedList;
 import java.util.List;
-import net.ranides.assira.text.FormatUnit;
+import net.ranides.assira.text.FormatNumber;
 import net.ranides.assira.trace.LoggerUtils;
 import net.ranides.assira.trace.StackInspector;
 
@@ -66,7 +66,7 @@ public final class RuntimeUtils {
         catch(final OutOfMemoryError e) {
             // at this point all SoftReferences have been released - GUARANTEED
             long alloc = Runtime.getRuntime().totalMemory() - prev;
-            LOGGER.debug("Forced OutOfMemoryError by allocation {} bytes", FormatUnit.format(alloc));
+            LOGGER.debug("Forced OutOfMemoryError by allocation {} bytes", FormatNumber.group(alloc));
             Runtime.getRuntime().gc();
             // at this point we should use minimal amount of memory
             return prev - getMemoryUse();

+ 138 - 0
assira/src/main/java/net/ranides/assira/text/FormatNumber.java

@@ -0,0 +1,138 @@
+/*
+ * @author Ranides Atterwim <ranides@gmail.com>
+ * @copyright Ranides Atterwim
+ * @license WTFPL
+ * @url http://ranides.net/projects/assira
+ */
+package net.ranides.assira.text;
+
+import java.util.Locale;
+
+/**
+ *
+ * @author ranides
+ */
+public final class FormatNumber {
+    
+    private FormatNumber() {
+        /* utility class */ 
+    }
+    
+    public static class UnitPrefix {
+        
+        private final double v;
+        private final String u;
+
+        UnitPrefix(double v, String u) {
+            this.v = v;
+            this.u = u;
+        }
+
+        public double value() {
+            return v;
+        }
+
+        public String text() {
+            return u;
+        }
+        
+        StringBuilder append(StringBuilder target, int padding, int precision, double value) {
+            return target.append(
+                String.format(Locale.ENGLISH, 
+                    String.format("%%%d.%df%s", padding, precision, text()), value/value())
+            );
+        }
+        
+    }
+    
+    public static final UnitPrefix[] METRIC_PREFIX = new UnitPrefix[]{
+        new UnitPrefix(Math.pow(1000, 8),"Y"),
+        new UnitPrefix(Math.pow(1000, 7),"Z"),
+        new UnitPrefix(Math.pow(1000, 6),"E"),
+        new UnitPrefix(Math.pow(1000, 5),"P"),
+        new UnitPrefix(Math.pow(1000, 4),"T"),
+        new UnitPrefix(Math.pow(1000, 3),"G"),
+        new UnitPrefix(Math.pow(1000, 2),"M"),
+        new UnitPrefix(Math.pow(1000, 1),"k"),
+        new UnitPrefix(Math.pow(1000, 0),""),
+        new UnitPrefix(Math.pow(1000, -1),"m"),
+        new UnitPrefix(Math.pow(1000, -2),"μ"),
+        new UnitPrefix(Math.pow(1000, -3),"n"),
+        new UnitPrefix(Math.pow(1000, -4),"p"),
+        new UnitPrefix(Math.pow(1000, -5),"f"),
+        new UnitPrefix(Math.pow(1000, -6),"a"),
+        new UnitPrefix(Math.pow(1000, -7),"z"),
+        new UnitPrefix(Math.pow(1000, -8),"y")
+    };
+    
+    public static final UnitPrefix[] METRIC_EXP = new UnitPrefix[]{
+        new UnitPrefix(Math.pow(1000, 8),"E24"),
+        new UnitPrefix(Math.pow(1000, 7),"E21"),
+        new UnitPrefix(Math.pow(1000, 6),"E18"),
+        new UnitPrefix(Math.pow(1000, 5),"E15"),
+        new UnitPrefix(Math.pow(1000, 4),"E12"),
+        new UnitPrefix(Math.pow(1000, 3),"E9"),
+        new UnitPrefix(Math.pow(1000, 2),"E6"),
+        new UnitPrefix(Math.pow(1000, 1),"E3"),
+        new UnitPrefix(Math.pow(1000, 0),"E0"),
+        new UnitPrefix(Math.pow(1000, -1),"E-3"),
+        new UnitPrefix(Math.pow(1000, -2),"E-6"),
+        new UnitPrefix(Math.pow(1000, -3),"E-9"),
+        new UnitPrefix(Math.pow(1000, -4),"E-12"),
+        new UnitPrefix(Math.pow(1000, -5),"E-15"),
+        new UnitPrefix(Math.pow(1000, -6),"E-18"),
+        new UnitPrefix(Math.pow(1000, -7),"E-21"),
+        new UnitPrefix(Math.pow(1000, -8),"E-24")
+    };
+    
+    public static final UnitPrefix[] BYTE_PREFIX = new UnitPrefix[]{
+        new UnitPrefix(Math.pow(1024, 8),"Y"),
+        new UnitPrefix(Math.pow(1024, 7),"Z"),
+        new UnitPrefix(Math.pow(1024, 6),"E"),
+        new UnitPrefix(Math.pow(1024, 5),"P"),
+        new UnitPrefix(Math.pow(1024, 4),"T"),
+        new UnitPrefix(Math.pow(1024, 3),"G"),
+        new UnitPrefix(Math.pow(1024, 2),"M"),
+        new UnitPrefix(Math.pow(1024, 1),"K"),
+        new UnitPrefix(Math.pow(1024, 0),""),
+    };
+ 
+    public static String asEngineer(int padding, int precision, UnitPrefix[] units, double value) {
+        return asEngineer(new StringBuilder(), padding, precision, units, value).toString();
+    }
+
+    public static StringBuilder asEngineer(StringBuilder target, int padding, int precision, UnitPrefix[] units, double value) {
+        if(value < 0) {
+            target.append('-');
+            return asEngineer(target, padding, precision, units, -value);
+        }
+        UnitPrefix c = units[0];
+        for (UnitPrefix u : units) {
+            c = u;
+            if (value > c.value()) {
+                break;
+            }
+        }
+        return c.append(target, padding, precision, value);
+    }
+    
+    public static String group(int value) {
+        return group(Integer.toString(value, 10), "'");
+    }
+
+    public static String group(long value) {
+        return group(Long.toString(value, 10), "'");
+    }
+    
+    private static String group(String text, String separator) {
+        StringBuilder ret = new StringBuilder(text.length() + (text.length()/3 + 1) * separator.length());
+        for(int i=0, n=text.length()-1; i<=n; i++) {
+            ret.append(text.charAt(i));
+            if( n>i && ((n-i)%3 == 0) ) {
+                ret.append(separator);
+            }
+        }
+        return ret.toString();
+    }
+
+}

+ 0 - 118
assira/src/main/java/net/ranides/assira/text/FormatUnit.java

@@ -1,118 +0,0 @@
-/*
- * @author Ranides Atterwim <ranides@gmail.com>
- * @copyright Ranides Atterwim
- * @license WTFPL
- * @url http://ranides.net/projects/assira
- */
-package net.ranides.assira.text;
-
-import java.util.Map;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-import net.ranides.assira.collection.maps.HashMap;
-
-/**
- *
- * @author ranides
- */
-public final class FormatUnit {
-
-    private static final Map<String, Long> PREFIX = new HashMap<>(
-        new String[]{"K", "M", "G", "T", "k", "m", "g", "t"}, 
-        new Long[]{
-            1024L, 1024L * 1024L, 1024L * 1024L * 1024L, 1024L * 1024L * 1024L * 1024L,
-            1000L, 1000L * 1000L, 1000L * 1000L * 1000L, 1000L * 1000L * 1000L * 1000L
-    });
-
-    private static final Pattern PATTERN_BYTES = Pattern.compile("([0-9\\. ]+)([KMGTkmgt])?([Bb])?");
-
-    private FormatUnit() { /* utility class */ }
-
-    public static int asInt(String value, int ddefault) {
-        try {
-            return asInt(value);
-        } catch(NumberFormatException _e) {
-            return ddefault;
-        }
-    }
-
-    public static int asInt(String value) {
-        Matcher hit = PATTERN_BYTES.matcher(value);
-        if(hit.matches()) {
-            return (int)asLong(hit);
-        } else {
-            return Integer.parseInt( value.trim() );
-        }
-    }
-    
-    public static long asLong(String value, long ddefault) {
-        try {
-            return asLong(value);
-        } catch(NumberFormatException _e) {
-            return ddefault;
-        }
-    }
-    
-    public static long asLong(String value) {
-        Matcher hit = PATTERN_BYTES.matcher(value);
-        if(hit.matches()) {
-            return asLong(hit);
-        } else {
-            return Long.parseLong( value.trim() );
-        }
-    }
-
-    public static double asDouble(String value) {
-        Matcher hit = PATTERN_BYTES.matcher(value);
-        if(hit.matches()) {
-            return asDouble(hit);
-        } else {
-            return Double.parseDouble( value.trim() );
-        }
-    }
-    
-    public static double asDouble(String value, double ddefault) {
-        try {
-            return asDouble(value);
-        } catch(NumberFormatException _e) {
-            return ddefault;
-        }
-    }
-
-    private static double asDouble(Matcher hit) {
-        // @todo (assira # 4) StringUtils: remove(text,char)
-        double value = Double.parseDouble(hit.group(1).replaceAll(" ", ""));
-        if(null !=hit.group(2)) {
-            value *= PREFIX.get(hit.group(2));
-        }
-        if("b".equals(hit.group(3))) {
-            value /= 8;
-        }
-        return value;
-    }
-
-    private static long asLong(Matcher hit) {
-        // @todo (assira # 4) StringUtils: remove(text,char)
-        long value = Long.parseLong(hit.group(1).replaceAll(" ", ""));
-        if(null !=hit.group(2)) {
-            value *= PREFIX.get(hit.group(2));
-        }
-        if("b".equals(hit.group(3))) {
-            value /= 8;
-        }
-        return value;
-    }
-
-    public static String format(long value) {
-        String text = Long.toString(value, 10);
-        StringBuilder ret = new StringBuilder(text.length() + text.length()/3 + 1);
-        for(int i=0, n=text.length()-1; i<=n; i++) {
-            ret.append(text.charAt(i));
-            if( n>i && ((n-i)%3 == 0) ) {
-                ret.append('\'');
-}
-        }
-        return ret.toString();
-    }
-
-}

+ 59 - 0
assira/src/test/java/net/ranides/assira/text/FormatNumberTest.java

@@ -0,0 +1,59 @@
+/*
+ * @author Ranides Atterwim <ranides@gmail.com>
+ * @copyright Ranides Atterwim
+ * @license WTFPL
+ * @url http://ranides.net/projects/assira
+ */
+package net.ranides.assira.text;
+
+import org.junit.Test;
+import static org.junit.Assert.*;
+
+/**
+ *
+ * @author Ranides Atterwim <ranides@gmail.com>
+ */
+public class FormatNumberTest {
+    
+    public FormatNumberTest() {
+    }
+
+    @Test
+    public void testGroup() {
+        assertEquals("3", FormatNumber.group(3));
+        assertEquals("12", FormatNumber.group(12));
+        assertEquals("127", FormatNumber.group(127));
+        assertEquals("1'270", FormatNumber.group(1270));
+        assertEquals("1'270'000", FormatNumber.group(1270000));
+    }
+    
+    @Test
+    public void testFormat() {
+        assertEquals("1.20k", FormatNumber.asEngineer(1, 2, FormatNumber.METRIC_PREFIX, 1200));
+        assertEquals("12.00", FormatNumber.asEngineer(1, 2, FormatNumber.METRIC_PREFIX, 12));
+        assertEquals("100.00m", FormatNumber.asEngineer(1, 2, FormatNumber.METRIC_PREFIX, 0.1));
+        assertEquals("120.00m", FormatNumber.asEngineer(1, 2, FormatNumber.METRIC_PREFIX, 0.12));
+        assertEquals("51.00m", FormatNumber.asEngineer(1, 2, FormatNumber.METRIC_PREFIX, 0.051));
+        assertEquals("5.10m", FormatNumber.asEngineer(1, 2, FormatNumber.METRIC_PREFIX, 0.0051));
+        assertEquals("510.00μ", FormatNumber.asEngineer(1, 2, FormatNumber.METRIC_PREFIX, 0.00051));
+        
+        assertEquals("1.20E3", FormatNumber.asEngineer(1, 2, FormatNumber.METRIC_EXP, 1200));
+        assertEquals("12.00E0", FormatNumber.asEngineer(1, 2, FormatNumber.METRIC_EXP, 12));
+        assertEquals("100.00E-3", FormatNumber.asEngineer(1, 2, FormatNumber.METRIC_EXP, 0.1));
+        assertEquals("120.00E-3", FormatNumber.asEngineer(1, 2, FormatNumber.METRIC_EXP, 0.12));
+        assertEquals("51.00E-3", FormatNumber.asEngineer(1, 2, FormatNumber.METRIC_EXP, 0.051));
+        assertEquals("5.10E-3", FormatNumber.asEngineer(1, 2, FormatNumber.METRIC_EXP, 0.0051));
+        assertEquals("510.00E-6", FormatNumber.asEngineer(1, 2, FormatNumber.METRIC_EXP, 0.00051));
+        
+        assertEquals("12.53M", FormatNumber.asEngineer(1, 2, FormatNumber.BYTE_PREFIX, 12.527*1024*1024));
+        assertEquals("11.72K", FormatNumber.asEngineer(1, 2, FormatNumber.BYTE_PREFIX, 12000));
+        assertEquals("1.17K", FormatNumber.asEngineer(1, 2, FormatNumber.BYTE_PREFIX, 1200));
+        assertEquals("12.00", FormatNumber.asEngineer(1, 2, FormatNumber.BYTE_PREFIX, 12));
+        assertEquals("0.10", FormatNumber.asEngineer(1, 2, FormatNumber.BYTE_PREFIX, 0.1));
+        assertEquals("0.12", FormatNumber.asEngineer(1, 2, FormatNumber.BYTE_PREFIX, 0.12));
+        assertEquals("0.05", FormatNumber.asEngineer(1, 2, FormatNumber.BYTE_PREFIX, 0.051));
+        assertEquals("0.01", FormatNumber.asEngineer(1, 2, FormatNumber.BYTE_PREFIX, 0.0051));
+        assertEquals("0.00", FormatNumber.asEngineer(1, 2, FormatNumber.BYTE_PREFIX, 0.00051));
+    }
+    
+}