Skip to content

fix: PikeVM capture route compiled lazy quantifiers as greedy - #137

Merged
jbachorik merged 1 commit into
mainfrom
fix/pikevm-lazy-group-priority
Sep 29, 2026
Merged

jbachorik merged 1 commit into
mainfrom
fix/pikevm-lazy-group-priority

Conversation

@jbachorik

Copy link
Copy Markdown
Collaborator

What does this PR do?

One-line fix: RuntimeCompiler.compilePikeVm now builds its NFA with new ThompsonBuilder(true) (lazy-aware), matching every other PikeVM compile site in the file.

Motivation

compilePikeVm is the fallback the annotation processor emits for patterns its native strategies refuse (e.g. ^(.+?)\.([^/]+)). It built the NFA with the non-lazy-aware ThompsonBuilder, so lazy quantifiers (+?, *?, ??) compiled with greedy thread priority. The extracted capture spans therefore took the longest split instead of the lazy (shortest) one and diverged from the JDK — for ^(.+?)\.([^/]+) on net/http.(*ServeMux).ServeHTTP the JDK yields group1 = net/http, the PikeVM yielded net/http.(*ServeMux).

Boolean matches()/find() are priority-independent and were never affected, which is why the existing boolean differential suites did not catch this. The PikeVM boolean DFA fast paths (findDfa/matchesDfa) are existence checks over the same NFA and remain priority-independent — no behavior change there.

Related Issue(s)

None filed yet (regression present in 0.5.0; discovered during backend adoption).

Change Type

  • Bug fix
  • Test improvement

Checklist

  • I have read the CONTRIBUTING.md guidelines
  • All existing tests pass (./gradlew build)
  • I have added tests for my changes
  • My commits are signed

Performance Impact

None: lazyAware only changes epsilon-transition ordering for lazy quantifier splits (thread priority), not state count or engine complexity. The rebuilt NFA is cached in PIKEVM_NFA_CACHE as before.

Additional Notes

New test PikeVMLazyGroupParityTest: differential JDK parity for match() group strings and findMatchFrom per-group spans over 6 lazy patterns x 6 inputs on the compilePikeVm route.

Companion PR on fix/apt-findlongestmatchend-missing fixes the APT rich-API (findAll/replaceAll/split) crashes; the two are independent and both were found by the profiling-backend wave-2 differential gate.

An external model review (gpt-5.6-terra) of this diff returned approve-with-comments; the one actionable finding (weak find-span oracle) was addressed by comparing all group spans.

compilePikeVm built its NFA with a non-lazy-aware ThompsonBuilder, so
lazy quantifiers got greedy priority and the extracted capture spans took
the longest split instead of the lazy one, diverging from the JDK for
both match() and findMatch*() group spans. Boolean results were
unaffected (priority-independent), so only group-extracting callers were
exposed. Every other PikeVM compile site already builds lazy-aware.
@jbachorik jbachorik added the AI Generated or assisted by AI label Sep 29, 2026
@jbachorik
jbachorik marked this pull request as ready for review September 29, 2026 14:43
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 29, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-09-29T14:45:26.076133Z a89e6bb Draft marked ready
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@codecov-commenter

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 85.4%. Comparing base (a1c0581) to head (a89e6bb).

Additional details and impacted files
@@           Coverage Diff           @@
##              main    #137   +/-   ##
=======================================
  Coverage     85.4%   85.4%           
  Complexity       1       1           
=======================================
  Files          163     163           
  Lines        48759   48759           
  Branches      6970    6970           
=======================================
+ Hits         41645   41649    +4     
+ Misses        5105    5103    -2     
+ Partials      2009    2007    -2     
Files with missing lines Coverage Δ
.../com/datadoghq/reggie/runtime/RuntimeCompiler.java 86.1% <100.0%> (+0.1%) ⬆️

... and 1 file with indirect coverage changes


Continue to review full report in Codecov by Harness.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update a1c0581...a89e6bb. Read the comment docs.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@datadog-prod-us1-3 datadog-prod-us1-3 Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bits Code Review: PASS

More details

compilePikeVm now uses lazy-aware Thompson construction consistently with sibling PikeVM routes, preserving shortest-first capture priority for both match and findMatch paths.

Was this helpful? React 👍 or 👎

Open Bits AI session

🤖 Bits Code Review · Commit a89e6bb · @DataDog review to ask questions

@jbachorik
jbachorik merged commit d7940fe into main Sep 29, 2026
10 checks passed
@jbachorik
jbachorik deleted the fix/pikevm-lazy-group-priority branch September 29, 2026 15:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

AI Generated or assisted by AI mergequeue-status: done

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants