Repository navigation
Resolve hot-path: stop copying every value, fix whole-collection exclusion - #4
Merged
Merged
Conversation
evaluate_step copied every resolved value with to_vec before testing it, even when the rule had no transformations, so the borrowing the resolver does to avoid copying was undone one line later. A rule set resolves thousands of values per request, and most operators read the value as-is. Candidates are now Cow: without transformations the value is tested in place with no copy, and a transformation that changes nothing (t:none, or t:lowercase on already-lowercase input) returns a borrow rather than allocating. Only the value that actually matches is owned, once, for MATCHED_VAR. multiMatch still materialises the value before and after each transformation, since it tests each stage. Behaviour is unchanged: the transformation-order and multiMatch tests pass as before, and the Core Rule Set still compiles to 590 rules and blocks the same traffic.
A selector-less exclusion (`!ARGS`) removed every resolved value whose name began with the collection name, so it also stripped `ARGS_GET:x` and `ARGS_NAMES:x`, whose names start with "ARGS". A rule that excluded one collection while inspecting a longer-named sibling silently lost members. The exclusion now resolves the value's name into (collection, member) and keeps it only when the collection matches exactly: a scalar named `PREFIX`, or a map member named `PREFIX:member`. A name that merely starts with the prefix, like ARGS_GET against ARGS, no longer matches. Selector-bearing exclusions were already anchored by the `:` split and are unaffected; the Core Rule Set, which always writes a selector, is unchanged.
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.
The two smaller resolve-path follow-ups from the engine review. Independent of each other; grouped because both touch resolution.
1. Stop copying every inspected value (perf)
evaluate_stepdidvalue.value.to_vec()for every resolved value before testing it, even for a rule with no transformations, undoing the borrowing the resolver does to avoid exactly that copy. A rule set resolves thousands of values per request and most operators read the value as-is.Candidates are now
Cow<[u8]>:t:none, ort:lowercaseon already-lowercase input) returns a borrow instead of allocating.MATCHED_VAR.multiMatchstill materialises the value before and after each transformation, since it tests each stage.2. Whole-collection exclusion matched by string prefix (correctness)
A selector-less exclusion (
!ARGS) removed every resolved value whose name began with the collection name — so it also strippedARGS_GET:xandARGS_NAMES:x, since those start with"ARGS". A rule excluding one collection while inspecting a longer-named sibling silently lost members.The exclusion now resolves each value name into
(collection, member)and matches the collection exactly: a scalarPREFIX, or a map memberPREFIX:member. A name that merely starts with the prefix no longer matches. Selector-bearing exclusions were already anchored by the:split, so CRS (which always writes a selector) is unaffected.Verification
ARGS_GET|!ARGSregression guard); clippy and fmt clean.__utmzallowed,sessionblocked).