BUG-1485: optimize primitive range checks
authorRobert Varga <rovarga@cisco.com>
Thu, 28 May 2015 23:50:23 +0000 (01:50 +0200)
committerGerrit Code Review <gerrit@opendaylight.org>
Fri, 5 Jun 2015 21:08:35 +0000 (21:08 +0000)
When we are dealing with a primitive type, we can force unboxing of the
type by declaring the range checker method's argument as the primitive
type. This will result in the stack not containing references for the
fast path (e.g. successful check) as well as reduce the number of
virtual calls to one. Checks will then be performed using primitive
manipulation instructions, which should result in better fast-path
execution.

The slow path will take a hit, as for throwing the exception, we will
end up re-boxing the primitive type.

Change-Id: I7e6b0e25790f9a43dc99f2fc7426bb9fe25c505c
Signed-off-by: Robert Varga <rovarga@cisco.com>
(cherry picked from commit 9b5366d775b93f0e2a37f028cda11832ba65ce6d)

code-generator/binding-java-api-generator/src/main/java/org/opendaylight/yangtools/sal/java/api/generator/AbstractPrimitiveRangeGenerator.java
code-generator/binding-java-api-generator/src/main/java/org/opendaylight/yangtools/sal/java/api/generator/AbstractSubIntegerRangeGenerator.java
code-generator/binding-java-api-generator/src/main/java/org/opendaylight/yangtools/sal/java/api/generator/ByteRangeGenerator.java
code-generator/binding-java-api-generator/src/main/java/org/opendaylight/yangtools/sal/java/api/generator/IntegerRangeGenerator.java
code-generator/binding-java-api-generator/src/main/java/org/opendaylight/yangtools/sal/java/api/generator/LongRangeGenerator.java
code-generator/binding-java-api-generator/src/main/java/org/opendaylight/yangtools/sal/java/api/generator/ShortRangeGenerator.java

index 72091a3a9d36f36a630293879f193b64bc751eb4..50dc2ca77a40dfd844761998f9a8d731ecf801d6 100644 (file)
@@ -12,21 +12,33 @@ import com.google.common.collect.Range;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.List;
+import javax.annotation.Nonnull;
 import org.opendaylight.yangtools.yang.model.api.type.RangeConstraint;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 abstract class AbstractPrimitiveRangeGenerator<T extends Number & Comparable<T>> extends AbstractRangeGenerator<T> {
     private static final Logger LOG = LoggerFactory.getLogger(AbstractPrimitiveRangeGenerator.class);
+    private final String primitiveName;
     private final T minValue;
     private final T maxValue;
 
-    protected AbstractPrimitiveRangeGenerator(final Class<T> typeClass, final T minValue, final T maxValue) {
+    protected AbstractPrimitiveRangeGenerator(final Class<T> typeClass, final String primitiveName, final T minValue, final T maxValue) {
         super(typeClass);
+        this.primitiveName = Preconditions.checkNotNull(primitiveName);
         this.minValue = Preconditions.checkNotNull(minValue);
         this.maxValue = Preconditions.checkNotNull(maxValue);
     }
 
+    /**
+     * Return the name of the primitive type, as known by the Java language.
+     *
+     * @return Primitive type name
+     */
+    @Nonnull protected final String getPrimitiveName() {
+        return primitiveName;
+    }
+
     private boolean needsMaximumEnforcement(final T maxToEnforce) {
         return maxValue.compareTo(maxToEnforce) > 0;
     }
@@ -82,7 +94,7 @@ abstract class AbstractPrimitiveRangeGenerator<T extends Number & Comparable<T>>
         final StringBuilder sb = new StringBuilder();
         final Collection<String> expressions = createExpressions(constraints);
 
-        sb.append("private static void ").append(checkerName).append("(final ").append(getTypeName()).append(" value) {\n");
+        sb.append("private static void ").append(checkerName).append("(final ").append(primitiveName).append(" value) {\n");
 
         if (!expressions.isEmpty()) {
             for (String exp : expressions) {
index 8a23cc96e617ff849a6aa4a9437981a1a513b248..ef87454ab3b6a124a45991f56b6563786bb4821a 100644 (file)
@@ -7,19 +7,14 @@
  */
 package org.opendaylight.yangtools.sal.java.api.generator;
 
-import com.google.common.base.Preconditions;
-
 abstract class AbstractSubIntegerRangeGenerator<T extends Number & Comparable<T>> extends AbstractPrimitiveRangeGenerator<T> {
-    private final String castType;
-
-    protected AbstractSubIntegerRangeGenerator(final Class<T> typeClass, final T minValue, final T maxValue, final String castType) {
-        super(typeClass, minValue, maxValue);
-        this.castType = Preconditions.checkNotNull(castType);
+    protected AbstractSubIntegerRangeGenerator(final Class<T> typeClass, final String primitiveName, final T minValue, final T maxValue) {
+        super(typeClass, primitiveName, minValue, maxValue);
     }
 
     @Override
     protected final String format(final T value) {
         // Make sure the number constant is cast to the corresponding primitive type
-        return '(' + castType + ')' + value;
+        return '(' + getPrimitiveName() + ')' + value;
     }
 }
index 4656897b035d76fa405fd0be32a73816b6ff6e44..b4b86126ab2c3338d110895a3784a867882f3dc7 100644 (file)
@@ -9,7 +9,7 @@ package org.opendaylight.yangtools.sal.java.api.generator;
 
 final class ByteRangeGenerator extends AbstractSubIntegerRangeGenerator<Byte> {
     ByteRangeGenerator() {
-        super(Byte.class, Byte.MIN_VALUE, Byte.MAX_VALUE, byte.class.getName());
+        super(Byte.class, byte.class.getName(), Byte.MIN_VALUE, Byte.MAX_VALUE);
     }
 
     @Override
index ffb9990528134619693b75965e13e7d063418c51..a9a5b847445b813d343678ef912db2d37cedbfb8 100644 (file)
@@ -9,7 +9,7 @@ package org.opendaylight.yangtools.sal.java.api.generator;
 
 final class IntegerRangeGenerator extends AbstractPrimitiveRangeGenerator<Integer> {
     IntegerRangeGenerator() {
-        super(Integer.class, Integer.MIN_VALUE, Integer.MAX_VALUE);
+        super(Integer.class, int.class.getName(), Integer.MIN_VALUE, Integer.MAX_VALUE);
     }
 
     @Override
index 0afba8404827e8d88d92f6e5b4b9343f0716b254..781283f76fdcde7050d557be289164fe40e8038f 100644 (file)
@@ -10,7 +10,7 @@ package org.opendaylight.yangtools.sal.java.api.generator;
 final class LongRangeGenerator extends AbstractPrimitiveRangeGenerator<Long> {
 
     protected LongRangeGenerator() {
-        super(Long.class, Long.MIN_VALUE, Long.MAX_VALUE);
+        super(Long.class, long.class.getName(), Long.MIN_VALUE, Long.MAX_VALUE);
     }
 
     @Override
index 9ad2a83a8f9598911280cfa1fd64fff8cfe2d6df..abe07a55521536f5f845c4933222b3fa9648f10b 100644 (file)
@@ -9,7 +9,7 @@ package org.opendaylight.yangtools.sal.java.api.generator;
 
 final class ShortRangeGenerator extends AbstractSubIntegerRangeGenerator<Short> {
     ShortRangeGenerator() {
-        super(Short.class, Short.MIN_VALUE, Short.MAX_VALUE, short.class.getName());
+        super(Short.class, short.class.getName(), Short.MIN_VALUE, Short.MAX_VALUE);
     }
 
     @Override