Improved thread safety when building the method cache in JavaTranslator
Project: http://git-wip-us.apache.org/repos/asf/tinkerpop/repo Commit: http://git-wip-us.apache.org/repos/asf/tinkerpop/commit/c47217d2 Tree: http://git-wip-us.apache.org/repos/asf/tinkerpop/tree/c47217d2 Diff: http://git-wip-us.apache.org/repos/asf/tinkerpop/diff/c47217d2 Branch: refs/heads/TINKERPOP-1404 Commit: c47217d26336ff68dc8dbb9a028664cb80bdaf42 Parents: 1fc52cb Author: Stephen Mallette <sp...@genoprime.com> Authored: Thu Sep 15 15:42:12 2016 -0400 Committer: Stephen Mallette <sp...@genoprime.com> Committed: Thu Sep 15 15:42:12 2016 -0400 ---------------------------------------------------------------------- .../gremlin/jsr223/JavaTranslator.java | 34 ++++++++++---------- 1 file changed, 17 insertions(+), 17 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/c47217d2/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/jsr223/JavaTranslator.java ---------------------------------------------------------------------- diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/jsr223/JavaTranslator.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/jsr223/JavaTranslator.java index ed2def2..5d3e82d 100644 --- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/jsr223/JavaTranslator.java +++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/jsr223/JavaTranslator.java @@ -102,25 +102,9 @@ public final class JavaTranslator<S extends TraversalSource, T extends Traversal } private Object invokeMethod(final Object delegate, final Class returnType, final String methodName, final Object... arguments) { - ////////////////////////// - ////////////////////////// // populate method cache for fast access to methods in subsequent calls final Map<String, List<Method>> methodCache = GLOBAL_METHOD_CACHE.getOrDefault(delegate.getClass(), new HashMap<>()); - if (methodCache.isEmpty()) { - for (final Method method : delegate.getClass().getMethods()) { - if (!(method.getName().equals("addV") && method.getParameterCount() == 1 && method.getParameters()[0].getType().equals(Object[].class))) { // hack cause its hard to tell Object[] vs. String :| - List<Method> list = methodCache.get(method.getName()); - if (null == list) { - list = new ArrayList<>(); - methodCache.put(method.getName(), list); - } - list.add(method); - } - } - GLOBAL_METHOD_CACHE.put(delegate.getClass(), methodCache); - } - ////////////////////////// - ////////////////////////// + if (methodCache.isEmpty()) buildMethodCache(delegate, methodCache); // create a copy of the argument array so as not to mutate the original bytecode final Object[] argumentsCopy = new Object[arguments.length]; @@ -179,4 +163,20 @@ public final class JavaTranslator<S extends TraversalSource, T extends Traversal } throw new IllegalStateException("Could not locate method: " + delegate.getClass().getSimpleName() + "." + methodName + "(" + Arrays.toString(argumentsCopy) + ")"); } + + private synchronized static void buildMethodCache(final Object delegate, final Map<String, List<Method>> methodCache) { + if (methodCache.isEmpty()) { + for (final Method method : delegate.getClass().getMethods()) { + if (!(method.getName().equals("addV") && method.getParameterCount() == 1 && method.getParameters()[0].getType().equals(Object[].class))) { // hack cause its hard to tell Object[] vs. String :| + List<Method> list = methodCache.get(method.getName()); + if (null == list) { + list = new ArrayList<>(); + methodCache.put(method.getName(), list); + } + list.add(method); + } + } + GLOBAL_METHOD_CACHE.put(delegate.getClass(), methodCache); + } + } }