Repository: bval Updated Branches: refs/heads/master 3da9b757a -> b421b5b9c
BVAL-154: cache unconstrained types by type only and quickly return empty descriptors on subsequent fetches Project: http://git-wip-us.apache.org/repos/asf/bval/repo Commit: http://git-wip-us.apache.org/repos/asf/bval/commit/b421b5b9 Tree: http://git-wip-us.apache.org/repos/asf/bval/tree/b421b5b9 Diff: http://git-wip-us.apache.org/repos/asf/bval/diff/b421b5b9 Branch: refs/heads/master Commit: b421b5b9c8053390e53ad1bcf8e14f152c128b73 Parents: 3da9b75 Author: Matt Benson <[email protected]> Authored: Wed Oct 17 12:54:02 2018 -0500 Committer: Matt Benson <[email protected]> Committed: Wed Oct 17 12:54:02 2018 -0500 ---------------------------------------------------------------------- .../bval/jsr/descriptor/DescriptorManager.java | 26 ++++++++++++++------ .../org/apache/bval/jsr/BeanDescriptorTest.java | 16 ++++++++++++ 2 files changed, 35 insertions(+), 7 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/bval/blob/b421b5b9/bval-jsr/src/main/java/org/apache/bval/jsr/descriptor/DescriptorManager.java ---------------------------------------------------------------------- diff --git a/bval-jsr/src/main/java/org/apache/bval/jsr/descriptor/DescriptorManager.java b/bval-jsr/src/main/java/org/apache/bval/jsr/descriptor/DescriptorManager.java index 7c84f87..f25514c 100644 --- a/bval-jsr/src/main/java/org/apache/bval/jsr/descriptor/DescriptorManager.java +++ b/bval-jsr/src/main/java/org/apache/bval/jsr/descriptor/DescriptorManager.java @@ -16,8 +16,10 @@ */ package org.apache.bval.jsr.descriptor; +import java.util.HashSet; import java.util.List; import java.util.Optional; +import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; @@ -26,11 +28,13 @@ import javax.validation.metadata.CascadableDescriptor; import javax.validation.metadata.ContainerDescriptor; import javax.validation.metadata.ElementDescriptor; import javax.validation.metadata.ExecutableDescriptor; +import javax.validation.metadata.MethodType; import org.apache.bval.jsr.ApacheValidatorFactory; import org.apache.bval.jsr.metadata.AnnotationBehaviorMergeStrategy; import org.apache.bval.jsr.metadata.CompositeBuilder; import org.apache.bval.jsr.metadata.DualBuilder; +import org.apache.bval.jsr.metadata.EmptyBuilder; import org.apache.bval.jsr.metadata.HierarchyBuilder; import org.apache.bval.jsr.metadata.MetadataBuilder; import org.apache.bval.jsr.metadata.ReflectionBuilder; @@ -55,6 +59,8 @@ public class DescriptorManager { private final ApacheValidatorFactory validatorFactory; private final ConcurrentMap<Class<?>, BeanD<?>> beanDescriptors = new ConcurrentHashMap<>(); + // synchronization unnecessary + private final Set<Class<?>> knownUnconstrainedTypes = new HashSet<>(); private final ReflectionBuilder reflectionBuilder; public DescriptorManager(ApacheValidatorFactory validatorFactory) { @@ -70,13 +76,19 @@ public class DescriptorManager { if (beanDescriptors.containsKey(beanClass)) { return beanDescriptors.get(beanClass); } - final MetadataReader.ForBean<T> reader = - new MetadataReader(validatorFactory, beanClass).forBean(builder(beanClass)); - final BeanD<T> beanD = new BeanD<>(reader); - @SuppressWarnings("unchecked") - final BeanD<T> result = - Optional.ofNullable((BeanD<T>) beanDescriptors.putIfAbsent(beanClass, beanD)).orElse(beanD); - return result; + final MetadataBuilder.ForBean<T> builder = + knownUnconstrainedTypes.contains(beanClass) ? EmptyBuilder.instance().forBean() : builder(beanClass); + final BeanD<T> beanD = new BeanD<>(new MetadataReader(validatorFactory, beanClass).forBean(builder)); + + if (beanD.isBeanConstrained() || !(beanD.getConstrainedConstructors().isEmpty() + && beanD.getConstrainedMethods(MethodType.GETTER, MethodType.NON_GETTER).isEmpty())) { + @SuppressWarnings("unchecked") + final BeanD<T> result = + Optional.ofNullable((BeanD<T>) beanDescriptors.putIfAbsent(beanClass, beanD)).orElse(beanD); + return result; + } + knownUnconstrainedTypes.add(beanClass); + return beanD; } public void clear() { http://git-wip-us.apache.org/repos/asf/bval/blob/b421b5b9/bval-jsr/src/test/java/org/apache/bval/jsr/BeanDescriptorTest.java ---------------------------------------------------------------------- diff --git a/bval-jsr/src/test/java/org/apache/bval/jsr/BeanDescriptorTest.java b/bval-jsr/src/test/java/org/apache/bval/jsr/BeanDescriptorTest.java index d81f90a..b18030d 100644 --- a/bval-jsr/src/test/java/org/apache/bval/jsr/BeanDescriptorTest.java +++ b/bval-jsr/src/test/java/org/apache/bval/jsr/BeanDescriptorTest.java @@ -23,6 +23,9 @@ import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.RetentionPolicy.RUNTIME; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNotSame; +import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; import java.lang.annotation.Documented; @@ -165,6 +168,19 @@ public class BeanDescriptorTest extends ValidationTestBase { assertEquals("Incorrect number of descriptors", 1, constraints.size()); } + @Test + public void testDescriptorCaching() { + // constrained + final BeanDescriptor personDescriptor = validator.getConstraintsForClass(Person.class); + assertNotNull(personDescriptor); + assertSame(personDescriptor, validator.getConstraintsForClass(Person.class)); + + // unconstrained + final BeanDescriptor objectDescriptor = validator.getConstraintsForClass(Object.class); + assertNotNull(objectDescriptor); + assertNotSame(objectDescriptor, validator.getConstraintsForClass(Object.class)); + } + public static class Form { @NotNull public String name;
