You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@bval.apache.org by ta...@apache.org on 2026/07/25 00:51:22 UTC
(bval) 01/03: BVAL-226 Remove redundant per-constraint validation de-duplication
This is an automated email from the ASF dual-hosted git repository.
asf-gitbox-commits pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/bval.git
commit d99606b257f455793f3f97f1689bd96ceb75ded4
Author: tandraschko <ta...@apache.org>
AuthorDate: Sat Jul 25 02:33:23 2026 +0200
BVAL-226 Remove redundant per-constraint validation de-duplication
---
.../org/apache/bval/jsr/job/ValidationJob.java | 28 ++++++----------------
1 file changed, 7 insertions(+), 21 deletions(-)
diff --git a/bval-jsr/src/main/java/org/apache/bval/jsr/job/ValidationJob.java b/bval-jsr/src/main/java/org/apache/bval/jsr/job/ValidationJob.java
index e57cc22..3177ea6 100644
--- a/bval-jsr/src/main/java/org/apache/bval/jsr/job/ValidationJob.java
+++ b/bval-jsr/src/main/java/org/apache/bval/jsr/job/ValidationJob.java
@@ -24,14 +24,12 @@ import java.lang.reflect.TypeVariable;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
-import java.util.IdentityHashMap;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
-import java.util.TreeMap;
import java.util.function.Consumer;
import java.util.function.Predicate;
import java.util.stream.Collectors;
@@ -144,16 +142,12 @@ public abstract class ValidationJob<T> {
@SuppressWarnings({ "rawtypes", "unchecked" })
private boolean validate(ConstraintD<?> constraint, Consumer<ConstraintViolation<T>> sink) {
- // Use the same path ordering/equality as before (ConcurrentSkipListMap): comparator-based, not Path#equals.
- final Map<Path, Set<Object>> pathMap = completedValidations.computeIfAbsent(constraint,
- k -> new TreeMap<>(PathImpl.PATH_COMPARATOR));
- // Read-only use as a comparator-based map key for the duration of this validation; no copy needed.
- final Set<Object> objectSet =
- pathMap.computeIfAbsent(context.pathReference(),
- p -> Collections.newSetFromMap(new IdentityHashMap<>()));
- if (!objectSet.add(context.getValue())) {
- return true;
- }
+ // No per-(constraint, path, value) de-duplication is performed here. It is not needed: groups are
+ // validated in a single pass (see GroupStrategy usage in process()), so a given constraint at a
+ // given path/value is reached exactly once, even when it belongs to several targeted groups or a
+ // redefined Default sequence. Distinct locations (e.g. the same shared object cascaded via two
+ // properties) are distinct paths and must each be reported. Cycles are handled separately via
+ // GraphContext#isRecursive(), not by tracking completed validations.
final ConstraintValidator constraintValidator = getConstraintValidator(constraint);
final ConstraintValidatorContextImpl<T> constraintValidatorContext =
new ConstraintValidatorContextImpl<>(this, constraint);
@@ -590,9 +584,6 @@ public abstract class ValidationJob<T> {
private final Lazy<Set<ConstraintViolation<T>>> results = new Lazy<>(LinkedHashSet::new);
- /** Filled only during single-threaded {@link #getResults()} for one validation. */
- private Map<ConstraintD<?>, Map<Path, Set<Object>>> completedValidations;
-
ValidationJob(ApacheFactoryContext validatorContext, Class<?>[] groups) {
super();
this.validatorContext = Validate.notNull(validatorContext, "validatorContext");
@@ -609,12 +600,7 @@ public abstract class ValidationJob<T> {
final Consumer<ConstraintViolation<T>> sink = results.consumer(Set::add);
- completedValidations = new HashMap<>();
- try {
- baseFrame.process(groups.asStrategy(), sink);
- } finally {
- completedValidations = null;
- }
+ baseFrame.process(groups.asStrategy(), sink);
if (results.optional().isPresent()) {
return Collections.unmodifiableSet(results.get());
}