Simplify internals and speed up per-file line/col computation - #11
Merged
Conversation
Its only caller, compiledRuleSet, is already memoised behind sync.OnceValue, so the inner OnceValue wrapper added a layer of indirection without saving any work.
… mask size The two hand-unrolled OR blocks duplicated kwMask.orIn, which the compiler already inlines to the same code (verified with -gcflags=-m and A/B benchmarks). The 320-pattern cap is now computed from the kwMask array length so it can't silently drift if the mask grows.
dedupOverlapping and mergeOverlapping used the same inline comparator; a named helper documents the ordering contract once.
findMatches and Contains duplicated the empty-input check, rule-set lookup, and keyword-mask early-out; one helper now owns that logic.
lineCol rescanned data from offset 0 for every match, making output formatting O(len(file) x matches). Matches are emitted in ascending Start order, so a single incremental cursor gives identical line and column numbers in one pass.
…ne/col cursor - kwMask doc and the overflow test no longer hardcode 320; both now track len(kwMask)*64 so they can't drift from buildAhoCorasick. - scanPrelude doc mentions Redact, which also reaches it via findMatches. - New table-driven scanFileBytes test locks down the incremental line/column cursor: match at offset zero, two matches on one line, CRLF endings, and empty files.
aheritier
approved these changes
Jul 24, 2026
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.
Several small internal cleanups landed together with one targeted performance fix in
portcullis-scan.On the simplification side, the nested
sync.OnceValueinsideruleswas redundant because its only caller already memoises the result;rulesis now a plain function. The two hand-unrolled five-word OR blocks inscanSerialduplicatedkwMask.orIn, so they were replaced with a call to it; the hard-coded 320-pattern cap is now derived fromlen(kwMask{})*64so it can't silently drift. A shared match-sort comparator is factored intosortMatches, and the repeated AC pre-filter prologue is factored intoscanPrelude, both used byfindMatchesandContains.The performance change affects
portcullis-scan: the oldlineColhelper rescanned from offset 0 for every match, giving O(file × matches) work. Because matches arrive in ascendingStartorder, a single incremental cursor now walks each file once, giving identical output in a single pass.All changes are behavior-preserving.
go test ./...,go vet, andgolangci-lintpass with zero issues; A/B benchmarks show no regression (identical allocations, timings within noise).