You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by lb...@apache.org on 2016/07/21 10:01:34 UTC
[4/5] camel git commit: CAMEL-10106: [api-component-framework] Reduce
object allocation in ApiMethodHelper, ApiMethodImpl
CAMEL-10106: [api-component-framework] Reduce object allocation in ApiMethodHelper, ApiMethodImpl
Project: http://git-wip-us.apache.org/repos/asf/camel/repo
Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/aac2662a
Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/aac2662a
Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/aac2662a
Branch: refs/heads/master
Commit: aac2662ab66b65c65e8d723d68a02678ecc0727c
Parents: 90ac673
Author: lburgazzoli <lb...@gmail.com>
Authored: Thu Jun 30 14:10:13 2016 +0200
Committer: lburgazzoli <lb...@gmail.com>
Committed: Thu Jul 21 11:47:40 2016 +0200
----------------------------------------------------------------------
.../camel/util/component/ApiMethodHelper.java | 84 +++++++++++++-------
.../camel/util/component/ApiMethodImpl.java | 17 ++--
2 files changed, 65 insertions(+), 36 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/camel/blob/aac2662a/camel-core/src/main/java/org/apache/camel/util/component/ApiMethodHelper.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/util/component/ApiMethodHelper.java b/camel-core/src/main/java/org/apache/camel/util/component/ApiMethodHelper.java
index 3d06e3f..8d09517 100644
--- a/camel-core/src/main/java/org/apache/camel/util/component/ApiMethodHelper.java
+++ b/camel-core/src/main/java/org/apache/camel/util/component/ApiMethodHelper.java
@@ -28,7 +28,6 @@ import java.util.Map;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
-import java.util.stream.Collectors;
import org.apache.camel.RuntimeCamelException;
import org.slf4j.Logger;
@@ -42,16 +41,18 @@ public final class ApiMethodHelper<T extends Enum<T> & ApiMethod> {
private static final Logger LOG = LoggerFactory.getLogger(ApiMethodHelper.class);
// maps method name to ApiMethod
- private final Map<String, List<T>> methodMap = new HashMap<String, List<T>>();
+ private final Map<String, List<T>> methodMap;
// maps method name to method arguments of the form Class type1, String name1, Class type2, String name2,...
- private final Map<String, List<Object>> argumentsMap = new HashMap<String, List<Object>>();
+ private final Map<String, List<Object>> argumentsMap;
// maps argument name to argument type
- private final Map<String, Class<?>> validArguments = new HashMap<String, Class<?>>();
+ private final Map<String, Class<?>> validArguments;
// maps aliases to actual method names
- private final HashMap<String, Set<String>> aliasesMap = new HashMap<String, Set<String>>();
+ private final Map<String, Set<String>> aliasesMap;
+
+ // nullable args
private final List<String> nullableArguments;
/**
@@ -62,6 +63,11 @@ public final class ApiMethodHelper<T extends Enum<T> & ApiMethod> {
*/
public ApiMethodHelper(Class<T> apiMethodEnum, Map<String, String> aliases, List<String> nullableArguments) {
+ Map<String, List<T>> tmpMethodMap = new HashMap<>();
+ Map<String, List<Object>> tmpArgumentsMap = new HashMap<>();
+ Map<String, Class<?>> tmpValidArguments = new HashMap<>();
+ Map<String, Set<String>> tmpAliasesMap = new HashMap<>();
+
// validate ApiMethod Enum
if (apiMethodEnum == null) {
throw new IllegalArgumentException("ApiMethod enumeration cannot be null");
@@ -103,28 +109,28 @@ public final class ApiMethodHelper<T extends Enum<T> & ApiMethod> {
builder.append(Character.toLowerCase(firstChar)).append(alias.substring(1));
alias = builder.toString();
}
- Set<String> names = aliasesMap.get(alias);
+ Set<String> names = tmpAliasesMap.get(alias);
if (names == null) {
names = new HashSet<String>();
- aliasesMap.put(alias, names);
+ tmpAliasesMap.put(alias, names);
}
names.add(name);
}
}
// map method name to Enum
- List<T> overloads = methodMap.get(name);
+ List<T> overloads = tmpMethodMap.get(name);
if (overloads == null) {
overloads = new ArrayList<T>();
- methodMap.put(method.getName(), overloads);
+ tmpMethodMap.put(method.getName(), overloads);
}
overloads.add(method);
// add arguments for this method
- List<Object> arguments = argumentsMap.get(name);
+ List<Object> arguments = tmpArgumentsMap.get(name);
if (arguments == null) {
arguments = new ArrayList<Object>();
- argumentsMap.put(name, arguments);
+ tmpArgumentsMap.put(name, arguments);
}
// process all arguments for this method
@@ -140,27 +146,27 @@ public final class ApiMethodHelper<T extends Enum<T> & ApiMethod> {
}
// also collect argument names for all methods, and detect clashes here
- final Class<?> previousType = validArguments.get(argName);
+ final Class<?> previousType = tmpValidArguments.get(argName);
if (previousType != null && previousType != argType) {
throw new IllegalArgumentException(String.format(
"Argument %s has ambiguous types (%s, %s) across methods!",
name, previousType, argType));
} else if (previousType == null) {
- validArguments.put(argName, argType);
+ tmpValidArguments.put(argName, argType);
}
}
}
// validate nullableArguments
- if (!validArguments.keySet().containsAll(this.nullableArguments)) {
+ if (!tmpValidArguments.keySet().containsAll(this.nullableArguments)) {
List<String> unknowns = new ArrayList<String>(this.nullableArguments);
- unknowns.removeAll(validArguments.keySet());
+ unknowns.removeAll(tmpValidArguments.keySet());
throw new IllegalArgumentException("Unknown nullable arguments " + unknowns.toString());
}
// validate aliases
- for (Map.Entry<String, Set<String>> entry : aliasesMap.entrySet()) {
+ for (Map.Entry<String, Set<String>> entry : tmpAliasesMap.entrySet()) {
// look for aliases that match multiple methods
final Set<String> methodNames = entry.getValue();
@@ -169,7 +175,7 @@ public final class ApiMethodHelper<T extends Enum<T> & ApiMethod> {
// get mapped methods
final List<T> aliasedMethods = new ArrayList<T>();
for (String methodName : methodNames) {
- List<T> mappedMethods = methodMap.get(methodName);
+ List<T> mappedMethods = tmpMethodMap.get(methodName);
aliasedMethods.addAll(mappedMethods);
}
@@ -199,7 +205,12 @@ public final class ApiMethodHelper<T extends Enum<T> & ApiMethod> {
}
}
- LOG.debug("Found {} unique method names in {} methods", methodMap.size(), methods.length);
+ this.methodMap = Collections.unmodifiableMap(tmpMethodMap);
+ this.argumentsMap = Collections.unmodifiableMap(tmpArgumentsMap);
+ this.validArguments = Collections.unmodifiableMap(tmpValidArguments);
+ this.aliasesMap = Collections.unmodifiableMap(tmpAliasesMap);
+
+ LOG.debug("Found {} unique method names in {} methods", tmpMethodMap.size(), methods.length);
}
/**
@@ -225,10 +236,10 @@ public final class ApiMethodHelper<T extends Enum<T> & ApiMethod> {
List<T> methods = methodMap.get(name);
if (methods == null) {
if (aliasesMap.containsKey(name)) {
- methods = aliasesMap.get(name)
- .stream()
- .map(method -> (T)methodMap.get(method))
- .collect(Collectors.toList());
+ methods = new ArrayList<T>();
+ for (String method : aliasesMap.get(name)) {
+ methods.addAll(methodMap.get(method));
+ }
}
}
if (methods == null) {
@@ -282,9 +293,9 @@ public final class ApiMethodHelper<T extends Enum<T> & ApiMethod> {
}
// list of methods that have all args in the given names
- final List<ApiMethod> result = new ArrayList<ApiMethod>();
- final List<ApiMethod> extraArgs = new ArrayList<ApiMethod>();
- final List<ApiMethod> nullArgs = new ArrayList<ApiMethod>();
+ List<ApiMethod> result = new ArrayList<>();
+ List<ApiMethod> extraArgs = null;
+ List<ApiMethod> nullArgs = null;
for (ApiMethod method : methods) {
final List<String> methodArgs = method.getArgNames();
@@ -308,13 +319,20 @@ public final class ApiMethodHelper<T extends Enum<T> & ApiMethod> {
if (methodArgs.containsAll(argNames)) {
// prefer exact match to avoid unused args
result.add(method);
- } else {
+ } else if (result.isEmpty()) {
+ // if result is empty, add method to extra args list
+ if (extraArgs == null) {
+ extraArgs = new ArrayList<>();
+ }
// method takes a subset, unused args
extraArgs.add(method);
}
- } else if (result.isEmpty() && extraArgs.isEmpty()) {
+ } else if (result.isEmpty() && extraArgs != null && extraArgs.isEmpty()) {
// avoid looking for nullable args by checking for empty result and extraArgs
if (withNullableArgsList != null && withNullableArgsList.containsAll(methodArgs)) {
+ if (nullArgs == null) {
+ nullArgs = new ArrayList<>();
+ }
nullArgs.add(method);
}
}
@@ -322,8 +340,14 @@ public final class ApiMethodHelper<T extends Enum<T> & ApiMethod> {
}
}
+ List<ApiMethod> methodList = result.isEmpty()
+ ? (extraArgs != null && extraArgs.isEmpty())
+ ? nullArgs
+ : extraArgs
+ : result;
+
// preference order is exact match, matches with extra args, matches with null args
- return Collections.unmodifiableList(result.isEmpty() ? (extraArgs.isEmpty() ? nullArgs : extraArgs) : result);
+ return methodList != null ? Collections.unmodifiableList(methodList) : Collections.emptyList();
}
/**
@@ -372,7 +396,7 @@ public final class ApiMethodHelper<T extends Enum<T> & ApiMethod> {
* @return alias names mapped to method names.
*/
public Map<String, Set<String>> getAliases() {
- return Collections.unmodifiableMap(aliasesMap);
+ return aliasesMap;
}
/**
@@ -380,7 +404,7 @@ public final class ApiMethodHelper<T extends Enum<T> & ApiMethod> {
* @return map with argument names as keys, and types as values
*/
public Map<String, Class<?>> allArguments() {
- return Collections.unmodifiableMap(validArguments);
+ return validArguments;
}
/**
http://git-wip-us.apache.org/repos/asf/camel/blob/aac2662a/camel-core/src/main/java/org/apache/camel/util/component/ApiMethodImpl.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/util/component/ApiMethodImpl.java b/camel-core/src/main/java/org/apache/camel/util/component/ApiMethodImpl.java
index 75c66a6..324ac80 100644
--- a/camel-core/src/main/java/org/apache/camel/util/component/ApiMethodImpl.java
+++ b/camel-core/src/main/java/org/apache/camel/util/component/ApiMethodImpl.java
@@ -65,14 +65,18 @@ public final class ApiMethodImpl implements ApiMethod {
throw new IllegalArgumentException("Invalid parameter list, "
+ "must be of the form 'Class arg1, String arg1Name, Class arg2, String arg2Name...");
}
+
int nArgs = args.length / 2;
- this.argNames = new ArrayList<String>(nArgs);
- this.argTypes = new ArrayList<Class<?>>(nArgs);
+ final List<String> tmpArgNames = new ArrayList<>(nArgs);
+ final List<Class<?>> tmpArgTypes = new ArrayList<>(nArgs);
for (int i = 0; i < nArgs; i++) {
- this.argTypes.add((Class<?>) args[i * 2]);
- this.argNames.add((String) args[i * 2 + 1]);
+ tmpArgTypes.add((Class<?>) args[i * 2]);
+ tmpArgNames.add((String) args[i * 2 + 1]);
}
+ this.argNames = Collections.unmodifiableList(tmpArgNames);
+ this.argTypes = Collections.unmodifiableList(tmpArgTypes);
+
// find method in Proxy type
try {
this.method = proxyType.getMethod(name, argTypes.toArray(new Class[nArgs]));
@@ -95,12 +99,12 @@ public final class ApiMethodImpl implements ApiMethod {
@Override
public List<String> getArgNames() {
- return Collections.unmodifiableList(argNames);
+ return argNames;
}
@Override
public List<Class<?>> getArgTypes() {
- return Collections.unmodifiableList(argTypes);
+ return argTypes;
}
@Override
@@ -117,6 +121,7 @@ public final class ApiMethodImpl implements ApiMethod {
.append(", argNames=").append(argNames)
.append(", argTypes=").append(argTypes)
.append("}");
+
return builder.toString();
}
}