fix(base-query): fix five indexing and scope bugs; wire @Unique#60
Merged
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Q1 —
IsEqualTofallback path was null-asymmetric: when a queried value was null, the fallback stream filter calledObjects.equals(rawValue, NULL_OBJECT)which always returned false. The fix wraps the extracted value withnonNull()before comparing, matching the behaviour of the indexed fast path.Q2 — Match-level scope was silently ignored by all three terminals (
IsEqualTo,IsNotEqualTo,Matches). Each terminal initialisedthis.scope = Scope.Directunconditionally, discarding any scope set viaMatch.scope(). The fix initialisesthis.scope = where.select.scopeso the terminal inherits the match scope, with its own override still taking precedence.Q3 —
Scope.Direct,Scope.BreadthFirst, andScope.DepthFirstwere not additive as their Javadoc promised. IfobjectByClasscontained any entry for the queried class,traverse()was never called. The fix restructuresstream(Scope)soScope.Indexedis the only short-circuit; all other scopes concatenate indexed objects with traversal results, deduplicated by identity.Q4 —
add(Class, T)andremove(Class, T)silently swallowed null arguments via anif (x != null)guard. Null class or value is a programmer error; both parameters are now validated withObjects.requireNonNull.Q5 —
@Uniquewas annotated@Target(METHOD)but nothing ever read it on methods, making it dead code. The target is changed toFIELDso it can coexist with@Indexableonpublic static final Functionfields. When present, the index stores a directkey → objectmapping instead ofkey → Set<object>,isEqualTolookups become O(1), and duplicate keys throwIllegalStateExceptionat index time.