Parallel Matching

FindParallel and FindIndexParallel split one text into chunks and scan them concurrently. The automaton is loaded once per call, so the Redis cost is the same as a serial Find however many chunks result.

matches, err := ac.FindParallel(largeText, &acor.ParallelOptions{
    Workers:     4,
    ChunkSize:   1000, // runes per base chunk; must be positive
    AutoOverlap: true,
    Boundary:    acor.ChunkBoundaryWord,
})
if err != nil {
    panic(err)
}
_ = matches

Boundaries

Only Boundary changes between these; everything else stays as above.

BoundarySplits atSuited to
ChunkBoundaryWord (default)WhitespaceNatural language
ChunkBoundaryLineNewlinesLog files
ChunkBoundarySentence. ! ?Documents

Boundary choice alone does not protect a keyword that straddles a split. AutoOverlap does.

Boundary protection

AutoOverlap: true extends each base chunk to the right by max(Overlap, longest keyword rune length - 1), using the longest keyword in the engine already loaded for this call — no extra Redis read, and every worker shares one snapshot. Matches starting inside an extension belong to the next chunk and are not double-counted. This also catches keywords longer than ChunkSize, including Korean and emoji.

AutoOverlap defaults to false, which keeps the legacy behavior: an Overlap shorter than your longest keyword silently misses boundary matches, and a keyword longer than ChunkSize may fit in no chunk at all.

Result order

FindParallel reports each keyword once, in chunk order and then first-match order within a chunk — which need not equal serial scan order. FindIndexParallel returns sorted, unique rune positions in the original text. Empty input performs no Redis read.

When it pays

Worth it above roughly 100 KB of text, with cores to spare. Below ~10 KB, or for a single expected match, the chunking overhead outweighs it. Start Workers at runtime.NumCPU().