You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jclouds.apache.org by ga...@apache.org on 2013/10/15 02:53:06 UTC

git commit: [JCLOUD 301]: Make increased use of Invokable params cache

Updated Branches:
  refs/heads/master 0722ce71a -> 53146fb7b


[JCLOUD 301]: Make increased use of Invokable params cache

This patch moves the Invokable Parameter cache to Reflection2 and adds
a convenience method for it to allow it to be shared by multiple
callers. The subsequent ability of S3Utils to use this cache results
in a ~40% improvement in performance for generating signed GETs and
PUTs for S3. This commit also converts a few others calls to
Invokable.getParameters() but the observed benefit from those was
small in microbenchmarks.


Project: http://git-wip-us.apache.org/repos/asf/incubator-jclouds/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-jclouds/commit/53146fb7
Tree: http://git-wip-us.apache.org/repos/asf/incubator-jclouds/tree/53146fb7
Diff: http://git-wip-us.apache.org/repos/asf/incubator-jclouds/diff/53146fb7

Branch: refs/heads/master
Commit: 53146fb7bb746309b5e1c4abe0dd12e6d9f0d008
Parents: 0722ce7
Author: Niraj Tolia <nt...@maginatics.com>
Authored: Tue Oct 1 00:50:17 2013 -0700
Committer: Andrew Gaul <ga...@apache.org>
Committed: Mon Oct 14 17:44:03 2013 -0700

----------------------------------------------------------------------
 .../main/java/org/jclouds/s3/util/S3Utils.java  |  5 +++--
 .../java/org/jclouds/reflect/Reflection2.java   | 18 ++++++++++++++++++
 .../org/jclouds/rest/InputParamValidator.java   |  5 ++---
 .../rest/internal/RestAnnotationProcessor.java  | 20 +++++++-------------
 4 files changed, 30 insertions(+), 18 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/53146fb7/apis/s3/src/main/java/org/jclouds/s3/util/S3Utils.java
----------------------------------------------------------------------
diff --git a/apis/s3/src/main/java/org/jclouds/s3/util/S3Utils.java b/apis/s3/src/main/java/org/jclouds/s3/util/S3Utils.java
index 4080b22..ef836c3 100644
--- a/apis/s3/src/main/java/org/jclouds/s3/util/S3Utils.java
+++ b/apis/s3/src/main/java/org/jclouds/s3/util/S3Utils.java
@@ -22,15 +22,16 @@ import static com.google.common.collect.Iterables.any;
 
 import java.lang.annotation.Annotation;
 import java.util.Arrays;
+import java.util.List;
 import java.util.regex.Pattern;
 
 import org.jclouds.http.HttpRequest;
+import org.jclouds.reflect.Reflection2;
 import org.jclouds.rest.internal.GeneratedHttpRequest;
 import org.jclouds.s3.Bucket;
 import org.jclouds.s3.S3Client;
 
 import com.google.common.base.Predicate;
-import com.google.common.collect.ImmutableList;
 import com.google.common.reflect.Parameter;
 
 /**
@@ -77,7 +78,7 @@ public class S3Utils {
 
       String bucketName = null;
 
-      ImmutableList<Parameter> parameters = request.getInvocation().getInvokable().getParameters();
+      List<Parameter> parameters = Reflection2.getInvokableParameters(request.getInvocation().getInvokable());
       for (int i = 0; i < parameters.size(); i++) {
          if (any(Arrays.asList(parameters.get(i).getAnnotations()), ANNOTATIONTYPE_BUCKET)) {
             bucketName = (String) request.getInvocation().getArgs().get(i);

http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/53146fb7/core/src/main/java/org/jclouds/reflect/Reflection2.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/jclouds/reflect/Reflection2.java b/core/src/main/java/org/jclouds/reflect/Reflection2.java
index 674c416..7246f64 100644
--- a/core/src/main/java/org/jclouds/reflect/Reflection2.java
+++ b/core/src/main/java/org/jclouds/reflect/Reflection2.java
@@ -195,6 +195,24 @@ public class Reflection2 {
             }
          });
 
+   private static final LoadingCache<Invokable<?, ?>, ImmutableList<Parameter>> invokableParamsCache =
+      CacheBuilder.newBuilder().maximumSize(100).build(new CacheLoader<Invokable<?, ?>, ImmutableList<Parameter>>() {
+            @Override
+            public ImmutableList<Parameter> load(Invokable<?, ?> invokable) {
+               return invokable.getParameters();
+            }
+         });
+
+   /**
+    * Returns the {@link Parameter}s associated with the given {@link Invokable}. This function is backed by a cache.
+    * 
+    * @param invokable
+    *           The {@link Invokable} we want to get Parameters from
+    */
+   public static List<Parameter> getInvokableParameters(final Invokable<?, ?> invokable) {
+      return invokableParamsCache.getUnchecked(invokable);
+   }
+
    private static class TypeTokenAndParameterTypes {
 
       protected TypeToken<?> type;

http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/53146fb7/core/src/main/java/org/jclouds/rest/InputParamValidator.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/jclouds/rest/InputParamValidator.java b/core/src/main/java/org/jclouds/rest/InputParamValidator.java
index c7c5bb9..3931e39 100644
--- a/core/src/main/java/org/jclouds/rest/InputParamValidator.java
+++ b/core/src/main/java/org/jclouds/rest/InputParamValidator.java
@@ -26,7 +26,6 @@ import org.jclouds.predicates.Validator;
 import org.jclouds.reflect.Invocation;
 import org.jclouds.rest.annotations.ParamValidators;
 
-import com.google.common.collect.ImmutableList;
 import com.google.common.collect.Iterables;
 import com.google.common.collect.Lists;
 import com.google.common.reflect.Parameter;
@@ -67,7 +66,7 @@ public class InputParamValidator {
     * @throws IllegalStateException
     *            if validation failed
     */
-   public void validateMethodParametersOrThrow(Invocation invocation, ImmutableList<Parameter> parameters) {
+   public void validateMethodParametersOrThrow(Invocation invocation, List<Parameter> parameters) {
       try {
          performMethodValidation(checkNotNull(invocation, "invocation"));
          performParameterValidation(invocation, checkNotNull(parameters, "parameters"));
@@ -105,7 +104,7 @@ public class InputParamValidator {
     * @param args
     *           arguments that correspond to the array of annotations
     */
-   private void performParameterValidation(Invocation invocation, ImmutableList<Parameter> parameters) {
+   private void performParameterValidation(Invocation invocation, List<Parameter> parameters) {
       for (Parameter param : parameters) {
          ParamValidators annotation = param.getAnnotation(ParamValidators.class);
          if (annotation == null)

http://git-wip-us.apache.org/repos/asf/incubator-jclouds/blob/53146fb7/core/src/main/java/org/jclouds/rest/internal/RestAnnotationProcessor.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/jclouds/rest/internal/RestAnnotationProcessor.java b/core/src/main/java/org/jclouds/rest/internal/RestAnnotationProcessor.java
index 89b430c..d48d876 100644
--- a/core/src/main/java/org/jclouds/rest/internal/RestAnnotationProcessor.java
+++ b/core/src/main/java/org/jclouds/rest/internal/RestAnnotationProcessor.java
@@ -38,6 +38,7 @@ import static org.jclouds.http.HttpUtils.filterOutContentHeaders;
 import static org.jclouds.http.HttpUtils.tryFindHttpMethod;
 import static org.jclouds.http.Uris.uriBuilder;
 import static org.jclouds.io.Payloads.newPayload;
+import static org.jclouds.reflect.Reflection2.getInvokableParameters;
 import static org.jclouds.util.Strings2.replaceTokens;
 
 import java.lang.annotation.Annotation;
@@ -150,13 +151,6 @@ public class RestAnnotationProcessor implements Function<Invocation, HttpRequest
    private final GetAcceptHeaders getAcceptHeaders;
    private final Invocation caller;
    private final boolean stripExpectHeader;
-   private static final LoadingCache<Invokable<?, ?>, ImmutableList<Parameter>> invokableParamsCache =
-       CacheBuilder.newBuilder().maximumSize(100).build(new CacheLoader<Invokable<?, ?>, ImmutableList<Parameter>>() {
-               @Override
-               public ImmutableList<Parameter> load(Invokable<?, ?> invokable) {
-                   return invokable.getParameters();
-               }
-           });
 
    @Inject
    private RestAnnotationProcessor(Injector injector, @ApiVersion String apiVersion, @BuildVersion String buildVersion,
@@ -186,7 +180,7 @@ public class RestAnnotationProcessor implements Function<Invocation, HttpRequest
    @Override
    public GeneratedHttpRequest apply(Invocation invocation) {
       checkNotNull(invocation, "invocation");
-      inputParamValidator.validateMethodParametersOrThrow(invocation, invokableParamsCache.getUnchecked(invocation.getInvokable()));
+      inputParamValidator.validateMethodParametersOrThrow(invocation, getInvokableParameters(invocation.getInvokable()));
 
       Optional<URI> endpoint = Optional.absent();
       HttpRequest r = findOrNull(invocation.getArgs(), HttpRequest.class);
@@ -506,7 +500,7 @@ public class RestAnnotationProcessor implements Function<Invocation, HttpRequest
 
    private static Collection<Parameter> parametersWithAnnotation(Invokable<?, ?> invokable,
          final Class<? extends Annotation> annotationType) {
-      return filter(invokableParamsCache.getUnchecked(invokable), new Predicate<Parameter>() {
+      return filter(getInvokableParameters(invokable), new Predicate<Parameter>() {
          public boolean apply(Parameter in) {
             return in.isAnnotationPresent(annotationType);
          }
@@ -609,7 +603,7 @@ public class RestAnnotationProcessor implements Function<Invocation, HttpRequest
             if (!argType.isArray() && parameterType.isArray()) {// TODO: &&
                                                                 // invocation.getInvokable().isVarArgs())
                                                                 // {
-               int arrayLength = args.size() - invocation.getInvokable().getParameters().size() + 1;
+               int arrayLength = args.size() - getInvokableParameters(invocation.getInvokable()).size() + 1;
                if (arrayLength == 0)
                   break OUTER;
                arg = (Object[]) Array.newInstance(arg.getClass(), arrayLength);
@@ -631,7 +625,7 @@ public class RestAnnotationProcessor implements Function<Invocation, HttpRequest
             if (shouldBreak)
                break OUTER;
          } else {
-            if (position + 1 == invocation.getInvokable().getParameters().size() && entry.getType().isArray())// TODO:
+            if (position + 1 == getInvokableParameters(invocation.getInvokable()).size() && entry.getType().isArray())// TODO:
                                                                                                               // &&
                                                                                                               // invocation.getInvokable().isVarArgs())
                continue OUTER;
@@ -650,7 +644,7 @@ public class RestAnnotationProcessor implements Function<Invocation, HttpRequest
             @Override
             public Set<Integer> load(Invokable<?, ?> invokable) {
                Builder<Integer> toReturn = ImmutableSet.builder();
-               for (Parameter param : invokable.getParameters()) {
+               for (Parameter param : getInvokableParameters(invokable)) {
                   Class<?> type = param.getType().getRawType();
                   if (HttpRequestOptions.class.isAssignableFrom(type)
                         || HttpRequestOptions[].class.isAssignableFrom(type))
@@ -776,7 +770,7 @@ public class RestAnnotationProcessor implements Function<Invocation, HttpRequest
    }
 
    private boolean checkPresentOrNullable(Invocation invocation, String paramKey, int argIndex, Object arg) {
-      if (arg == null && !invocation.getInvokable().getParameters().get(argIndex).isAnnotationPresent(Nullable.class))
+      if (arg == null && !getInvokableParameters(invocation.getInvokable()).get(argIndex).isAnnotationPresent(Nullable.class))
          throw new NullPointerException(format("param{%s} for invocation %s.%s", paramKey, invocation.getInvokable()
                .getOwnerType().getRawType().getSimpleName(), invocation.getInvokable().getName()));
       return true;