5 Commits

Author SHA1 Message Date
Andrew Gallant
fc3e6aa19a
license: remove license headers from files
The Rust project determined these were unnecessary a while back[1,2,3]
and we follow suite.

[1] - 0565653eec
[2] - https://github.com/rust-lang/rust/pull/43498
[3] - https://github.com/rust-lang/rust/pull/57108
2019-08-03 14:47:45 -04:00
Andrew Gallant
7038f5c430 small cleanups 2016-05-06 20:20:05 -04:00
Andrew Gallant
37b6d318c0 Reintroduce the reverse suffix literal optimization.
It's too good to pass up. This time, we avoid quadratic behavior
with a simple work-around: we limit the amount of reverse searching
we do after having found a literal match. If the reverse search ends
at the beginning of its search text (whether a match or not), then we
stop the reverse suffix optimization and fall back to the standard forward
search.

This reverts commit 50d991eaf53e6c21b8101c82e01ab6cf36fe687c.

# Conflicts:
#	src/exec.rs
2016-05-06 18:00:02 -04:00
Andrew Gallant
50d991eaf5 It's a sad day: remove reverse suffix literal optimization.
TL;DR: As implemented, its worst case time complexity was quadratic.

Given the regex `.*z.*abcd` and the haystack `abcdabcdabcdabcd...`,
the reverse suffix literal optimization would find the first occurrence
of `abcd`, then try to match `.*z.*` in reverse. When the match fails,
it starts searching for `abcd` again after the last occurrence. On the
second match (immediately after the first match), it has to run the DFA
backwards all over again. This is repeated for every match of `abcd`.
In essence, it will have run for quadratic time before reporting that the
regex cannot match.

There is hope. If we can know that the "reverse" search, in this case,
`.*z.*` *cannot* match the suffix literal `abcd`, then we can cap the
haystack that is searched in reverse so that each byte is visited by the
DFA at most once. In particular, we can cause the DFA to only search as
far as the previous match of the suffix literal.

This is somewhat close to a generalization of Boyer-Moore in the sense
that we're utilizing information of mismatches and the nature of the needle
to limit how much work search has to do.
2016-04-09 09:16:11 -04:00
Andrew Gallant
31a317eadd Major literal optimization refactoring.
The principle change in this commit is a complete rewrite of how
literals are detected from a regular expression. In particular, we now
traverse the abstract syntax to discover literals instead of the
compiled byte code. This permits more tuneable control over which and
how many literals are extracted, and is now exposed in the
`regex-syntax` crate so that others can benefit from it.

Other changes in this commit:

* The Boyer-Moore algorithm was rewritten to use my own concoction based
  on frequency analysis. We end up regressing on a couple benchmarks
  slightly because of this, but gain in some others and in general should
  be faster in a broader number of cases. (Principally because we try to
  run `memchr` on the rarest byte in a literal.) This should also greatly
  improve handling of non-Western text.
* A "reverse suffix" literal optimization was added. That is, if suffix
  literals exist but no prefix literals exist, then we can quickly scan
  for suffix matches and then run the DFA in reverse to find matches.
  (I'm not aware of any other regex engine that does this.)
* The mutex-based pool has been replaced with a spinlock-based pool
  (from the new `mempool` crate). This reduces some amount of constant
  overhead and improves several benchmarks that either search short
  haystacks or find many matches in long haystacks.
* Search parameters have been refactored.
* RegexSet can now contain 0 or more regular expressions (previously, it
  could only contain 2 or more). The InvalidSet error variant is now
  deprecated.
* A bug in computing start states was fixed. Namely, the DFA assumed the
  start states was always the first instruction, which is trivially
  wrong for an expression like `^☃$`. This bug persisted because it
  typically occurred when a literal optimization would otherwise run.
* A new CLI tool, regex-debug, has been added as a non-published
  sub-crate. The CLI tool can answer various facts about regular
  expressions, such as printing its AST, its compiled byte code or its
  detected literals.

Closes #96, #188, #189
2016-03-27 20:07:46 -04:00