Skip to main content

[jsonp~git:a7186689] [JSONP-22] Creates BigDecimal lazily when int and long numbers are used

  • From:
  • To:
  • Subject: [jsonp~git:a7186689] [JSONP-22] Creates BigDecimal lazily when int and long numbers are used
  • Date: Fri, 4 Oct 2013 22:15:49 +0000

Project:    jsonp
Repository: git
Revision:   a7186689b0535e098e6fa66ff61743d1913d8b64
Author:     jitu
Date:       2013-10-04 22:15:26 UTC
Link:       

Log Message:
------------
[JSONP-22] Creates BigDecimal lazily when int and long numbers are used
to represent JsonNumber



Revisions:
----------
a7186689b0535e098e6fa66ff61743d1913d8b64


Modified Paths:
---------------
impl/src/main/java/org/glassfish/json/JsonArrayBuilderImpl.java
impl/src/main/java/org/glassfish/json/JsonNumberImpl.java
impl/src/main/java/org/glassfish/json/JsonObjectBuilderImpl.java


Diffs:
------
--- a/impl/src/main/java/org/glassfish/json/JsonArrayBuilderImpl.java
+++ b/impl/src/main/java/org/glassfish/json/JsonArrayBuilderImpl.java
@@ -73,28 +73,28 @@ class JsonArrayBuilderImpl implements JsonArrayBuilder {
 
     public JsonArrayBuilder add(BigDecimal value) {
         validateValue(value);
-        addValueList(new JsonNumberImpl(value));
+        addValueList(JsonNumberImpl.getJsonNumber(value));
         return this;
     }
 
     public JsonArrayBuilder add(BigInteger value) {
         validateValue(value);
-        addValueList(new JsonNumberImpl(value));
+        addValueList(JsonNumberImpl.getJsonNumber(value));
         return this;
     }
 
     public JsonArrayBuilder add(int value) {
-        addValueList(new JsonNumberImpl(value));
+        addValueList(JsonNumberImpl.getJsonNumber(value));
         return this;
     }
 
     public JsonArrayBuilder add(long value) {
-        addValueList(new JsonNumberImpl(value));
+        addValueList(JsonNumberImpl.getJsonNumber(value));
         return this;
     }
 
     public JsonArrayBuilder add(double value) {
-        addValueList(new JsonNumberImpl(value));
+        addValueList(JsonNumberImpl.getJsonNumber(value));
         return this;
     }
 --- a/impl/src/main/java/org/glassfish/json/JsonNumberImpl.java
+++ b/impl/src/main/java/org/glassfish/json/JsonNumberImpl.java
@@ -44,74 +44,186 @@ import javax.json.JsonNumber;
 import java.math.BigDecimal;
 import java.math.BigInteger;
 
-final class JsonNumberImpl implements JsonNumber {
-    private final BigDecimal bigDecimal;
+abstract class JsonNumberImpl implements JsonNumber {
 
-    public JsonNumberImpl(int value) {
-        bigDecimal = new BigDecimal(value);
+    static JsonNumber getJsonNumber(int num) {
+        return new JsonIntNumber(num);
     }
 
-    public JsonNumberImpl(long value) {
-        bigDecimal = new BigDecimal(value);
+    static JsonNumber getJsonNumber(long num) {
+        return new JsonLongNumber(num);
     }
 
-    public JsonNumberImpl(BigInteger value) {
-        bigDecimal = new BigDecimal(value);
+    static JsonNumber getJsonNumber(BigInteger value) {
+        return new JsonBigDecimalNumber(new BigDecimal(value));
     }
 
-    public JsonNumberImpl(double value) {
+    static JsonNumber getJsonNumber(double value) {
         //bigDecimal = new BigDecimal(value);
         // This is the preferred way to convert double to BigDecimal
-        bigDecimal = BigDecimal.valueOf(value);
+        return new JsonBigDecimalNumber(BigDecimal.valueOf(value));
     }
 
-    public JsonNumberImpl(BigDecimal value) {
-        this.bigDecimal = value;
+    static JsonNumber getJsonNumber(BigDecimal value) {
+        return new JsonBigDecimalNumber(value);
+    }
+
+    // Optimized JsonNumber impl for int numbers.
+    private static final class JsonIntNumber extends JsonNumberImpl {
+        private final int num;
+        private BigDecimal bigDecimal;  // assigning it lazily on demand
+
+        JsonIntNumber(int num) {
+            this.num = num;
+        }
+
+        @Override
+        public boolean isIntegral() {
+            return true;
+        }
+
+        @Override
+        public int intValue() {
+            return num;
+        }
+
+        @Override
+        public int intValueExact() {
+            return num;
+        }
+
+        @Override
+        public long longValue() {
+            return num;
+        }
+
+        @Override
+        public long longValueExact() {
+            return num;
+        }
+
+        @Override
+        public double doubleValue() {
+            return num;
+        }
+
+        @Override
+        public BigDecimal bigDecimalValue() {
+            // reference assignments are atomic. At the most some more temp
+            // BigDecimal objects are created
+            BigDecimal bd = bigDecimal;
+            if (bd == null) {
+                bigDecimal = bd = new BigDecimal(num);
+            }
+            return bd;
+        }
+
+        @Override
+        public String toString() {
+            return Integer.toString(num);
+        }
+    }
+
+    // Optimized JsonNumber impl for long numbers.
+    private static final class JsonLongNumber extends JsonNumberImpl {
+        private final long num;
+        private BigDecimal bigDecimal;  // assigning it lazily on demand
+
+        JsonLongNumber(long num) {
+            this.num = num;
+        }
+
+        @Override
+        public boolean isIntegral() {
+            return true;
+        }
+
+        @Override
+        public long longValue() {
+            return num;
+        }
+
+        @Override
+        public long longValueExact() {
+            return num;
+        }
+
+        @Override
+        public double doubleValue() {
+            return num;
+        }
+
+        @Override
+        public BigDecimal bigDecimalValue() {
+            // reference assignments are atomic. At the most some more temp
+            // BigDecimal objects are created
+            BigDecimal bd = bigDecimal;
+            if (bd == null) {
+                bigDecimal = bd = new BigDecimal(num);
+            }
+            return bd;
+        }
+
+        @Override
+        public String toString() {
+            return Long.toString(num);
+        }
+
+    }
+
+    // JsonNumber impl using BigDecimal numbers.
+    private static final class JsonBigDecimalNumber extends JsonNumberImpl {
+        private final BigDecimal bigDecimal;
+
+        JsonBigDecimalNumber(BigDecimal value) {
+            this.bigDecimal = value;
+        }
+
+        @Override
+        public BigDecimal bigDecimalValue() {
+            return bigDecimal;
+        }
+
     }
 
     @Override
     public boolean isIntegral() {
-        return bigDecimal.scale() == 0;
+        return bigDecimalValue().scale() == 0;
     }
 
     @Override
     public int intValue() {
-        return bigDecimal.intValue();
+        return bigDecimalValue().intValue();
     }
 
     @Override
     public int intValueExact() {
-        return bigDecimal.intValueExact();
+        return bigDecimalValue().intValueExact();
     }
 
     @Override
     public long longValue() {
-        return bigDecimal.longValue();
+        return bigDecimalValue().longValue();
     }
 
     @Override
     public long longValueExact() {
-        return bigDecimal.longValueExact();
+        return bigDecimalValue().longValueExact();
     }
 
     @Override
-    public BigInteger bigIntegerValue() {
-        return bigDecimal.toBigInteger();
-    }
-
-    @Override
-    public BigInteger bigIntegerValueExact() {
-        return bigDecimal.toBigIntegerExact();
+    public double doubleValue() {
+        return bigDecimalValue().doubleValue();
     }
 
     @Override
-    public double doubleValue() {
-        return bigDecimal.doubleValue();
+    public BigInteger bigIntegerValue() {
+        return bigDecimalValue().toBigInteger();
     }
 
     @Override
-    public BigDecimal bigDecimalValue() {
-        return bigDecimal;
+    public BigInteger bigIntegerValueExact() {
+        return bigDecimalValue().toBigIntegerExact();
     }
 
     @Override
@@ -135,7 +247,7 @@ final class JsonNumberImpl implements JsonNumber {
 
     @Override
     public String toString() {
-        return bigDecimal.toString();
+        return bigDecimalValue().toString();
     }
 
 }--- a/impl/src/main/java/org/glassfish/json/JsonObjectBuilderImpl.java
+++ b/impl/src/main/java/org/glassfish/json/JsonObjectBuilderImpl.java
@@ -74,32 +74,32 @@ class JsonObjectBuilderImpl implements JsonObjectBuilder {
     public JsonObjectBuilder add(String name, BigInteger value) {
         validateName(name);
         validateValue(value);
-        putValueMap(name, new JsonNumberImpl(value));
+        putValueMap(name, JsonNumberImpl.getJsonNumber(value));
         return this;
     }
 
     public JsonObjectBuilder add(String name, BigDecimal value) {
         validateName(name);
         validateValue(value);
-        putValueMap(name, new JsonNumberImpl(value));
+        putValueMap(name, JsonNumberImpl.getJsonNumber(value));
         return this;
     }
 
     public JsonObjectBuilder add(String name, int value) {
         validateName(name);
-        putValueMap(name, new JsonNumberImpl(value));
+        putValueMap(name, JsonNumberImpl.getJsonNumber(value));
         return this;
     }
 
     public JsonObjectBuilder add(String name, long value) {
         validateName(name);
-        putValueMap(name, new JsonNumberImpl(value));
+        putValueMap(name, JsonNumberImpl.getJsonNumber(value));
         return this;
     }
 
     public JsonObjectBuilder add(String name, double value) {
         validateName(name);
-        putValueMap(name, new JsonNumberImpl(value));
+        putValueMap(name, JsonNumberImpl.getJsonNumber(value));
         return this;
     }
 





[jsonp~git:a7186689] [JSONP-22] Creates BigDecimal lazily when int and long numbers are used

jitu 10/04/2013
 
 
Close
loading
Please Confirm
Close