Skip to content

Commit 8baa0ef

Browse files
authored
Merge pull request #103 from coregx/feature/findall-multiline-fix
fix: FindAll now uses UseMultilineReverseSuffix strategy (#102)
2 parents 43efbbd + ff9ea25 commit 8baa0ef

File tree

4 files changed

+39
-3
lines changed

4 files changed

+39
-3
lines changed

CHANGELOG.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,19 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1414

1515
---
1616

17+
## [0.11.4] - 2026-01-16
18+
19+
### Fixed
20+
- **FindAll/FindAllIndex now use UseMultilineReverseSuffix strategy** (Issue #102)
21+
- Previously `FindIndicesAt()` was missing dispatch for `UseMultilineReverseSuffix`
22+
- `IsMatch`/`Find` were fast (1µs), but `FindAll` was slow (78ms) - **100x gap vs Rust**
23+
- After fix: `FindAll` on 6MB with 2000 matches: **~1ms** (was 78ms)
24+
25+
### Changed
26+
- Updated `golang.org/x/sys` dependency v0.39.0 → v0.40.0
27+
28+
---
29+
1730
## [0.11.3] - 2026-01-16
1831

1932
### Changed
@@ -1537,6 +1550,7 @@ v1.0.0 → Stable release (API frozen)
15371550
---
15381551

15391552
[Unreleased]: https://github.com/coregx/coregex/compare/v0.11.3...HEAD
1553+
[0.11.4]: https://github.com/coregx/coregex/releases/tag/v0.11.4
15401554
[0.11.3]: https://github.com/coregx/coregex/releases/tag/v0.11.3
15411555
[0.11.2]: https://github.com/coregx/coregex/releases/tag/v0.11.2
15421556
[0.11.1]: https://github.com/coregx/coregex/releases/tag/v0.11.1

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,5 @@ go 1.25.4
44

55
require (
66
github.com/coregx/ahocorasick v0.1.0
7-
golang.org/x/sys v0.39.0
7+
golang.org/x/sys v0.40.0
88
)

go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
github.com/coregx/ahocorasick v0.1.0 h1:CiCQwQ/Gu6pahlO3u4jrPo8q0Tb8pLknU7tzqiLRZcw=
22
github.com/coregx/ahocorasick v0.1.0/go.mod h1:SDcS9KTiwLP8FHNpYSO3Q3mRqrK8SYJAYpygrhcIils=
3-
golang.org/x/sys v0.39.0 h1:CvCKL8MeisomCi6qNZ+wbb0DN9E5AATixKsvNtMoMFk=
4-
golang.org/x/sys v0.39.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
3+
golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ=
4+
golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=

meta/find_indices.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@ func (e *Engine) FindIndices(haystack []byte) (start, end int, found bool) {
4646
return e.findIndicesDigitPrefilter(haystack)
4747
case UseAhoCorasick:
4848
return e.findIndicesAhoCorasick(haystack)
49+
case UseMultilineReverseSuffix:
50+
return e.findIndicesMultilineReverseSuffix(haystack)
4951
default:
5052
return e.findIndicesNFA(haystack)
5153
}
@@ -86,6 +88,8 @@ func (e *Engine) FindIndicesAt(haystack []byte, at int) (start, end int, found b
8688
return e.findIndicesDigitPrefilterAt(haystack, at)
8789
case UseAhoCorasick:
8890
return e.findIndicesAhoCorasickAt(haystack, at)
91+
case UseMultilineReverseSuffix:
92+
return e.findIndicesMultilineReverseSuffixAt(haystack, at)
8993
default:
9094
return e.findIndicesNFAAt(haystack, at)
9195
}
@@ -436,6 +440,24 @@ func (e *Engine) findIndicesReverseInnerAt(haystack []byte, at int) (int, int, b
436440
return e.reverseInnerSearcher.FindIndicesAt(haystack, at)
437441
}
438442

443+
// findIndicesMultilineReverseSuffix searches using multiline suffix optimization - zero alloc.
444+
func (e *Engine) findIndicesMultilineReverseSuffix(haystack []byte) (int, int, bool) {
445+
if e.multilineReverseSuffixSearcher == nil {
446+
return e.findIndicesNFA(haystack)
447+
}
448+
atomic.AddUint64(&e.stats.DFASearches, 1)
449+
return e.multilineReverseSuffixSearcher.FindIndicesAt(haystack, 0)
450+
}
451+
452+
// findIndicesMultilineReverseSuffixAt searches using multiline suffix optimization from position - zero alloc.
453+
func (e *Engine) findIndicesMultilineReverseSuffixAt(haystack []byte, at int) (int, int, bool) {
454+
if e.multilineReverseSuffixSearcher == nil {
455+
return e.findIndicesNFAAt(haystack, at)
456+
}
457+
atomic.AddUint64(&e.stats.DFASearches, 1)
458+
return e.multilineReverseSuffixSearcher.FindIndicesAt(haystack, at)
459+
}
460+
439461
// findIndicesBoundedBacktracker searches using bounded backtracker - zero alloc.
440462
// Thread-safe: uses pooled state.
441463
func (e *Engine) findIndicesBoundedBacktracker(haystack []byte) (int, int, bool) {

0 commit comments

Comments
 (0)