brooklyn-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From aleds...@apache.org
Subject [1/5] brooklyn-server git commit: Use stripped version of ScriptBytecodeAdapter.isCase
Date Thu, 12 Jan 2017 10:32:30 GMT
Repository: brooklyn-server
Updated Branches:
  refs/heads/master 03ded82d2 -> 0df68a851


Use stripped version of ScriptBytecodeAdapter.isCase

- Optimize performance and avoid locks used in groovy dynamic invocation
  Should fix BROOKLYN-424


Project: http://git-wip-us.apache.org/repos/asf/brooklyn-server/repo
Commit: http://git-wip-us.apache.org/repos/asf/brooklyn-server/commit/2396f226
Tree: http://git-wip-us.apache.org/repos/asf/brooklyn-server/tree/2396f226
Diff: http://git-wip-us.apache.org/repos/asf/brooklyn-server/diff/2396f226

Branch: refs/heads/master
Commit: 2396f226e78a6d6e273d0a8a8068467d4c1f3b00
Parents: 07e5503
Author: Valentin Aitken <bostko@gmail.com>
Authored: Tue Jan 10 21:29:25 2017 +0200
Committer: Valentin Aitken <bostko@gmail.com>
Committed: Wed Jan 11 14:38:11 2017 +0200

----------------------------------------------------------------------
 .../util/groovy/FromRunnableClosure.java        |  4 +-
 .../brooklyn/util/groovy/GroovyJavaMethods.java | 23 ++++-
 .../util/groovy/GroovJavaMethodsTest.java       | 89 ++++++++++++++++++++
 3 files changed, 110 insertions(+), 6 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/2396f226/utils/groovy/src/main/java/org/apache/brooklyn/util/groovy/FromRunnableClosure.java
----------------------------------------------------------------------
diff --git a/utils/groovy/src/main/java/org/apache/brooklyn/util/groovy/FromRunnableClosure.java
b/utils/groovy/src/main/java/org/apache/brooklyn/util/groovy/FromRunnableClosure.java
index 37fad87..3f60a3e 100644
--- a/utils/groovy/src/main/java/org/apache/brooklyn/util/groovy/FromRunnableClosure.java
+++ b/utils/groovy/src/main/java/org/apache/brooklyn/util/groovy/FromRunnableClosure.java
@@ -22,7 +22,7 @@ import groovy.lang.Closure;
 
 import java.util.concurrent.Callable;
 
-import org.codehaus.groovy.runtime.ScriptBytecodeAdapter;
+import org.codehaus.groovy.runtime.DefaultGroovyMethods;
 
 public class FromRunnableClosure<T> extends Closure<T> {
     private static final long serialVersionUID = 1L;
@@ -35,7 +35,7 @@ public class FromRunnableClosure<T> extends Closure<T> {
 
     @SuppressWarnings("unchecked")
     public T doCall() throws Throwable {
-        if (ScriptBytecodeAdapter.isCase(job, Callable.class)) {
+        if (DefaultGroovyMethods.isCase(job, Callable.class)) {
             return ((Callable<T>)job).call();
         } else {
             job.run();

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/2396f226/utils/groovy/src/main/java/org/apache/brooklyn/util/groovy/GroovyJavaMethods.java
----------------------------------------------------------------------
diff --git a/utils/groovy/src/main/java/org/apache/brooklyn/util/groovy/GroovyJavaMethods.java
b/utils/groovy/src/main/java/org/apache/brooklyn/util/groovy/GroovyJavaMethods.java
index 7f019a9..ffd4c3b 100644
--- a/utils/groovy/src/main/java/org/apache/brooklyn/util/groovy/GroovyJavaMethods.java
+++ b/utils/groovy/src/main/java/org/apache/brooklyn/util/groovy/GroovyJavaMethods.java
@@ -22,6 +22,7 @@ import java.util.concurrent.Callable;
 
 import org.apache.brooklyn.util.concurrent.CallableFromRunnable;
 import org.apache.brooklyn.util.exceptions.Exceptions;
+import org.codehaus.groovy.runtime.DefaultGroovyMethods;
 import org.codehaus.groovy.runtime.ScriptBytecodeAdapter;
 import org.codehaus.groovy.runtime.callsite.CallSite;
 import org.codehaus.groovy.runtime.callsite.CallSiteArray;
@@ -65,7 +66,7 @@ public class GroovyJavaMethods {
     @SuppressWarnings("unchecked")
     public static <T> Callable<T> callableFromRunnable(final Runnable job) {
         try {
-            if (ScriptBytecodeAdapter.isCase(job, Callable.class)) {
+            if (safeGroovyIsCase(job, Callable.class)) {
                 return (Callable<T>)ScriptBytecodeAdapter.asType(job, Callable.class);
             } else {
                 return CallableFromRunnable.newInstance(job, null);
@@ -75,6 +76,20 @@ public class GroovyJavaMethods {
         }
     }
 
+    /**
+     * Alternative implementation of {@link ScriptBytecodeAdapter#isCase(Object, Object)}<br>
+     * Stripped down to work only for caseExpression of type <code>java.lang.Class</code>.<br>
+     * It behaves the same way only for cases when caseExpression <code>java.lang.Class</code>
does <b>not</b> implement <code>isCase</code> method.<br>
+     * It goes directly to {@link DefaultGroovyMethods#isCase(Object, Object)} method instead
of using Groovy dynamic invocation.<br>
+     * This saves extra operations and avoids the locks used in Groovy dynamic invocation.
See <a href="https://issues.apache.org/jira/browse/BROOKLYN-424">BROOKLYN-424</a>.
+     */
+    public static boolean safeGroovyIsCase(Object switchValue, Class caseExpression) {
+        if (caseExpression == null) {
+            return switchValue == null;
+        }
+        return DefaultGroovyMethods.isCase(caseExpression, switchValue);
+    }
+
     public static <T> Predicate<T> predicateFromClosure(final Closure<Boolean>
job) {
         return new Predicate<T>() {
             @Override
@@ -96,7 +111,7 @@ public class GroovyJavaMethods {
     @SuppressWarnings("unchecked")
     public static <T> Predicate<T> castToPredicate(Object o) {
         try {
-            if (ScriptBytecodeAdapter.isCase(o, Closure.class)) {
+            if (safeGroovyIsCase(o, Closure.class)) {
                 return predicateFromClosure((Closure<Boolean>)o);
             } else {
                 return (Predicate<T>) o;
@@ -111,7 +126,7 @@ public class GroovyJavaMethods {
         try {
             if (ScriptBytecodeAdapter.compareEqual(o, null)) {
                 return (Closure<T>)ScriptBytecodeAdapter.castToType(o, Closure.class);
-            } else if (ScriptBytecodeAdapter.isCase(o, Closure.class)) {
+            } else if (safeGroovyIsCase(o, Closure.class)) {
                 return (Closure<T>)ScriptBytecodeAdapter.castToType(o, Closure.class);
             } else if (o instanceof Runnable) {
                 return closureFromRunnable((Runnable)ScriptBytecodeAdapter.createPojoWrapper(ScriptBytecodeAdapter.castToType(o,
Runnable.class), Runnable.class));
@@ -173,7 +188,7 @@ public class GroovyJavaMethods {
     @SuppressWarnings("unchecked")
     public static <T> T fix(Object o) {
         try {
-            if (ScriptBytecodeAdapter.isCase(o, GString.class)) {
+            if (safeGroovyIsCase(o, GString.class)) {
                 return (T)ScriptBytecodeAdapter.asType(o, String.class);
             } else {
                 return (T)o;

http://git-wip-us.apache.org/repos/asf/brooklyn-server/blob/2396f226/utils/groovy/src/test/java/org/apache/brooklyn/util/groovy/GroovJavaMethodsTest.java
----------------------------------------------------------------------
diff --git a/utils/groovy/src/test/java/org/apache/brooklyn/util/groovy/GroovJavaMethodsTest.java
b/utils/groovy/src/test/java/org/apache/brooklyn/util/groovy/GroovJavaMethodsTest.java
new file mode 100644
index 0000000..f32e92e
--- /dev/null
+++ b/utils/groovy/src/test/java/org/apache/brooklyn/util/groovy/GroovJavaMethodsTest.java
@@ -0,0 +1,89 @@
+/*
+ * 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.brooklyn.util.groovy;
+
+import groovy.lang.Closure;
+import groovy.lang.GString;
+import org.testng.annotations.Test;
+
+import java.util.concurrent.Callable;
+
+import static org.apache.brooklyn.util.groovy.GroovyJavaMethods.truth;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertTrue;
+
+public class GroovJavaMethodsTest {
+    @Test
+    public void testTruth() {
+        assertTrue(truth("someString"));
+        assertTrue(truth(1));
+        assertFalse(truth(false));
+        assertFalse(truth(null));
+    }
+
+    @Test
+    public void testIsCase() throws Throwable {
+        assertFalse(callScriptBytecodeAdapter_isCase(
+                null,
+                GString.class));
+        assertTrue(
+                callScriptBytecodeAdapter_isCase(
+                        new GString(new String[]{"Hi"}) {
+                            @Override public String[] getStrings() {
+                                return new String[0];
+                            }
+                        },
+                        GString.class));
+        assertFalse(
+                callScriptBytecodeAdapter_isCase(
+                        "exampleString",
+                        GString.class));
+
+        assertTrue(
+                callScriptBytecodeAdapter_isCase(
+                        new Callable<Void>() {
+                            @Override public Void call() {
+                                return null;
+                            }
+                        },
+                        Callable.class));
+        assertFalse(
+                callScriptBytecodeAdapter_isCase(
+                        "exampleString",
+                        Callable.class));
+
+        assertTrue(
+                callScriptBytecodeAdapter_isCase(
+                        new Closure(null) {
+                            @Override public Void call() {
+                                return null;
+                            }
+                        },
+                        Closure.class));
+        assertFalse(
+                callScriptBytecodeAdapter_isCase(
+                        "exampleString",
+                        Closure.class));
+    }
+
+    private boolean callScriptBytecodeAdapter_isCase(Object switchValue, Class caseExpression)
throws Throwable {
+//        return org.codehaus.groovy.runtime.ScriptBytecodeAdapter.isCase(switchValue, caseExpression);
+        return org.apache.brooklyn.util.groovy.GroovyJavaMethods.safeGroovyIsCase(switchValue,
caseExpression);
+    }
+}


Mime
View raw message