Skip to content
Permalink
Browse files
BVAL-172 more thread safety in our caches
  • Loading branch information
rmannibucau committed Apr 19, 2019
1 parent 69c36fa commit c4e1bdf29657af63749c8e0af73aea3485774097
Showing 6 changed files with 46 additions and 13 deletions.
@@ -37,6 +37,33 @@
<jaxb.version>2.2.6</jaxb.version>
</properties>
<profiles>

<profile>
<id>java11</id>
<activation>
<jdk>11</jdk>
</activation>
<dependencies>
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-core</artifactId>
<version>2.3.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-base</artifactId>
<version>11</version>
<scope>provided</scope>
</dependency>
</dependencies>
</profile>
<!--
default profile using geronimo-validation_2.0_spec.jar active when
property "ri" is not present.
@@ -23,9 +23,7 @@
import java.util.Arrays;
import java.util.Collections;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
@@ -99,8 +97,8 @@ public int hashCode() {
}
}

private final Map<Class<? extends Annotation>, Set<ConstraintValidatorInfo<?>>> constraintValidatorInfo =
new HashMap<>();
private final ConcurrentMap<Class<? extends Annotation>, Set<ConstraintValidatorInfo<?>>> constraintValidatorInfo =
new ConcurrentHashMap<>();
private final ConcurrentMap<ConstraintD<?>, ConstraintValidator<?, ?>> validators =
new ConcurrentHashMap<>();

@@ -39,10 +39,14 @@

protected CascadableContainerD(MetadataReader.ForContainer<E> reader, P parent) {
super(reader, parent);
cascaded = reader.isCascaded();
groupConversions = reader.getGroupConversions();
containerElementTypes = reader.getContainerElementTypes(this).stream().filter(DescriptorManager::isConstrained)
.collect(ToUnmodifiable.set());
synchronized (reader.meta.getHost()) { // cache is not thread safe for runtime perf so ensure we lock properly
cascaded = reader.isCascaded();
groupConversions = reader.getGroupConversions();
containerElementTypes = reader.getContainerElementTypes(this)
.stream()
.filter(DescriptorManager::isConstrained)
.collect(ToUnmodifiable.set());
}
}

@Override
@@ -334,8 +334,10 @@ public <T> MetadataBuilder.ForBean<T> forBean(Class<T> beanClass) {
return (MetadataBuilder.ForBean<T>) delegates.get(0);
}
// pretend:
return delegates.stream().<MetadataBuilder.ForBean<T>> map(MetadataBuilder.ForBean.class::cast)
.collect(compose());
// note: stream split for java 11 compilation
final Stream<MetadataBuilder.ForBean<T>> forBeanStream = delegates.stream()
.map(MetadataBuilder.ForBean.class::cast);
return forBeanStream.collect(compose());
}

@Override
@@ -345,7 +347,7 @@ protected <E extends AnnotatedElement> Map<Meta<E>, Annotation[]> getConstraintD
@SuppressWarnings("unchecked")
final Function<MetadataBuilder.ForElement<E>, Meta<E>> keyMapper =
d -> Optional.of(d).filter(HierarchyDelegate.class::isInstance).map(HierarchyDelegate.class::cast)
.map(HierarchyDelegate::getHierarchyElement).orElse(meta);
.map(HierarchyDelegate::getHierarchyElement).map(Meta.class::cast).orElse(meta);

return composite.delegates.stream().collect(Collectors.toMap(keyMapper, d -> d.getDeclaredConstraints(meta),
(u, v) -> Stream.of(u, v).flatMap(Stream::of).toArray(Annotation[]::new), LinkedHashMap::new));
@@ -59,7 +59,9 @@
*/
AnnotationProxyBuilder(final Class<A> annotationType, Map<Class<?>, Method[]> cache) {
this.type = Validate.notNull(annotationType, "annotationType");
this.methods = Validate.notNull(cache, "cache").computeIfAbsent(annotationType, Reflection::getDeclaredMethods);
synchronized (annotationType) { // cache is not thread safe generally
this.methods = Validate.notNull(cache, "cache").computeIfAbsent(annotationType, Reflection::getDeclaredMethods);
}
}

/**
@@ -35,7 +35,7 @@ public LRUCache(int maximumCapacity) {
}

@Override
protected boolean removeEldestEntry(Map.Entry<K, V> eldest) {
protected boolean removeEldestEntry(Map.Entry<K, V> eldest) { // todo: synchronize?
return super.removeEldestEntry(eldest) || size() >= maximumCapacity;
}
}

0 comments on commit c4e1bdf

Please sign in to comment.