ReviewOS

also looking at this

zig-utils/zig-regex

fix(vm): make findAll linear by stopping matchAt when no threads remain

#8
Merged DaliVana wants to merge fix/findall-quadratic into main
3 files +102 -0
src/vm.zigmodified+11-0
Changes to src/vm.zig
@@ -227,6 +227,17 @@ pub const VM = struct {
227227 next_threads.clearRetainingCapacity();
228228
229229 pos += 1;
230
231 // No live threads remain. matchAt only ever seeds the start-state
232 // thread (at start_pos), and threads can only be spawned by cloning
233 // existing ones, so once the set is empty no further match can
234 // begin from this start_pos — the longest match found so far
235 // (last_match) is final. Without this break the loop walks every
236 // remaining byte doing nothing; because findAll restarts matchAt
237 // per match, that dead-walk is what makes findAll O(n^2). Any
238 // accepting state reached on the consumed input was already
239 // recorded by the accept check at the top of the loop.
240 if (current_threads.items.len == 0) break;
230241 }
231242
232243 // Return the last (longest) match we found